Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <array>
- #include <string_view>
- namespace enum_util {
- consteval bool check_sig( std::string_view name ) noexcept {
- for ( std::size_t i = name.size( ); i > 0; --i ) {
- if ( !( ( name[ i - 1 ] >= '0' && name[ i - 1 ] <= '9' ) ||
- ( name[ i - 1 ] >= 'a' && name[ i - 1 ] <= 'z' ) ||
- ( name[ i - 1 ] >= 'A' && name[ i - 1 ] <= 'Z' ) ||
- ( name[ i - 1 ] == '_' ) ) ) {
- name.remove_prefix( i );
- break;
- }
- }
- if ( name.size( ) > 0 && ( ( name.front( ) >= 'a' && name.front( ) <= 'z' ) ||
- ( name.front( ) >= 'A' && name.front( ) <= 'Z' ) ||
- ( name.front( ) == '_' ) ) )
- return true;
- return false;
- }
- template <typename E, E V>
- constexpr auto n( ) noexcept {
- return check_sig( { __FUNCSIG__, sizeof( __FUNCSIG__ ) - 17 } );
- }
- template <typename E, auto V>
- constexpr auto is_valid( ) noexcept {
- return n<E, static_cast< E >( V )>( );
- }
- template <std::size_t N>
- consteval std::size_t values_count( const bool( &valid )[ N ] ) noexcept {
- auto count = std::size_t { 0 };
- for ( std::size_t i = 0; i < N; ++i ) {
- if ( valid[ i ] )
- ++count;
- }
- return count;
- }
- template <typename T, std::size_t N, std::size_t... I>
- constexpr std::array<std::remove_cv_t<T>, N> to_array( T( &a )[ N ], std::index_sequence<I...> ) {
- return { {a[ I ]...} };
- }
- //
- template <typename E, std::size_t... I>
- consteval auto do_values( std::index_sequence<I...> ) noexcept {
- constexpr bool valid[ sizeof...( I ) ] = { is_valid<E, I>( )... };
- constexpr std::size_t count = values_count( valid );
- E values[ count ] = {};
- for ( std::size_t i = 0, v = 0; v < count; ++i ) {
- if ( valid[ i ] )
- values[ v++ ] = static_cast< E >( i );
- }
- return to_array( values, std::make_index_sequence<count>{} );
- }
- template<typename E, std::size_t... I>
- consteval auto do_count( std::index_sequence<I...> ) noexcept {
- constexpr bool valid[ sizeof...( I ) ] = { is_valid<E, I>( )... };
- return values_count( valid );
- }
- template <typename E, std::size_t... I>
- consteval auto do_index( E search_value, std::index_sequence<I...> ) noexcept {
- constexpr bool valid[ sizeof...( I ) ] = { is_valid<E, I>( )... };
- constexpr std::size_t count = values_count( valid );
- std::size_t ret = 0;
- for ( std::size_t i = 0; ret < count; ++i ) {
- if ( static_cast< E >( i ) == search_value )
- break;
- if ( valid[ i ] )
- ret++;
- }
- return ret;
- }
- //
- template<typename E, E Min, E Max>
- constexpr auto values( ) noexcept {
- constexpr auto range_size = static_cast< int >( Max ) - static_cast< int >( Min ) + 1;
- return do_values<E>( std::make_index_sequence<range_size>{} );
- }
- template<typename E, E Min, E Max>
- constexpr auto count( ) noexcept {
- constexpr auto range_size = static_cast< int >( Max ) - static_cast< int >( Min ) + 1;
- return do_count<E>( std::make_index_sequence<range_size>{} );
- }
- template<typename E, E Min, E Max>
- consteval auto index( E value ) noexcept {
- constexpr auto range_size = static_cast< int >( Max ) - static_cast< int >( Min ) + 1;
- return do_index<E>( value, std::make_index_sequence<range_size>{} );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement