#include "trace.hpp" #include struct gen_t { int max_size, max_depth, max_length; std::mt19937 rand; std::string str; int i_total = 0, i_odd = 0, i_neg = 0; int a_total = 0, a_odd = 0, a_empty = 0; int o_total = 0, o_odd = 0, o_empty = 0; int d_odd = 0, d_even = 0; int id_odd = 0; gen_t( int s ) : rand( s ) {} void integer( int d ) { ++ i_total; if ( d % 2 ) id_odd ++; if ( rand() % 20 == 0 ) { str += "0"; return; } if ( rand() % 2 ) { str += '-'; ++ i_neg; } std::geometric_distribution geom( 0.3 ); int size = geom( rand ) % 6; str += ( '1' + rand() % 9 ); for ( int i = 0; i < size; ++i ) str += ( '0' + rand() % 10 ); if ( ( str.back() - '0' ) % 2 ) i_odd ++; } int length( int d ) { std::geometric_distribution dist( 0.1 ); return std::max( d < 3 ? 3ul - d : 0ul, dist( rand ) % std::max( max_length - str.size() / 100, 10ul ) ); } void object( int d ) { std::geometric_distribution keysize_d( 0.6 ); int size = length( d ); int keysize = 1 + ( size ? std::log( size ) : 0 ) + keysize_d( rand ) % 20; std::string key( keysize, 'a' ); auto next = [&] { while ( true ) { char &c = key[ rand() % key.size() ]; if ( c < 'z' ) { ++ c; break; } }; }; o_total ++; if ( size % 2 ) o_odd ++; if ( !size ) o_empty ++; for ( int i = 0; i < size; ++i ) { str += i ? ", " : "{ "; str += key + ": "; value( d + 1 ); next(); } str += size ? " }" : "{}"; } void array( int d ) { int size = length( d ); a_total ++; if ( size % 2 ) a_odd ++; if ( !size ) a_empty ++; for ( int i = 0; i < size; ++i ) { str += i ? ", " : "[ "; value( d + 1 ); } str += size ? " ]" : "[]"; } void value( int d = 0 ) { if ( d % 2 == 1 ) d_odd ++; if ( d > max_depth || int( str.size() ) > max_size ) return integer( d ); switch ( rand() % 3 ) { case 0: if ( d >= 3 ) return integer( d ); else { if ( d == 1 || d == 3 ) d_odd --; return value( d ); } case 1: return object( d ); case 2: return array( d ); } } };