diff --git a/alib2common/src/core/components.hpp b/alib2common/src/core/components.hpp index da115825604d5611d0720c80f081607435cef422..89c49c6e094cf4c1e07a8ab5edb6a3c34399b0f4 100644 --- a/alib2common/src/core/components.hpp +++ b/alib2common/src/core/components.hpp @@ -305,7 +305,7 @@ struct ComponentAux < Derived, SymbolType, tuple < SetTypes ... > > : public Com * @param SetType alphabet type used to distinguish different sub alphabets * @return sub-component */ - template < class SetType > + template < class SetType, typename std::enable_if < std::is_in < SetType, SetTypes ... >::value >::type * = nullptr > const Component < Derived, SymbolType, SetType > & accessComponent ( ) const { return static_cast < const Component < Derived, SymbolType, SetType > & > ( * this ); } @@ -315,7 +315,7 @@ struct ComponentAux < Derived, SymbolType, tuple < SetTypes ... > > : public Com * @param SetType alphabet type used to distinguish different sub alphabets * @return sub-component */ - template < class SetType > + template < class SetType, typename std::enable_if < std::is_in < SetType, SetTypes ... >::value >::type * = nullptr > Component < Derived, SymbolType, SetType > & accessComponent ( ) { return static_cast < Component < Derived, SymbolType, SetType > & > ( * this ); } @@ -355,7 +355,7 @@ struct ElementAux < Derived, SymbolType, tuple < ElementTypes ... > > : public E * @param ElementType alphabet type used to distinguish different sub alphabets * @return sub-component */ - template < class ElementType > + template < class ElementType, typename std::enable_if < std::is_in < ElementType, ElementTypes ... >::value >::type * = nullptr > const Element < Derived, SymbolType, ElementType > & accessElement ( ) const { return static_cast < const Element < Derived, SymbolType, ElementType > & > ( * this ); } @@ -365,7 +365,7 @@ struct ElementAux < Derived, SymbolType, tuple < ElementTypes ... > > : public E * @param ElementType alphabet type used to distinguish different sub alphabets * @return sub-component */ - template < class ElementType > + template < class ElementType, typename std::enable_if < std::is_in < ElementType, ElementTypes ... >::value >::type * = nullptr > Element < Derived, SymbolType, ElementType > & accessElement ( ) { return static_cast < Element < Derived, SymbolType, ElementType > & > ( * this ); } @@ -409,12 +409,18 @@ public: /** * Construct an alphabet pack from two alphabets. */ - template < class RealSetTypes, class RealElementTypes > - Components ( RealSetTypes params1, RealElementTypes params2 ) : ComponentAux < Derived, SymbolType, SetTypesPack > ( std::move ( params1 ), std::make_index_sequence < std::tuple_size < SetTypesPack >::value > { } ), ElementAux < Derived, SymbolType, ElementTypesPack > ( std::move ( params2 ), std::make_index_sequence < std::tuple_size < ElementTypesPack >::value > { } ) { + template < class RealSetTypes, class RealElementTypes, class ... NextRealTypes > + Components ( RealSetTypes params1, RealElementTypes params2, NextRealTypes ... nextParams ) : ComponentAux < Derived, SymbolType, SetTypesPack > ( std::move ( params1 ), std::make_index_sequence < std::tuple_size < SetTypesPack >::value > { } ), ElementAux < Derived, SymbolType, ElementTypesPack > ( std::move ( params2 ), std::make_index_sequence < std::tuple_size < ElementTypesPack >::value > { } ), Components < Derived, NextGroup ... > ( std::move ( nextParams ) ... ) { ComponentAux < Derived, SymbolType, SetTypesPack >::checkState ( ); ElementAux < Derived, SymbolType, ElementTypesPack >::checkState ( ); } + + using ComponentAux < Derived, SymbolType, SetTypesPack >::accessComponent; + using ElementAux < Derived, SymbolType, ElementTypesPack >::accessElement; + + using Components < Derived, NextGroup ... >::accessComponent; + using Components < Derived, NextGroup ... >::accessElement; }; } /* namespace std */ diff --git a/alib2std/src/extensions/type_traits.hpp b/alib2std/src/extensions/type_traits.hpp index 09755ae36ce82db1cc5f5bafef62d2ee3ec0b2f1..8b3924ada4618fefd2b893f747cb57ce55d8bda0 100644 --- a/alib2std/src/extensions/type_traits.hpp +++ b/alib2std/src/extensions/type_traits.hpp @@ -45,6 +45,18 @@ namespace std { typedef typename get_type_pack_element < N - 1, Ts ... >::type type; }; + template < typename T, typename ... Ts > + struct is_in; + + template < typename T > + struct is_in < T > : std::false_type { }; + + template < typename T, typename U, typename ... Ts > + struct is_in < T, U, Ts ... > : is_in < T, Ts ... > { }; + + template < typename T, typename ... Ts > + struct is_in < T, T, Ts ... > : std::true_type { }; + } /* namespace std */ #endif // TYPE_TRAITS_HPP_ diff --git a/alib2std/test-src/extensions/TypeTraitsTest.cpp b/alib2std/test-src/extensions/TypeTraitsTest.cpp index 1fb9db2a2e22e6afa29ddc21c7adbbff90c4efbf..5790deafa87352c899211b960450cde77856c78d 100644 --- a/alib2std/test-src/extensions/TypeTraitsTest.cpp +++ b/alib2std/test-src/extensions/TypeTraitsTest.cpp @@ -20,3 +20,8 @@ void TypeTraitsTest::testIsBaseOf() { void TypeTraitsTest::testAccessPackElement() { CPPUNIT_ASSERT( ( std::is_same< std::get_type_pack_element < 0, int, double >::type, int >::value ) == true ); } + +void TypeTraitsTest::testTypeInPack() { + CPPUNIT_ASSERT( ( std::is_in< int, double, std::set<int>, float, char, int, std::string >::value ) == true ); + CPPUNIT_ASSERT( ( std::is_in< long, double, std::set<int>, float, char, int, std::string >::value ) == false ); +} diff --git a/alib2std/test-src/extensions/TypeTraitsTest.h b/alib2std/test-src/extensions/TypeTraitsTest.h index aaa13c3681d72d6befd58d7adf52e35084b231fa..43f01fc916a9d933f98732d2f66cafc59497f52e 100644 --- a/alib2std/test-src/extensions/TypeTraitsTest.h +++ b/alib2std/test-src/extensions/TypeTraitsTest.h @@ -8,6 +8,7 @@ class TypeTraitsTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE( TypeTraitsTest ); CPPUNIT_TEST( testIsBaseOf ); CPPUNIT_TEST( testAccessPackElement ); + CPPUNIT_TEST( testTypeInPack ); CPPUNIT_TEST_SUITE_END(); public: @@ -65,6 +66,7 @@ public: void testIsBaseOf(); void testAccessPackElement(); + void testTypeInPack(); }; #endif // TYPE_TRAITS_TEST_H_