3030#include < cassert>
3131#include < climits>
3232#include < iostream>
33+ #include < fstream>
3334#include < iomanip>
3435#include < algorithm>
3536#include < numeric>
@@ -53,24 +54,8 @@ using pcg_extras::operator<<;
5354
5455#if !PCG_EMULATED_128BIT_MATH || !AWKWARD_128BIT_CODE
5556
56- int main ( int argc, char ** argv )
57+ int main_test (std::ostream& out, int rounds, bool nondeterministic_seed )
5758{
58- // Read command-line options
59-
60- int rounds = 5 ;
61- bool nondeterministic_seed = false ;
62-
63- ++argv;
64- --argc;
65- if (argc > 0 && strcmp (argv[0 ], " -r" ) == 0 ) {
66- nondeterministic_seed = true ;
67- ++argv;
68- --argc;
69- }
70- if (argc > 0 ) {
71- rounds = atoi (argv[0 ]);
72- }
73-
7459 /* Many of the generators can be initialized with two arguments; the second
7560 * one specifies the stream.
7661 */
@@ -95,52 +80,52 @@ int main(int argc, char** argv)
9580 : bits > 32 ? 3
9681 : how_many_nums;
9782
98- cout << STRINGIFY (RNG) << " :\n "
99- // << " - aka: " << pcg_extras::printable_typename<RNG>()
83+ out << STRINGIFY (RNG) << " :\n "
84+ // << " - aka: " << pcg_extras::printable_typename<RNG>()
10085 // ^-- we skip this line because the output is long, scary, ugly, and
10186 // and varies depending on the platform
102- << " - result: " << bits << " -bit unsigned int\n "
103- << " - period: 2^" << RNG::period_pow2 ();
87+ << " - result: " << bits << " -bit unsigned int\n "
88+ << " - period: 2^" << RNG::period_pow2 ();
10489 if (RNG::streams_pow2 () > 0 )
105- cout << " (* 2^" << RNG::streams_pow2 () << " streams)" ;
106- cout << " \n - size: " << sizeof (RNG) << " bytes\n\n " ;
90+ out << " (* 2^" << RNG::streams_pow2 () << " streams)" ;
91+ out << " \n - size: " << sizeof (RNG) << " bytes\n\n " ;
10792
10893 for (int round = 1 ; round <= rounds; ++round) {
109- printf ( " Round %d :\n " , round) ;
94+ out << " Round " << round << " :\n " ;
11095
11196 /* Make some N-bit numbers */
112- cout << setw (4 ) << setfill (' ' ) << bits << " bit:" ;
97+ out << setw (4 ) << setfill (' ' ) << bits << " bit:" ;
11398 for (int i = 0 ; i < how_many_nums; ++i) {
11499 if (i > 0 && i % wrap_nums_at == 0 )
115- cout << " \n\t " ;
116- cout << " 0x" << hex << setfill (' 0' )
117- << setw (sizeof (RNG::result_type)*2 ) << rng ();
100+ out << " \n\t " ;
101+ out << " 0x" << hex << setfill (' 0' )
102+ << setw (sizeof (RNG::result_type)*2 ) << rng ();
118103 }
119- cout << endl;
104+ out << endl;
120105
121- cout << " Again:" ;
106+ out << " Again:" ;
122107 rng.backstep (6 );
123108 for (int i = 0 ; i < how_many_nums; ++i) {
124109 if (i > 0 && i % wrap_nums_at == 0 )
125- cout << " \n\t " ;
126- cout << " 0x" << hex << setfill (' 0' )
127- << setw (sizeof (RNG::result_type)*2 ) << rng ();
110+ out << " \n\t " ;
111+ out << " 0x" << hex << setfill (' 0' )
112+ << setw (sizeof (RNG::result_type)*2 ) << rng ();
128113 }
129- cout << dec << endl;
114+ out << dec << endl;
130115
131116 /* Toss some coins */
132- cout << " Coins: " ;
117+ out << " Coins: " ;
133118 for (int i = 0 ; i < 65 ; ++i)
134- cout << (rng (2 ) ? " H" : " T" );
135- cout << endl;
119+ out << (rng (2 ) ? " H" : " T" );
120+ out << endl;
136121
137122 RNG rng_copy{rng};
138123 /* Roll some dice */
139- printf ( " Rolls:" ) ;
124+ out << " Rolls:" ;
140125 for (int i = 0 ; i < 33 ; ++i)
141- cout << " " << (uint32_t (rng (6 )) + 1 );
142- cout << " \n --> rolling dice used "
143- << (rng - rng_copy) << " random numbers" << endl;
126+ out << " " << (uint32_t (rng (6 )) + 1 );
127+ out << " \n --> rolling dice used "
128+ << (rng - rng_copy) << " random numbers" << endl;
144129
145130 /* Deal some cards using pcg_extras::shuffle, which follows
146131 * the algorithm for shuffling that most programmers would expect.
@@ -152,24 +137,57 @@ int main(int argc, char** argv)
152137 pcg_extras::shuffle (begin (cards), end (cards), rng);
153138
154139 /* Output the shuffled deck */
155- printf ( " Cards:" ) ;
140+ out << " Cards:" ;
156141 static const signed char number[] = {' A' , ' 2' , ' 3' , ' 4' , ' 5' , ' 6' , ' 7' ,
157142 ' 8' , ' 9' , ' T' , ' J' , ' Q' , ' K' };
158143 static const signed char suit[] = {' h' , ' c' , ' d' , ' s' };
159144 int i = 0 ;
160145 for (auto card : cards) {
161146 ++i;
162- cout << " " << number[card / SUITS] << suit[card % SUITS];
147+ out << " " << number[card / SUITS] << suit[card % SUITS];
163148 if (i % 22 == 0 )
164- cout << " \n\t " ;
149+ out << " \n\t " ;
165150 }
166151
167- cout << " \n " << endl;
152+ out << " \n " << endl;
168153 }
169154
170155 return 0 ;
171156}
172157
158+ int main (int argc, char ** argv)
159+ {
160+ // Read command-line options
161+ int rounds = 5 ;
162+ bool nondeterministic_seed = false ;
163+ std::ofstream out_file;
164+
165+ ++argv;
166+ --argc;
167+ if (argc > 0 && strcmp (argv[0 ], " -r" ) == 0 ) {
168+ nondeterministic_seed = true ;
169+ ++argv;
170+ --argc;
171+ }
172+ if (argc > 0 && strcmp (argv[0 ], " -o" ) == 0 ) {
173+ ++argv;
174+ --argc;
175+ if (argc > 0 ) {
176+ out_file.open (argv[0 ], std::ios::out | std::ios::trunc);
177+ ++argv;
178+ --argc;
179+ }
180+ }
181+ if (argc > 0 ) {
182+ rounds = atoi (argv[0 ]);
183+ }
184+
185+ if (out_file.is_open ()) {
186+ return main_test (out_file, rounds, nondeterministic_seed);
187+ }
188+ return main_test (std::cout, rounds, nondeterministic_seed);
189+ }
190+
173191#else // i.e. PCG_EMULATED_128BIT_MATH && AWKWARD_128BIT_CODE
174192
175193int main ()
0 commit comments