Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //----------------------------------------------------------- C++98 METHOD
- #include <stdlib.h>
- template< size_t n > // This type returns a number through function lookup.
- struct cn // The function returns cn<n>.
- { char data[ n + 1 ]; }; // The caller uses (sizeof fn() - 1).
- template< typename id, size_t n, size_t acc >
- cn< acc > seen( id, cn< n >, cn< acc > ); // Default fallback case.
- /* Evaluate the counter by finding the last defined overload.
- Each function, when defined, alters the lookup sequence for lower-order
- functions. */
- #define counter_read( id ) \
- ( sizeof seen( id(), cn< 1 >(), cn< \
- ( sizeof seen( id(), cn< 2 >(), cn< \
- ( sizeof seen( id(), cn< 4 >(), cn< \
- ( sizeof seen( id(), cn< 8 >(), cn< \
- ( sizeof seen( id(), cn< 16 >(), cn< \
- ( sizeof seen( id(), cn< 32 >(), cn< 0 \
- /* Add more as desired; trimmed for Stack Overflow code block. */ \
- >() ).data - 1 ) \
- >() ).data - 1 ) \
- >() ).data - 1 ) \
- >() ).data - 1 ) \
- >() ).data - 1 ) \
- >() ).data - 1 )
- /* Define a single new function with place-value equal to the bit flipped to 1
- by the increment operation.
- This is the lowest-magnitude function yet undefined in the current context
- of defined higher-magnitude functions. */
- #define counter_inc( id ) \
- cn< counter_read( id ) + 1 > \
- seen( id, cn< ( counter_read( id ) + 1 ) & ~ counter_read( id ) >, \
- cn< ( counter_read( id ) + 1 ) & counter_read( id ) > )
- struct my_cnt {};
- int const a = counter_read( my_cnt );
- counter_inc( my_cnt );
- counter_inc( my_cnt );
- counter_inc( my_cnt );
- counter_inc( my_cnt );
- counter_inc( my_cnt );
- int const b = counter_read( my_cnt );
- counter_inc( my_cnt );
- #include <iostream>
- int main() {
- std::cout << a << ' ' << b << '\n';
- std::cout << counter_read( my_cnt ) << '\n';
- }
- //----------------------------------------------------------- C++11 METHOD
- #define COUNTER_READ_CRUMB( TAG, RANK, ACC ) counter_crumb( TAG(), constant_index< RANK >(), constant_index< ACC >() )
- #define COUNTER_READ( TAG ) COUNTER_READ_CRUMB( TAG, 1, COUNTER_READ_CRUMB( TAG, 2, COUNTER_READ_CRUMB( TAG, 4, COUNTER_READ_CRUMB( TAG, 8, \
- COUNTER_READ_CRUMB( TAG, 16, COUNTER_READ_CRUMB( TAG, 32, COUNTER_READ_CRUMB( TAG, 64, COUNTER_READ_CRUMB( TAG, 128, 0 ) ) ) ) ) ) ) )
- #define COUNTER_INC( TAG ) \
- constant_index< COUNTER_READ( TAG ) + 1 > \
- constexpr counter_crumb( TAG, constant_index< ( COUNTER_READ( TAG ) + 1 ) & ~ COUNTER_READ( TAG ) >, \
- constant_index< ( COUNTER_READ( TAG ) + 1 ) & COUNTER_READ( TAG ) > ) { return {}; }
- #define COUNTER_LINK_NAMESPACE( NS ) using NS::counter_crumb;
- #include <utility>
- template< std::size_t n >
- struct constant_index : std::integral_constant< std::size_t, n > {};
- template< typename id, std::size_t rank, std::size_t acc >
- constexpr constant_index< acc > counter_crumb( id, constant_index< rank >, constant_index< acc > ) { return {}; } // found by ADL via constant_index
- // define your different counter here
- struct my_cnt {};
- struct my_cnt2 {};
- #include <iostream>
- //COUNTER_INC( my_cnt ); // increment counter !
- struct A
- {
- static int constexpr type = COUNTER_READ(my_cnt); // read counter value !
- };
- COUNTER_INC( my_cnt );
- struct B
- {
- static int constexpr type = COUNTER_READ(my_cnt);
- };
- COUNTER_INC( my_cnt );
- struct C
- {
- static int constexpr type = COUNTER_READ(my_cnt);
- };
- COUNTER_INC( my_cnt );
- struct D
- {
- static int constexpr type = COUNTER_READ(my_cnt2);
- };
- int main() {
- std::cout << "A::type = "<< A::type << '\n';
- std::cout << "B::type = "<< B::type << '\n';
- std::cout << "C::type = "<< C::type << '\n';
- std::cout << "D::type = "<< D::type << '\n';
- }
Add Comment
Please, Sign In to add comment