1
0
forked from Alepha/Alepha

Well this whole () base TMP experiment kinda works.

It's a lot of heavy lifting.  I'm not sure it actually
adds any useful value yet, but I'll continue to play
with it.  It is nice that we can *sometimes* use
loops.  Sometimes we can't though.  And we have
to make some blind-corner evaluations that throw
dummy failures to keep the compiler from complaining
about missing cases -- despite the fact that they;ll
never be reached at compiletime.  (Runtime evaluation
could be different, of course.)

I think, perhaps, a universal representation of a
dereferenced iterator might solve some of this, but
I also don't want to sink too much effort into this,
despite how much fun I'm having.
This commit is contained in:
2021-10-26 01:53:47 -04:00
parent e3d7bbe616
commit cf3f77ba6e
8 changed files with 221 additions and 80 deletions

View File

@ -5,7 +5,7 @@ static_assert( __cplusplus > 201700, "C++17 Required" );
#include <Alepha/Alepha.h>
#include <Alepha/Meta/find.h>
#include <Alepha/Stud/type_traits.h>
#include <Alepha/Meta/type_value.h>
namespace Alepha::Hydrogen
{
@ -19,7 +19,7 @@ namespace Alepha::Hydrogen
struct Capabilities;
template< typename T, typename cap >
struct has_capability; //: std::is_base_of< cap, T > {};
struct has_capability_s; //: std::is_base_of< cap, T > {};
#if 0
@ -50,58 +50,68 @@ namespace Alepha::Hydrogen
}
template< typename T >
struct is_capability_list : std::false_type {};
struct is_capability_list_s : std::false_type {};
template< typename ... Args >
struct is_capability_list< Capabilities< Args... > > : std::true_type {};
struct is_capability_list_s< Capabilities< Args... > > : std::true_type {};
inline constexpr Meta::trait< is_capability_list_s > is_capability_list;
template< typename T >
constexpr bool is_capability_list_v= is_capability_list< T >::value;
constexpr bool is_capability_list_v= is_capability_list( Meta::type_value< T >{} );
template< template< typename ... > class ... HigherKinds >
struct higher_kind_tuple {};
template< typename cap, typename ... Caps >
constexpr auto
has_cap( const Stud::type_identity< Capabilities< Caps... > > & )
template< typename Cap, typename ... Caps >
constexpr bool
has_cap_in_capability_base( const Meta::type_value< Capabilities< Caps... > > &, Meta::type_value< Cap > cap )
{
return Meta::find_if< Meta::bind1st< std::is_base_of, cap >, Meta::Container::vector< Caps... > >{};
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 ) );
}
template< typename cap >
constexpr std::false_type has_cap( const Meta::Container::vector<> & ) { return {}; }
template< typename cap, typename First, typename ... TParams >
constexpr auto
has_cap( const Meta::Container::vector< First, TParams... > & )
template< typename Left, typename Cap >
constexpr bool
has_cap_in_capability_base( const Left &, Meta::type_value< Cap > cap )
{
using depth_type= decltype( has_cap< cap >( Meta::Container::vector< TParams... >{} ) );
if constexpr( is_capability_list_v< First > )
throw "Unevaluated";
}
template< typename Cap, typename ... TParams >
constexpr bool
has_cap( const Meta::Container::vector< TParams... > &types, Meta::type_value< Cap > cap )
{
bool rv= 0;
template_for( types ) <=[&]
( const auto type )
{
using bool_type= decltype( has_cap< cap >( Stud::type_identity< First >() ) );
if constexpr( bool_type::value )
{
return std::bool_constant< bool_type::value >{};
}
else return depth_type{};
}
else return depth_type{};
if( is_capability_list( type ) and has_cap_in_capability_base( type, cap ) ) rv= true;
};
return rv;
}
template< typename cap, template< typename ... > class Class, typename ... TParams >
constexpr auto
has_cap( const Class< TParams... > & )
template< typename Cap, template< typename ... > class Class, typename ... TParams >
constexpr bool
has_cap( const Meta::type_value< Class< TParams... > > &, Meta::type_value< Cap > cap )
{
return has_cap< cap >( Meta::Container::vector< TParams... >{} );
return has_cap( Meta::Container::vector< TParams... >{}, cap );
}
namespace exports
{
template< typename T, typename cap >
constexpr bool has_capability_v= std::is_base_of_v< cap, T > or decltype( has_cap< cap >( std::declval< T >() ) )::value;
constexpr bool has_capability_v=
std::is_base_of_v< cap, T >
or
has_cap( Meta::type_value< T >{}, Meta::type_value< cap >{} );
template< typename T, typename cap >
struct has_capability : std::bool_constant< has_capability_v< T, cap > > {};
struct has_capability_s : std::bool_constant< has_capability_v< T, cap > > {};
inline constexpr Meta::trait< has_capability_s > has_capability;
}
}