diff --git a/Reflection/tagged_ctor_count.h b/Reflection/tagged_ctor_count.h index 66288c1..b9210f5 100644 --- a/Reflection/tagged_ctor_count.h +++ b/Reflection/tagged_ctor_count.h @@ -37,8 +37,9 @@ namespace Alepha::Hydrogen::Reflection ::detail:: tagged_ctor_count_m }; template< typename T, typename ... Args > - requires Concepts::ConstructibleFrom< T, Args... > - constexpr void construct( const std::tuple< Args... > & ); + requires( Concepts::ConstructibleFrom< T, Args... > ) + constexpr void construct( std::tuple< Args... > && ); + template< typename T, typename Tuple > concept ConstructibleWithTuple= @@ -66,13 +67,31 @@ namespace Alepha::Hydrogen::Reflection ::detail:: tagged_ctor_count_m // The first step is to just start it all off with a blank sequence and walk forward from there. // The default arguments cause it to start with the blank sequence, even if it doesn't match this // case in the specialization selection. - template< typename T, typename tag, std::size_t cnt= 0 > + template< typename T, typename tag, std::size_t cnt= 0, typename= void > struct tagged_ctor_count : tagged_ctor_count< T, tag, cnt + 1 > {}; + template< typename T, typename tag > + struct tagged_ctor_count< T, tag, C::max_ctor_size + 1 > + { + struct impossible; + static_assert( std::is_same_v< impossible, T >, "Max depth reached." ); + }; + template< typename T, typename tag, std::size_t depth > - requires ConstructibleWith< T, tag, depth > - struct tagged_ctor_count< T, tag, depth > + struct tagged_ctor_count + < + T, + tag, + depth, + std::void_t + < + decltype( construct< T > + ( + std::tuple_cat( std::declval< expand_t< T, depth > >(), std::declval< std::tuple< tag > >() ) + ) ) + > + > // Size is 1 more than the depth we probed, since that also accounts for the tag. : std::integral_constant< std::size_t, depth + 1 > {};