static_assert( __cplusplus > 2020'99 ); #pragma once #include #include #include namespace Alepha::Hydrogen { inline namespace exports { inline namespace Capabilities_m {} } namespace detail::Capabilities_m { inline namespace exports { template< typename ... List > struct Capabilities; } template< typename List, typename Capability > struct list_matches; template< typename List, typename Capability > constexpr bool list_matches_v= list_matches< List, Capability >::value; template< typename Capability > struct list_matches< Nil, Capability > : std::false_type {}; template< typename List, typename Capability > struct list_matches { static constexpr bool value= false or DerivedFrom< car_t< List >, Capability > or list_matches_v< cdr_t< List >, Capability > ; }; template< typename Capability, typename List > concept CapabilityInList= list_matches_v< List, Capability >; Nil get_capability_list( ... ); template< typename ... List > struct exports::Capabilities { friend constexpr TypeList< List... > get_capability_list( const auto & ); }; template< typename > struct extract_capability_list { using type= Nil; }; template< typename ... Caps > struct extract_capability_list< Capabilities< Caps... > > { using type= TypeList< Caps... >; }; template< typename T > using extract_capability_list_t= typename extract_capability_list< T >::type; template< typename ... > struct extract_capability_lists; template< typename ... Args > using extract_capability_lists_t= typename extract_capability_lists< Args... >::type; template< typename Arg > struct extract_capability_lists< Arg > { using type= extract_capability_list_t< Arg >; }; template< typename Arg, typename ... Args > struct extract_capability_lists< Arg, Args... > { using type= list_cat_t< extract_capability_list_t< Arg >, extract_capability_lists_t< Args... > >; }; template < template< typename ... > class Basis, typename ... Args > extract_capability_lists_t< Args... > get_capability_list( Basis< Args... > ); namespace exports { template< typename T, typename Capability > concept HasCapability= false or DerivedFrom< T, Capability > or CapabilityInList< Capability, decltype( get_capability_list( std::declval< const T & >() ) ) > ; template< typename T, typename Capability > concept Capable= HasCapability< T, Capability >; template< typename T, typename Cap > concept Capability= HasCapability< T, Cap >; } } namespace exports::Capabilities_m { using namespace detail::Capabilities_m::exports; } }