fork(51) 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. #include <utility>
  13.  
  14. template< std::size_t n >
  15. struct constant_index : std::integral_constant< std::size_t, n > {};
  16.  
  17. template< typename id, std::size_t rank, std::size_t acc >
  18. constexpr constant_index< acc > counter_crumb( id, constant_index< rank >, constant_index< acc > ) { return {}; } // found by ADL via constant_index
  19.  
  20. struct my_cnt {};
  21.  
  22. int const a = COUNTER_READ( my_cnt );
  23. COUNTER_INC( my_cnt );
  24. COUNTER_INC( my_cnt );
  25. COUNTER_INC( my_cnt );
  26. COUNTER_INC( my_cnt );
  27. COUNTER_INC( my_cnt );
  28.  
  29. int const b = COUNTER_READ( my_cnt );
  30.  
  31. COUNTER_INC( my_cnt );
  32.  
  33. #include <iostream>
  34.  
  35. int main() {
  36. std::cout << a << ' ' << b << '\n';
  37.  
  38. std::cout << COUNTER_READ( my_cnt ) << '\n';
  39. }
Success #stdin #stdout 0s 16064KB
stdin
Standard input is empty
stdout
0 5
6