diff --git a/Sofa/framework/Type/src/sofa/type/trait/Rebind.h b/Sofa/framework/Type/src/sofa/type/trait/Rebind.h index c462e08a1f4..994158d70b8 100644 --- a/Sofa/framework/Type/src/sofa/type/trait/Rebind.h +++ b/Sofa/framework/Type/src/sofa/type/trait/Rebind.h @@ -23,19 +23,18 @@ namespace sofa::type { - // primary template handles types that have no nested ::rebind_to member: - template< class T, class OtherType, class = void > - struct HasRebindTypedef : std::false_type { }; + template + concept CanTypeRebind = requires + { + typename T::template rebind_to; + }; - // specialization recognizes types that do have a nested ::rebind_to member: - template< class T, class OtherType > - struct HasRebindTypedef > > : std::true_type { }; /** * Depending on the type _T, has a public member typedef to. Otherwise, there is no member typedef (this is the * case of this implementation). */ - template + template struct Rebind {}; /** @@ -45,33 +44,20 @@ namespace sofa::type * \tparam _T Type that does have a nested ::rebind_to member */ template - struct Rebind<_T, _OtherType, std::enable_if_t::value > > + requires CanTypeRebind<_T, _OtherType> + struct Rebind<_T, _OtherType> { using to = typename _T::template rebind_to<_OtherType>; }; - template - inline constexpr auto deny = false; - - /** - * \brief Specialization for types that do NOT have a nested ::rebind_to member. In this implementation, Rebind has - * no public member typedef \ref to. If this implementation is chosen by the compiler (the number of template - * parameters is probably different from 1), a compilation error occurs. - * \tparam _T Type that does NOT have a nested ::rebind_to member - */ - template - struct Rebind<_T, _OtherType, std::enable_if_t::value > > - { - static_assert(deny<_T>, "_T must match _T"); - }; - /** * \brief Specialization for types that do NOT have a nested ::rebind_to member. In this implementation, Rebind has * a public member typedef \ref to. * \tparam _T Type that does NOT have a nested ::rebind_to member */ template class _T, class A, class _OtherType> - struct Rebind<_T, _OtherType, std::enable_if_t, _OtherType >::value > > + requires (!CanTypeRebind<_T, _OtherType>) + struct Rebind<_T, _OtherType> { using to = _T<_OtherType>; }; @@ -83,7 +69,7 @@ namespace sofa::type * 1) sofa::type::rebind_to< sofa::type::vector, float> is of type sofa::type::vector. In this example, * sofa::type::vector has a typedef rebind_to that will be used to deduce the type. * 2) sofa::type::rebind_to< sofa::type::Quat, double> is of type sofa::type::Quat. In this example, - * sofa::type::Quat does not have a typdef rebind_to. + * sofa::type::Quat does not have a typedef rebind_to. * 3) It makes no sense to use sofa::type::rebind on types having more than one template parameter, such as * sofa::type::fixed_array. A compilation error would occur. */ diff --git a/Sofa/framework/Type/test/CMakeLists.txt b/Sofa/framework/Type/test/CMakeLists.txt index d6ac8363490..7e9ba83bd72 100644 --- a/Sofa/framework/Type/test/CMakeLists.txt +++ b/Sofa/framework/Type/test/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCE_FILES MatTypes_test.cpp Material_test.cpp Quater_test.cpp + Rebind_test.cpp RGBAColor_test.cpp StrongType_test.cpp SVector_test.cpp diff --git a/Sofa/framework/Type/test/Rebind_test.cpp b/Sofa/framework/Type/test/Rebind_test.cpp new file mode 100644 index 00000000000..5ef91da5aea --- /dev/null +++ b/Sofa/framework/Type/test/Rebind_test.cpp @@ -0,0 +1,59 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#include +#include + +static_assert(sofa::type::CanTypeRebind, int>); +static_assert(sofa::type::CanTypeRebind, int>); + +static_assert( + std::is_same_v< + sofa::type::rebind_to, int>, + sofa::type::vector + >); +static_assert( + std::is_same_v< + sofa::type::rebind_to, int>, + sofa::type::vector + >); + +template +struct DummyNoRebind{}; + +static_assert(!sofa::type::CanTypeRebind, int>); + +static_assert( + std::is_same_v< + sofa::type::rebind_to, int>, + DummyNoRebind + >); + +template +struct DummyWithConstraintRebind +{ + template + requires std::is_integral_v + using rebind_to = U; +}; + +static_assert(sofa::type::CanTypeRebind, int>); +static_assert(!sofa::type::CanTypeRebind, std::string>); diff --git a/Sofa/framework/Type/test/vector_test.cpp b/Sofa/framework/Type/test/vector_test.cpp index 11fa007a3a7..4322c605587 100644 --- a/Sofa/framework/Type/test/vector_test.cpp +++ b/Sofa/framework/Type/test/vector_test.cpp @@ -49,7 +49,7 @@ class vector_test : public NumericTest<>, void checkVector(const std::vector& params) ; void checkVectorAccessFailure() const; - void checkRebind(); + void checkRebind() const; }; template @@ -103,14 +103,18 @@ void vector_test::checkVectorAccessFailure() const } template -void vector_test::checkRebind() +void vector_test::checkRebind() const { - constexpr bool hasRebind = sofa::type::HasRebindTypedef, int>::value; + constexpr bool hasRebind = sofa::type::CanTypeRebind, int>; + static_assert(hasRebind); EXPECT_TRUE(hasRebind); - using rebinded = typename sofa::type::Rebind, int >::to; - using vec_int = vector; - constexpr bool isRebindOK = std::is_same_v; - EXPECT_TRUE(isRebindOK); + if constexpr (hasRebind) + { + using rebinded = typename sofa::type::Rebind, int >::to; + using vec_int = vector; + constexpr bool isRebindOK = std::is_same_v; + EXPECT_TRUE(isRebindOK); + } } ////////////////////////////////////////////////////////////////////////////////////////////////////