diff --git a/Buffer.h b/Buffer.h index c3d450d..0cb2883 100644 --- a/Buffer.h +++ b/Buffer.h @@ -235,7 +235,7 @@ namespace Alepha::Hydrogen ::detail:: Buffer_m struct BufferModel_capability {}; template< typename T > - concept UndecayedBufferModelable= Capability< T, BufferModel_capability >; + concept UndecayedBufferModelable= HasCapability< T, BufferModel_capability >; template< typename T > concept BufferModelable= UndecayedBufferModelable< std::decay_t< T > >; diff --git a/Capabilities.h b/Capabilities.h index e1b9011..3cc9e8d 100644 --- a/Capabilities.h +++ b/Capabilities.h @@ -4,8 +4,8 @@ static_assert( __cplusplus > 2020'99 ); #include -#include -#include +#include +#include namespace Alepha::Hydrogen { @@ -17,122 +17,94 @@ namespace Alepha::Hydrogen { template< typename ... capabilities > struct Capabilities; - - template< typename T, typename cap > - struct has_capability_s; //: std::is_base_of< cap, T > {}; - - -#if 0 - template< template< typename ... > class Type, typename ... Caps, typename cap > - struct has_capability< Type< Capabilities< Caps... > >, cap > - { - using T= Type< Capabilities< Caps... > >; - static constexpr bool value= Meta::find_in_tuple_v< cap, std::tuple< Caps... > > or std::is_base_of_v< cap, T >; - using type= has_capability; - }; - template< template< typename ... > class Type, typename ... Back, typename ... Caps, typename cap > - struct has_capability< Type< Capabilities< Caps... >, Back... >, cap > - { - using T= Type< Capabilities< Caps... >, Back... >; - static constexpr bool value= Meta::find_in_tuple_v< cap, std::tuple< Caps... > > or std::is_base_of_v< cap, T >; - using type= has_capability; - }; - - - template< template< typename ... > class Type, typename ... Front, typename ... Caps, typename cap > - struct has_capability< Type< Front..., Capabilities< Caps... > >, cap > - { - using T= Type< Front..., Capabilities< Caps... > >; - static constexpr bool value= Meta::find_in_tuple_v< cap, std::tuple< Caps... > > or std::is_base_of_v< cap, T >; - using type= has_capability; - }; -#endif } - template< typename T > - struct is_capability_list_s : std::false_type {}; - - template< typename ... Args > - struct is_capability_list_s< Capabilities< Args... > > : std::true_type {}; - - inline constexpr Meta::trait< is_capability_list_s > is_capability_list; + struct CapabilityBase {}; + template< typename ... capabilities > + struct exports::Capabilities : CapabilityBase {}; template< typename T > - constexpr bool is_capability_list_v= is_capability_list( Meta::type_value< T >{} ); + concept CapabilityList= DerivedFrom< T, CapabilityBase >; - template< template< typename ... > class ... HigherKinds > - struct higher_kind_tuple {}; + template< typename T > + constexpr bool is_capability_list_v= false; - template< typename Cap, typename ... Caps > - consteval bool - has_cap_in_capability_base( const Meta::type_value< Capabilities< Caps... > > &, Meta::type_value< Cap > cap ) + template< typename ... Args > + constexpr bool is_capability_list_v< Capabilities< Args... > > { true }; + + template< typename Capability, TypeListType List > + constexpr bool has_capability_in_list_v= false + or SameAs< car_t< List >, Capability > + or DerivedFrom< car_t< List >, Capability > + or has_capability_in_list_v< Capability, cdr_t< List > >; + + template< typename Capability > + constexpr bool has_capability_in_list_v< Capability, Nil > {}; + + template< typename ... Args > + constexpr TypeListType auto + extract_list( const Capabilities< Args... > & ) { - Meta::Container::vector< Caps... > types; - using std::begin, std::end; - return Meta::find_if( begin( types ), end( types ), Meta::bind1st( Meta::is_base_of, cap ) ); + return TypeList< Args... >{}; } - template< typename Left, typename Cap > - constexpr bool - has_cap_in_capability_base( const Left &, Meta::type_value< Cap > cap ) - { - throw "Unevaluated"; - return false; - } + template< typename T > struct get_capability_list { using type= Nil; }; - template< typename Cap, typename ... TParams > - consteval bool - has_cap( const Meta::Container::vector< TParams... > &types, Meta::type_value< Cap > cap ) + template< CapabilityList T > + struct get_capability_list< T > { - bool rv= 0; - template_for( types ) <=[&] - ( const auto type ) - { - if( is_capability_list( type ) and has_cap_in_capability_base( type, cap ) ) rv= true; - }; - return rv; - } + using type= decltype( extract_list( std::declval< const T & >() ) ); + }; - template< typename Cap, template< typename ... > class Class, typename ... TParams > - consteval bool - has_cap( const Meta::type_value< Class< TParams... > > &, Meta::type_value< Cap > cap ) + template + < + template< typename ... > class Built, + typename ... LeftArgs, + typename ... RightArgs, + CapabilityList List + > + struct get_capability_list< Built< LeftArgs..., List, RightArgs... > > { - return has_cap( Meta::Container::vector< TParams... >{}, cap ); - } + using type= typename get_capability_list< List >::type; + }; - template< typename Type, typename Cap > - consteval bool - has_cap( const Meta::type_value< Type > &, Meta::type_value< Cap > ) - { - return false; - } + template< typename T > + using get_capability_list_t= typename get_capability_list< T >::type; namespace exports { - template< typename T, typename cap > + template< typename T, typename Capability > constexpr bool has_capability_v= - std::is_base_of_v< cap, T > + has_capability_in_list_v< Capability, get_capability_list_t< T > > or - has_cap( Meta::type_value< T >{}, Meta::type_value< cap >{} ); + DerivedFrom< T, Capability >; - template< typename T, typename cap > - struct has_capability_s : std::bool_constant< has_capability_v< T, cap > > {}; + template< typename T, typename Capability > + concept HasCapability= has_capability_v< T, Capability >; - inline constexpr Meta::trait< has_capability_s > has_capability; - - template< typename T, typename capability > - concept Capability= has_capability_v< T, capability >; + template< typename T, typename Capability > + concept Capable= HasCapability< T, Capability >; } struct capability_demo {}; struct missing_capability_demo {}; template< typename= Capabilities< capability_demo > > - struct Capable_base {}; - using Capable= Capable_base<>; - static_assert( Capability< Capable, capability_demo > == true ); - static_assert( Capability< Capable, missing_capability_demo > == false ); - template< Capability< missing_capability_demo > C > void f( C ) {} + struct Example_base {}; + using Example= Example_base<>; + static_assert( not DerivedFrom< Example, capability_demo > ); + static_assert( has_capability_in_list_v< capability_demo, TypeList< capability_demo > > ); + using XXx= get_capability_list_t< Capabilities< capability_demo > >; + constexpr XXx qqq= TypeList< capability_demo >{}; + constexpr TypeList< capability_demo > zzz= get_capability_list_t< Example >{}; + static_assert( std::is_same_v< get_capability_list_t< Capabilities< capability_demo > >, TypeList< capability_demo > > ); + static_assert( std::is_same_v< get_capability_list_t< Example >, TypeList< capability_demo > > ); + static_assert( std::is_same_v< capability_demo, car_t< get_capability_list_t< Example > > > == true ); + static_assert( has_capability_in_list_v< capability_demo, TypeList< capability_demo > > == true ); + static_assert( has_capability_in_list_v< capability_demo, get_capability_list_t< Example > > == true ); + static_assert( HasCapability< Example, capability_demo > == true ); + static_assert( HasCapability< Example, missing_capability_demo > == false ); + template< HasCapability< missing_capability_demo > C > void f( C ) {} } namespace exports::Capabilities_m diff --git a/swappable.h b/swappable.h index 36152aa..3e0bb22 100644 --- a/swappable.h +++ b/swappable.h @@ -79,7 +79,7 @@ namespace Alepha::Hydrogen ::detail:: swappable_m }; template< typename T > - concept MemberSwapLensable= Capability< T, swappable > or HasMemberSwapLens< T >; + concept MemberSwapLensable= HasCapability< T, swappable > or HasMemberSwapLens< T >; template< MemberSwapLensable T > constexpr decltype( auto )