diff --git a/Meta/type_value.h b/Meta/type_value.h index e7305ce..9da37d8 100644 --- a/Meta/type_value.h +++ b/Meta/type_value.h @@ -4,6 +4,8 @@ static_assert( __cplusplus > 2017, "C++17 Required" ); #include +#include + namespace Alepha::Hydrogen::Meta { inline namespace exports { inline namespace type_value_wrapper {} } diff --git a/Reflection/tuplizeAggregate.h b/Reflection/tuplizeAggregate.h index 0b95846..e6f8690 100644 --- a/Reflection/tuplizeAggregate.h +++ b/Reflection/tuplizeAggregate.h @@ -15,7 +15,30 @@ namespace Alepha::Hydrogen::Reflection namespace detail::tuplize_aggregate { - inline namespace exports + inline namespace exports {} + + template< typename T, typename= void > + struct has_salient_members_constant : std::false_type {}; + + template< typename T > + struct has_salient_members_constant< T, std::void_t< decltype( T::salient_members ) > > + : std::true_type {}; + + template< typename T > + constexpr bool has_salient_members_constant_v= has_salient_members_constant< T >::value; + + template< typename T > + constexpr std::size_t + compute_salient_members_count_impl() + { + if constexpr( has_salient_members_constant_v< T > ) return T::salient_members; + else return aggregate_member_count_v< std::decay_t< T > >; + } + + template< typename T > + constexpr std::size_t compute_salient_members_count_v= compute_salient_members_count_impl< T >(); + + namespace exports { /*! * Deconstruct an aggregate object into a tie-based tuple pointing at its members. @@ -170,7 +193,7 @@ namespace Alepha::Hydrogen::Reflection constexpr decltype( auto ) tuplizeAggregate( Aggregate &&agg ) { - return tuplizeAggregate< aggregate_member_count_v< std::decay_t< Aggregate > > >( std::forward< Aggregate >( agg ) ); + return tuplizeAggregate< compute_salient_members_count_v< std::decay_t< Aggregate > > >( std::forward< Aggregate >( agg ) ); } } } diff --git a/comparisons.h b/comparisons.h index 579fea4..dd9cd1d 100644 --- a/comparisons.h +++ b/comparisons.h @@ -6,9 +6,12 @@ static_assert( __cplusplus > 201700, "C++17 Required" ); #include -#include +#include + #include +#include + namespace Alepha::Hydrogen { @@ -20,12 +23,8 @@ namespace Alepha::Hydrogen using namespace Meta::exports::template_overload; - // Basic capability support - // TODO: non-base-type capability via ADL rules on templates. - struct comparable {}; - namespace exports { using detail::comparisons::comparable; @@ -74,6 +73,14 @@ namespace Alepha::Hydrogen template< typename T > constexpr bool supports_spaceship_lens_v= supports_spaceship_lens< T >::value; + template< typename T > + constexpr decltype( auto ) + make_spaceship_lens( T &t ) + { + if constexpr( supports_spaceship_lens_v< T > ) return spaceship_lens( t ); + //else if constexpr( supports_default_lens_v< T > ) return default_lens( t ); + else static_assert( Meta::dep_value< false, T > ); + } // Value lens support @@ -121,6 +128,15 @@ namespace Alepha::Hydrogen template< typename T > constexpr bool supports_value_lens_v= supports_value_lens< T >::value; + template< typename T > + constexpr decltype( auto ) + make_value_lens( T &t ) + { + if constexpr( supports_value_lens_v< T > ) return value_lens( t ); + //else if constexpr( supports_default_lens_v< T > ) return default_lens( t ); + else static_assert( Meta::dep_value< false, T > ); + } + // Equality Lens support template< typename T, typename= void > @@ -167,6 +183,14 @@ namespace Alepha::Hydrogen template< typename T > constexpr bool supports_equality_lens_v= supports_equality_lens< T >::value; + template< typename T > + constexpr decltype( auto ) + make_equality_lens( T &t ) + { + if constexpr( supports_equality_lens_v< T > ) return equality_lens( t ); + //else if constexpr( supports_default_lens_v< T > ) return default_lens( t ); + else static_assert( Meta::dep_value< false, T > ); + } // Strict weak order lens support @@ -186,7 +210,7 @@ namespace Alepha::Hydrogen typename= std::enable_if_t< has_strict_weak_order_lens_member_v< T > >, overload< __LINE__ > = nullptr > - decltype( auto ) + constexpr decltype( auto ) strict_weak_order_lens( T &t ) { return t.strict_weak_order_lens(); @@ -199,7 +223,7 @@ namespace Alepha::Hydrogen typename= std::enable_if_t< supports_value_lens_v< T > >, overload< __LINE__ > = nullptr > - decltype( auto ) + constexpr decltype( auto ) strict_weak_order_lens( T &t ) { return value_lens( t ); @@ -214,84 +238,86 @@ namespace Alepha::Hydrogen template< typename T > constexpr bool supports_strict_weak_order_lens_v= supports_strict_weak_order_lens< T >::value; + template< typename T > + constexpr decltype( auto ) + make_strict_weak_order_lens( T &t ) + { + if constexpr( supports_strict_weak_order_lens_v< T > ) return strict_weak_order_lens( t ); + //else if constexpr( supports_default_lens_v< T > ) return default_lens( t ); + else static_assert( Meta::dep_value< false, T > ); + } // Operator support: template < typename T, typename= std::enable_if_t< has_comparable_capability_v< T > >, - typename= std::enable_if_t< supports_equality_lens_v< T > >, overload< __LINE__ > = nullptr > constexpr bool operator == ( const T &lhs, const T &rhs ) { - return equality_lens( lhs ) == equality_lens( rhs ); + return make_equality_lens( lhs ) == make_equality_lens( rhs ); } template < typename T, typename= std::enable_if_t< has_comparable_capability_v< T > >, - typename= std::enable_if_t< supports_equality_lens_v< T > >, overload< __LINE__ > = nullptr > constexpr bool operator != ( const T &lhs, const T &rhs ) { - return equality_lens( lhs ) != equality_lens( rhs ); + return make_equality_lens( lhs ) != make_equality_lens( rhs ); } template < typename T, typename= std::enable_if_t< has_comparable_capability_v< T > >, - typename= std::enable_if_t< supports_strict_weak_order_lens_v< T > >, overload< __LINE__ > = nullptr > constexpr bool operator < ( const T &lhs, const T &rhs ) { - return strict_weak_order_lens( lhs ) < strict_weak_order_lens( rhs ); + return make_strict_weak_order_lens( lhs ) < make_strict_weak_order_lens( rhs ); } template < typename T, typename= std::enable_if_t< has_comparable_capability_v< T > >, - typename= std::enable_if_t< supports_strict_weak_order_lens_v< T > >, overload< __LINE__ > = nullptr > constexpr bool operator > ( const T &lhs, const T &rhs ) { - return strict_weak_order_lens( lhs ) > strict_weak_order_lens( rhs ); + return make_strict_weak_order_lens( lhs ) > make_strict_weak_order_lens( rhs ); } template < typename T, typename= std::enable_if_t< has_comparable_capability_v< T > >, - typename= std::enable_if_t< supports_strict_weak_order_lens_v< T > >, overload< __LINE__ > = nullptr > constexpr bool operator <= ( const T &lhs, const T &rhs ) { - return strict_weak_order_lens( lhs ) <= strict_weak_order_lens( rhs ); + return make_strict_weak_order_lens( lhs ) <= make_strict_weak_order_lens( rhs ); } template < typename T, typename= std::enable_if_t< has_comparable_capability_v< T > >, - typename= std::enable_if_t< supports_strict_weak_order_lens_v< T > >, overload< __LINE__ > = nullptr > constexpr bool operator >= ( const T &lhs, const T &rhs ) { - return strict_weak_order_lens( lhs ) >= strict_weak_order_lens( rhs ); + return make_strict_weak_order_lens( lhs ) >= make_strict_weak_order_lens( rhs ); } template< typename ... Args >