fork(30) download
  1. #define COUNTER_READ_CRUMB( TAG, RANK, ACC ) counter_crumb( TAG(), constant_index< RANK >(), constant_index< ACC >() )
  2. #define COUNTER_READ( TAG ) COUNTER_READ_CRUMB( TAG, 1, COUNTER_READ_CRUMB( TAG, 2, COUNTER_READ_CRUMB( TAG, 4, COUNTER_READ_CRUMB( TAG, 8, \
  3.   COUNTER_READ_CRUMB( TAG, 16, COUNTER_READ_CRUMB( TAG, 32, COUNTER_READ_CRUMB( TAG, 64, COUNTER_READ_CRUMB( TAG, 128, 0 ) ) ) ) ) ) ) )
  4.  
  5. #define COUNTER_INC( TAG ) \
  6. constant_index< COUNTER_READ( TAG ) + 1 > \
  7. constexpr counter_crumb( TAG, constant_index< ( COUNTER_READ( TAG ) + 1 ) & ~ COUNTER_READ( TAG ) >, \
  8.   constant_index< ( COUNTER_READ( TAG ) + 1 ) & COUNTER_READ( TAG ) > ) { return {}; }
  9.  
  10. #define COUNTER_LINK_NAMESPACE( NS ) using NS::counter_crumb;
  11.  
  12. #define REGISTERED_CLASS( TAG, KEY, NAME ) KEY NAME &register_type( TAG, decltype( COUNTER_READ( TAG ) ) ); \
  13. COUNTER_INC( TAG ) KEY NAME /* class definition follows */
  14.  
  15. #include <utility>
  16.  
  17. template< std::size_t n >
  18. struct constant_index : std::integral_constant< std::size_t, n > {};
  19.  
  20. template< typename id, std::size_t rank, std::size_t acc >
  21. constexpr constant_index< acc > counter_crumb( id, constant_index< rank >, constant_index< acc > ) { return {}; } // found by ADL via constant_index
  22.  
  23. struct my_cnt {};
  24.  
  25. int const a = COUNTER_READ( my_cnt );
  26. COUNTER_INC( my_cnt );
  27. COUNTER_INC( my_cnt );
  28. COUNTER_INC( my_cnt );
  29. COUNTER_INC( my_cnt );
  30. COUNTER_INC( my_cnt );
  31.  
  32. int const b = COUNTER_READ( my_cnt );
  33.  
  34. COUNTER_INC( my_cnt );
  35.  
  36. #include <iostream>
  37.  
  38. int main() {
  39. std::cout << a << ' ' << b << '\n';
  40.  
  41. std::cout << COUNTER_READ( my_cnt ) << '\n';
  42. }
Success #stdin #stdout 0s 2896KB
stdin
Standard input is empty
stdout
0 5
6