#define DECLARE(x, ...) __trace( "decl: " #x, ## __VA_ARGS__ ) ; x #define DECLVEC(T, x, ...) __trace( "decl: std::vector< " #T " > " #x "{ " #__VA_ARGS__ " }"); \ std::vector< T > x{ __VA_ARGS__ } #define TRACE(x, ...) do { __trace( "trace: " #x, ## __VA_ARGS__ ) ; x ; } while ( false ) #define PSEUDO(x, ...) do { __trace( "trace: " x, ## __VA_ARGS__ ) ; } while ( false ) #define ASSERT(x, ...) do { __trace( "assert: " #x, ## __VA_ARGS__ ) ; assert( x ); } while ( false ) #define ASSERTV(x, ...) do { __trace( "trace: " #x, ## __VA_ARGS__ ) ; assert( x ); } while ( false ) #define CLEAR() __trace( "clear:" ); #define SAVE() __trace( "save:" ); #define EXCEPT(e, x, ...) do { __trace( "assert: " #x " throws " #e, ## __VA_ARGS__ ) ; \ assert_throws< e >( [&]{ x; } ); } while ( false ) #define UNPAREN(...) __VA_ARGS__ #define BIND(x, y, ...) __trace( "decl: auto [ " QUOTE x " ] = " #y, ## __VA_ARGS__ ); \ auto [ UNPAREN x ] = y #define QUOTE(...) #__VA_ARGS__ #define ASSERT_FOR(l, expr, ...) \ { \ DECLARE( auto &&range = expr ); using std::begin; using std::end; \ DECLARE( auto b = begin( range ) ); \ DECLARE( auto e = end( range ) ); \ for ( ; __trace( "trace: b != e", b != e ), b != e; __trace( "trace: ++ b" ), ++ b ) \ { \ __trace( "decl: auto [ " QUOTE l " ] = *b" ); \ auto [ UNPAREN l ] = *b; \ ASSERT( __VA_ARGS__ ); \ } \ } #define ASSERT_FOR_(expr, ...) \ { \ DECLARE( auto &&range = expr ); using std::begin; using std::end; \ DECLARE( auto b = begin( range ) ); \ DECLARE( auto e = end( range ) ); \ for ( ; __trace( "trace: b != e", b != e ), b != e; __trace( "trace: ++ b" ), ++ b ) \ { \ ASSERT( __VA_ARGS__ ); \ } \ } #include #include #include #ifdef NVALGRIND #define RUNNING_ON_VALGRIND 0 #else #include #endif #include void __trace_() { std::cerr << std::endl; } template< typename arg_t, typename... args_t > void __trace_( const arg_t &a, const args_t & ... as ) { std::cerr << a << " "; __trace_( as... ); } template< typename arg_t, typename... args_t > void __trace( const arg_t &a, const args_t & ... as ) { std::cerr << std::boolalpha << a; if ( sizeof...( as ) > 0 ) std::cerr << "\t// "; __trace_( as... ); } template< typename T, typename F > void assert_throws( const F &f ) { try { f(); int stat; char *dem = abi::__cxa_demangle( typeid( T ).name(), nullptr, nullptr, &stat ); std::cerr << "failed: expected an exception of type " << dem << std::endl; abort(); } catch ( T & ) {} } [[gnu::constructor]] void set_alarm() { const char *env = std::getenv( "FRAG_DEADLINE" ); if ( !env ) return; time_t dead = std::atol( env ); time_t now = ::time( nullptr ); if ( dead - now <= 10 ) { __trace( "trace: less than 10 seconds left, giving up" ); exit( 1 ); } __trace( "trace: configuring time limits", "subtest =", ( dead - now - 10 ) / 2, "total =", dead - now - 10, "seconds" ); SAVE(); alarm( ( dead - now - 10 ) / 2 ); } int vg_select( int n, int m ) { if ( RUNNING_ON_VALGRIND ) return m; else return n; }