forked from Alepha/Alepha
I think this makes capabilities much simpler and more reliable.
But the capabilities are now limited to a single param -- Time to change that?
This commit is contained in:
@ -15,76 +15,54 @@ namespace Alepha::Hydrogen
|
|||||||
{
|
{
|
||||||
inline namespace exports
|
inline namespace exports
|
||||||
{
|
{
|
||||||
template< typename ... capabilities >
|
template< typename ... List >
|
||||||
struct Capabilities;
|
struct Capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CapabilityBase {};
|
template< typename List, typename Capability >
|
||||||
template< typename ... capabilities >
|
struct list_matches;
|
||||||
struct exports::Capabilities : CapabilityBase {};
|
|
||||||
|
|
||||||
template< typename T >
|
template< typename List, typename Capability >
|
||||||
concept CapabilityList= DerivedFrom< T, CapabilityBase >;
|
constexpr bool list_matches_v= list_matches< List, Capability >::value;
|
||||||
|
|
||||||
|
|
||||||
template< typename T >
|
|
||||||
constexpr bool is_capability_list_v= false;
|
|
||||||
|
|
||||||
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 >
|
template< typename Capability >
|
||||||
constexpr bool has_capability_in_list_v< Capability, Nil > {};
|
struct list_matches< Nil, Capability > : std::false_type {};
|
||||||
|
|
||||||
template< typename ... Args >
|
template< typename List, typename Capability >
|
||||||
constexpr TypeListType auto
|
struct list_matches
|
||||||
extract_list( const Capabilities< Args... > & )
|
|
||||||
{
|
{
|
||||||
return TypeList< Args... >{};
|
static constexpr bool value= false
|
||||||
}
|
or DerivedFrom< car_t< List >, Capability >
|
||||||
|
or list_matches_v< cdr_t< List >, Capability >
|
||||||
template< typename T > struct get_capability_list { using type= Nil; };
|
;
|
||||||
|
|
||||||
template< CapabilityList T >
|
|
||||||
struct get_capability_list< T >
|
|
||||||
{
|
|
||||||
using type= decltype( extract_list( std::declval< const T & >() ) );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
template< typename ... > class Built,
|
|
||||||
typename ... LeftArgs,
|
|
||||||
typename ... RightArgs,
|
|
||||||
CapabilityList List
|
|
||||||
>
|
|
||||||
struct get_capability_list< Built< LeftArgs..., List, RightArgs... > >
|
|
||||||
{
|
|
||||||
using type= typename get_capability_list< List >::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename T >
|
template< typename Capability, typename List >
|
||||||
using get_capability_list_t= typename get_capability_list< T >::type;
|
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 & );
|
||||||
|
};
|
||||||
|
|
||||||
namespace exports
|
namespace exports
|
||||||
{
|
{
|
||||||
template< typename T, typename Capability >
|
template< typename T, typename Capability >
|
||||||
constexpr bool has_capability_v=
|
concept HasCapability= false
|
||||||
has_capability_in_list_v< Capability, get_capability_list_t< T > >
|
or DerivedFrom< T, Capability >
|
||||||
or
|
or CapabilityInList< Capability, decltype( get_capability_list( std::declval< const T & >() ) ) >
|
||||||
DerivedFrom< T, Capability >;
|
;
|
||||||
|
|
||||||
template< typename T, typename Capability >
|
|
||||||
concept HasCapability= has_capability_v< T, Capability >;
|
|
||||||
|
|
||||||
template< typename T, typename Capability >
|
template< typename T, typename Capability >
|
||||||
concept Capable= HasCapability< T, Capability >;
|
concept Capable= HasCapability< T, Capability >;
|
||||||
|
|
||||||
|
template< typename T, typename Cap >
|
||||||
|
concept Capability= HasCapability< T, Cap >;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct capability_demo {};
|
struct capability_demo {};
|
||||||
@ -92,16 +70,6 @@ namespace Alepha::Hydrogen
|
|||||||
template< typename= Capabilities< capability_demo > >
|
template< typename= Capabilities< capability_demo > >
|
||||||
struct Example_base {};
|
struct Example_base {};
|
||||||
using Example= 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, capability_demo > == true );
|
||||||
static_assert( HasCapability< Example, missing_capability_demo > == false );
|
static_assert( HasCapability< Example, missing_capability_demo > == false );
|
||||||
template< HasCapability< missing_capability_demo > C > void f( C ) {}
|
template< HasCapability< missing_capability_demo > C > void f( C ) {}
|
||||||
|
@ -28,16 +28,10 @@ namespace Alepha::Hydrogen
|
|||||||
namespace exports
|
namespace exports
|
||||||
{
|
{
|
||||||
using detail::comparisons_m::comparable;
|
using detail::comparisons_m::comparable;
|
||||||
inline constexpr Meta::type_value< comparable > comparable_capability;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
constexpr bool has_comparable_capability_v= has_capability( Meta::type_value< std::decay_t< T > >{}, comparable_capability );
|
constexpr bool has_comparable_capability_v= HasCapability< std::decay_t< T >, comparable >;
|
||||||
|
|
||||||
template< typename T >
|
|
||||||
struct has_comparable_capability_s : std::bool_constant< has_comparable_capability_v< T > > {};
|
|
||||||
|
|
||||||
inline constexpr Meta::trait< has_comparable_capability_s > has_comparable_capability;
|
|
||||||
|
|
||||||
|
|
||||||
// Spaceship lens support
|
// Spaceship lens support
|
||||||
@ -54,7 +48,7 @@ namespace Alepha::Hydrogen
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename T,
|
typename T,
|
||||||
typename= std::enable_if_t< has_comparable_capability( Meta::type_value< T >{} ) >,
|
typename= std::enable_if_t< has_comparable_capability_v< T > >,
|
||||||
typename= std::enable_if_t< has_spaceship_lens_member_v< T > >,
|
typename= std::enable_if_t< has_spaceship_lens_member_v< T > >,
|
||||||
overload< __LINE__ > = nullptr
|
overload< __LINE__ > = nullptr
|
||||||
>
|
>
|
||||||
|
@ -6,6 +6,9 @@ static_assert( __cplusplus > 2020'99 );
|
|||||||
#include <Alepha/Testing/TableTest.h>
|
#include <Alepha/Testing/TableTest.h>
|
||||||
#include <Alepha/Utility/evaluation_helpers.h>
|
#include <Alepha/Utility/evaluation_helpers.h>
|
||||||
|
|
||||||
|
#include <Alepha/Meta/find.h>
|
||||||
|
#include <Alepha/Meta/Container/vector.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
using Alepha::Hydrogen::exports::types_m::argcnt_t;
|
using Alepha::Hydrogen::exports::types_m::argcnt_t;
|
||||||
@ -19,8 +22,8 @@ namespace
|
|||||||
<
|
<
|
||||||
typename= int,
|
typename= int,
|
||||||
typename= Capabilities< comparable >,
|
typename= Capabilities< comparable >,
|
||||||
typename= float,
|
typename= float//,
|
||||||
typename= Capabilities< short >
|
//typename= Capabilities< short >
|
||||||
>
|
>
|
||||||
struct Date_core
|
struct Date_core
|
||||||
{
|
{
|
||||||
@ -43,8 +46,8 @@ namespace
|
|||||||
static_assert( Meta::find_if( begin( vec ), end( vec ), Meta::bind1st( Meta::is_same, Meta::type_value< int >{} ) ) );
|
static_assert( Meta::find_if( begin( vec ), end( vec ), Meta::bind1st( Meta::is_same, Meta::type_value< int >{} ) ) );
|
||||||
static_assert( not Meta::find_if( begin( vec ), end( vec ), Meta::bind1st( Meta::is_same, Meta::type_value< double >{} ) ) );
|
static_assert( not Meta::find_if( begin( vec ), end( vec ), Meta::bind1st( Meta::is_same, Meta::type_value< double >{} ) ) );
|
||||||
|
|
||||||
static_assert( detail::is_capability_list_v< Capabilities< comparable > > );
|
//static_assert( detail::is_capability_list_v< Capabilities< comparable > > );
|
||||||
static_assert( Alepha::has_capability( Meta::type_value< Date >{}, comparable_capability ) );
|
static_assert( Alepha::HasCapability< Date, Alepha::comparable > );
|
||||||
|
|
||||||
template< template< typename > class op, typename T >
|
template< template< typename > class op, typename T >
|
||||||
constexpr bool
|
constexpr bool
|
||||||
|
@ -96,7 +96,7 @@ namespace Alepha::Hydrogen ::detail:: swappable_m
|
|||||||
};
|
};
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
concept SwapLensable= Capability< T, swappable > and SupportsSwapLens< T >;
|
concept SwapLensable= HasCapability< T, swappable > and SupportsSwapLens< T >;
|
||||||
|
|
||||||
|
|
||||||
// To compute the noexceptness of a swap expression, we
|
// To compute the noexceptness of a swap expression, we
|
||||||
|
25
type_lisp.h
25
type_lisp.h
@ -5,6 +5,7 @@ static_assert( __cplusplus > 2020'99 );
|
|||||||
#include <Alepha/Alepha.h>
|
#include <Alepha/Alepha.h>
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
namespace Alepha::Hydrogen ::detail:: type_lisp_m
|
namespace Alepha::Hydrogen ::detail:: type_lisp_m
|
||||||
{
|
{
|
||||||
@ -74,18 +75,28 @@ namespace Alepha::Hydrogen ::detail:: type_lisp_m
|
|||||||
using cdr_t= typename cdr_impl< List >::type;
|
using cdr_t= typename cdr_impl< List >::type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename List, typename Element >
|
||||||
|
struct list_contains
|
||||||
|
{
|
||||||
|
static const bool value= std::is_same_v< Element, car_t< List > > or list_contains< cdr_t< List >, Element >::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename Element >
|
||||||
|
struct list_contains< Nil, Element > : std::false_type {};
|
||||||
|
|
||||||
namespace exports
|
namespace exports
|
||||||
{
|
{
|
||||||
template< typename List, typename Element >
|
template< typename List, typename Element >
|
||||||
constexpr bool list_contains_v=
|
constexpr bool list_contains_v= list_contains< List, Element >::value;
|
||||||
std::is_same_v< Element, car_t< List > >
|
|
||||||
or
|
|
||||||
list_contains_v< cdr_t< List >, Element >;
|
|
||||||
|
|
||||||
template< typename Element >
|
|
||||||
constexpr bool list_contains_v< Nil, Element >{};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Alpha;
|
||||||
|
struct Beta;
|
||||||
|
struct Gamma;
|
||||||
|
static_assert( list_contains_v< TypeList< Alpha, Beta >, Alpha > );
|
||||||
|
static_assert( list_contains_v< TypeList< Alpha, Beta >, Beta > );
|
||||||
|
static_assert( not list_contains_v< TypeList< Alpha, Beta >, Gamma > );
|
||||||
|
|
||||||
template< typename Element, typename List >
|
template< typename Element, typename List >
|
||||||
struct cons;
|
struct cons;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user