Advertisement
es3n1n

enum util

Mar 12th, 2022 (edited)
506
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.18 KB | None | 0 0
  1. #pragma once
  2. #include <array>
  3. #include <string_view>
  4.  
  5.  
  6. namespace enum_util {
  7.     consteval bool check_sig( std::string_view name ) noexcept {
  8.         for ( std::size_t i = name.size( ); i > 0; --i ) {
  9.             if ( !( ( name[ i - 1 ] >= '0' && name[ i - 1 ] <= '9' ) ||
  10.                     ( name[ i - 1 ] >= 'a' && name[ i - 1 ] <= 'z' ) ||
  11.                     ( name[ i - 1 ] >= 'A' && name[ i - 1 ] <= 'Z' ) ||
  12.                     ( name[ i - 1 ] == '_' ) ) ) {
  13.                 name.remove_prefix( i );
  14.                 break;
  15.             }
  16.         }
  17.  
  18.         if ( name.size( ) > 0 && ( ( name.front( ) >= 'a' && name.front( ) <= 'z' ) ||
  19.                                    ( name.front( ) >= 'A' && name.front( ) <= 'Z' ) ||
  20.                                    ( name.front( ) == '_' ) ) )
  21.             return true;
  22.  
  23.         return false;
  24.     }
  25.  
  26.     template <typename E, E V>
  27.     constexpr auto n( ) noexcept {
  28.         return check_sig( { __FUNCSIG__, sizeof( __FUNCSIG__ ) - 17 } );
  29.     }
  30.  
  31.     template <typename E, auto V>
  32.     constexpr auto is_valid( ) noexcept {
  33.         return n<E, static_cast< E >( V )>( );
  34.     }
  35.  
  36.     template <std::size_t N>
  37.     consteval std::size_t values_count( const bool( &valid )[ N ] ) noexcept {
  38.         auto count = std::size_t { 0 };
  39.         for ( std::size_t i = 0; i < N; ++i ) {
  40.             if ( valid[ i ] )
  41.                 ++count;
  42.         }
  43.  
  44.         return count;
  45.     }
  46.  
  47.     template <typename T, std::size_t N, std::size_t... I>
  48.     constexpr std::array<std::remove_cv_t<T>, N> to_array( T( &a )[ N ], std::index_sequence<I...> ) {
  49.         return { {a[ I ]...} };
  50.     }
  51.  
  52.     //
  53.  
  54.     template <typename E, std::size_t... I>
  55.     consteval auto do_values( std::index_sequence<I...> ) noexcept {
  56.         constexpr bool valid[ sizeof...( I ) ] = { is_valid<E, I>( )... };
  57.         constexpr std::size_t count = values_count( valid );
  58.  
  59.         E values[ count ] = {};
  60.         for ( std::size_t i = 0, v = 0; v < count; ++i ) {
  61.             if ( valid[ i ] )
  62.                 values[ v++ ] = static_cast< E >( i );
  63.         }
  64.  
  65.         return to_array( values, std::make_index_sequence<count>{} );
  66.     }
  67.  
  68.     template<typename E, std::size_t... I>
  69.     consteval auto do_count( std::index_sequence<I...> ) noexcept {
  70.         constexpr bool valid[ sizeof...( I ) ] = { is_valid<E, I>( )... };
  71.         return values_count( valid );
  72.     }
  73.  
  74.     template <typename E, std::size_t... I>
  75.     consteval auto do_index( E search_value, std::index_sequence<I...> ) noexcept {
  76.         constexpr bool valid[ sizeof...( I ) ] = { is_valid<E, I>( )... };
  77.         constexpr std::size_t count = values_count( valid );
  78.  
  79.         std::size_t ret = 0;
  80.         for ( std::size_t i = 0; ret < count; ++i ) {
  81.             if ( static_cast< E >( i ) == search_value )
  82.                 break;
  83.             if ( valid[ i ] )
  84.                 ret++;
  85.         }
  86.  
  87.         return ret;
  88.     }
  89.  
  90.     //
  91.  
  92.     template<typename E, E Min, E Max>
  93.     constexpr auto values( ) noexcept {
  94.         constexpr auto range_size = static_cast< int >( Max ) - static_cast< int >( Min ) + 1;
  95.         return do_values<E>( std::make_index_sequence<range_size>{} );
  96.     }
  97.  
  98.     template<typename E, E Min, E Max>
  99.     constexpr auto count( ) noexcept {
  100.         constexpr auto range_size = static_cast< int >( Max ) - static_cast< int >( Min ) + 1;
  101.         return do_count<E>( std::make_index_sequence<range_size>{} );
  102.     }
  103.  
  104.     template<typename E, E Min, E Max>
  105.     consteval auto index( E value ) noexcept {
  106.         constexpr auto range_size = static_cast< int >( Max ) - static_cast< int >( Min ) + 1;
  107.         return do_index<E>( value, std::make_index_sequence<range_size>{} );
  108.     }
  109. }
  110.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement