/*
Science and technology promotion license applied.
(c) Zhikai Wang/ www.heteroclinic.net 2013
*/
/* 
We utilize some natural feature of CPU processor and OS.
I am not sure this program will survive all platforms all OSs.
But we are sure whenever there is a race condition, there would be contingency, thus randomness.
It may not perform as good as linear congruential random generator, but it provides a seeding solution.
*/
/*
How to:
$ g++ -o RaceConditionRandomSeeder.exe RaceConditionRandomSeeder.cpp
$ ./RaceConditionRandomSeeder.exe
2363563459
1909203736
3261123683
3162715086
1930226747
2633383142
822405021
2352027847
2565609614
1664631857
*/

#include <iostream>
#include <cstdlib>
#include <climits>
#include <string>
#include <bitset>
#include <time.h>
#include <ctime>

#include <sstream>
#include <iostream>
#include <sstream>
#include <iomanip>

/*BEG test 2 */
/*
// #include <dynamic_bitset> // not in cygwin
//std::bitset<32> bsup(upper_pattern);
class bitsetWrapper {
	const int length;
	void * pt;
public:
	bitsetWrapper (const int  n_length): length(n_length)
	//,pt((void *) new std::bitset<length>())  
	{
		//pt = (void *) new std::bitset<length>();
		//std::bitset<length> bsup; // NO
		
		//const int length = 10; //must be const
		//std::bitset<length> bsup; // OK
	}
};
/*END test 2 */
inline int getWidth (int d) {
	int i = 0; 
	d = abs(d);
	if (0==d)
		return 1;
	while ( d >0 ) {
		d /= 10;
		++i;
	}
	return i;
}
inline const std::string getFormatedIntegerString (int d, int a,char c) {// it is required |a|>=|d|
	std::stringstream ss;
	ss << std::setw(getWidth(a))<<std::setfill(c) <<d;
	return ss.str();
}
inline const std::string getRandomBitsPattern (const unsigned int length ) {
	std::string bits="";
	clock_t start= std::clock();
    clock_t endd = start;
	int i = 0;
	while (i<length) {
		endd = std::clock();
		if (start != endd) {
			//std::cout<<start<<"\t"<<endd<<std::endl;
			start = endd;
			//std::cout<<endd%2<<std::endl;
		
			bits+= getFormatedIntegerString(endd%2,1,' ');
			++i;
		}
	}
	//std::cout<<bits<<std::endl;
	return bits;
}
inline const unsigned long getULSeed()  {
	std::string bits = getRandomBitsPattern (32);
	std::bitset<32> bitsbs (bits);
	return bitsbs.to_ulong();
}
int main () {
	//srand((unsigned)time(NULL));
	
	/*BEG test 1 */
	/*
	clock_t start= std::clock();
    clock_t endd = start;
	int i = 0;
	int * di = new int[10];
	while (i<10) {
		endd = std::clock();
		if (start != endd) {
			di[i++] = endd -start;
			start = endd;
		}
	}
	for (i=0; i<10; i++) {
		std::cout<<di[i]<<std::endl;
	}
	*/
	/*END test 1 */
	
	/*BEG test 3 */
	/*
	int i = 0;
	for (i=0; i<2; i++) {
	//getRandomBitsPattern(20);
	//std::cout<<std::endl;
		std::cout<< getRandomBitsPattern(20)<<std::endl;
	}
	*/
	/*END test 3 */
	
	
	/*BEG test 4 */
	int i = 0;
	for (i=0; i<10; i++) {
		std::cout<< getULSeed()<<std::endl;
	}
	/*END test 4 */

	return 0;
}