diff --git a/Sofa/framework/DefaultType/src/sofa/defaulttype/RigidTypes.h b/Sofa/framework/DefaultType/src/sofa/defaulttype/RigidTypes.h index f2294d62bd1..577da0cd2ec 100644 --- a/Sofa/framework/DefaultType/src/sofa/defaulttype/RigidTypes.h +++ b/Sofa/framework/DefaultType/src/sofa/defaulttype/RigidTypes.h @@ -140,7 +140,7 @@ class StdRigidTypes<3, real> getVCenter(c)[2] += static_cast(z); } - static constexpr const char* Name(); + static constexpr const char* Name() { return s_name.data(); } /// Return a Deriv with random value. Each entry with magnitude smaller than the given value. static Deriv randomDeriv(Real minMagnitude, Real maxMagnitude) @@ -240,17 +240,18 @@ class StdRigidTypes<3, real> /// create a rotation from Euler angles. For homogeneity with 2D. static Quat rotationEuler(Real x, Real y, Real z) { return Quat::fromEuler(x, y, z); } +private: + struct Prefix { static constexpr std::string_view value = "Rigid"; }; + + static constexpr auto s_name = helper::makeFixedSizeTypeName(); }; + typedef StdRigidTypes<3,double> Rigid3dTypes; typedef StdRigidTypes<3,float> Rigid3fTypes; -/// We now use template aliases so we do not break backward compatibility. -template<> constexpr const char* Rigid3dTypes::Name() { return "Rigid3d"; } -template<> constexpr const char* Rigid3fTypes::Name() { return "Rigid3f"; } - -typedef StdRigidTypes<3,SReal> Rigid3Types; ///< un-defined precision type -typedef StdRigidTypes<3,SReal> RigidTypes; ///< alias (beurk) +typedef StdRigidTypes<3,SReal> Rigid3Types; +typedef StdRigidTypes<3,SReal> RigidTypes; static_assert(type::isRigidType); static_assert(type::isRigidType); @@ -289,7 +290,7 @@ class StdRigidTypes<2, real> static constexpr const DRot& getDRot(const Deriv& d) { return getVOrientation(d); } static constexpr void setDRot(Deriv& d, const DRot& v) { getVOrientation(d) = v; } - static constexpr const char* Name(); + static constexpr const char* Name() { return s_name.data(); } typedef type::vector VecCoord; typedef type::vector VecDeriv; @@ -411,12 +412,12 @@ class StdRigidTypes<2, real> /// create a rotation from Euler angles (only the first is used). For homogeneity with 3D. static constexpr CRot rotationEuler( Real x, Real , Real ){ return CRot(x); } +private: + struct Prefix { static constexpr std::string_view value = "Rigid"; }; + static constexpr auto s_name = helper::makeFixedSizeTypeName(); }; -template<> constexpr const char* Rigid2dTypes::Name() { return "Rigid2d"; } -template<> constexpr const char* Rigid2fTypes::Name() { return "Rigid2f"; } - static_assert(type::isRigidType); static_assert(type::isRigidType); diff --git a/Sofa/framework/DefaultType/src/sofa/defaulttype/VecTypes.h b/Sofa/framework/DefaultType/src/sofa/defaulttype/VecTypes.h index 789ab1ca252..b5eb80bfd12 100644 --- a/Sofa/framework/DefaultType/src/sofa/defaulttype/VecTypes.h +++ b/Sofa/framework/DefaultType/src/sofa/defaulttype/VecTypes.h @@ -178,7 +178,7 @@ class StdVectorTypes Impl::add(c,x,y,z); } - static constexpr const char* Name(); + static constexpr const char* Name() { return s_name.data();} static Coord interpolate(const type::vector< Coord > &ancestors, const type::vector< Real > &coefs) { @@ -193,50 +193,42 @@ class StdVectorTypes return c; } -}; - -/// 3D DOFs, double precision -typedef StdVectorTypes Vec3dTypes; -template<> constexpr const char* Vec3dTypes::Name() { return "Vec3d"; } +private: -/// 2D DOFs, double precision -typedef StdVectorTypes Vec2dTypes; -template<> constexpr const char* Vec2dTypes::Name() { return "Vec2d"; } + struct Prefix { static constexpr std::string_view value = "Vec"; }; -/// 1D DOFs, double precision -typedef StdVectorTypes Vec1dTypes; -template<> constexpr const char* Vec1dTypes::Name() { return "Vec1d"; } + static constexpr auto s_name = helper::makeFixedSizeTypeName(); +}; -/// 6D DOFs, double precision -typedef StdVectorTypes Vec6dTypes; -template<> constexpr const char* Vec6dTypes::Name() { return "Vec6d"; } +namespace internal +{ +template using VecTypes = StdVectorTypes, type::Vec, T>; +} -/// 3f DOFs, single precision -typedef StdVectorTypes Vec3fTypes; -template<> constexpr const char* Vec3fTypes::Name() { return "Vec3f"; } +using Vec3dTypes = internal::VecTypes<3, double>; +using Vec2dTypes = internal::VecTypes<2, double>; +using Vec1dTypes = internal::VecTypes<1, double>; +using Vec6dTypes = internal::VecTypes<6, double>; -/// 2f DOFs, single precision -typedef StdVectorTypes Vec2fTypes; -template<> constexpr const char* Vec2fTypes::Name() { return "Vec2f"; } +using Vec3fTypes = internal::VecTypes<3, float>; +using Vec2fTypes = internal::VecTypes<2, float>; +using Vec1fTypes = internal::VecTypes<1, float>; +using Vec6fTypes = internal::VecTypes<6, float>; -/// 1f DOFs, single precision -typedef StdVectorTypes Vec1fTypes; -template<> constexpr const char* Vec1fTypes::Name() { return "Vec1f"; } +using Vec3Types = internal::VecTypes<3, SReal>; +using Vec2Types = internal::VecTypes<2, SReal>; +using Vec1Types = internal::VecTypes<1, SReal>; +using Vec6Types = internal::VecTypes<6, SReal>; -/// 6f DOFs, single precision -typedef StdVectorTypes Vec6fTypes; -template<> constexpr const char* Vec6fTypes::Name() { return "Vec6f"; } -/// 6D DOFs, double precision (default) -typedef StdVectorTypes Vec6Types; -/// 3D DOFs, double precision (default) -typedef StdVectorTypes Vec3Types; -/// 2D DOFs, double precision (default) -typedef StdVectorTypes Vec2Types; -/// 1D DOFs, double precision (default) -typedef StdVectorTypes Vec1Types; +static_assert(std::string_view(Vec1dTypes::Name()) == "Vec1d"); +static_assert(std::string_view(Vec2dTypes::Name()) == "Vec2d"); +static_assert(std::string_view(Vec3dTypes::Name()) == "Vec3d"); +static_assert(std::string_view(Vec1fTypes::Name()) == "Vec1f"); +static_assert(std::string_view(Vec2fTypes::Name()) == "Vec2f"); +static_assert(std::string_view(Vec3fTypes::Name()) == "Vec3f"); static_assert(!type::isRigidType); static_assert(!type::isRigidType); diff --git a/Sofa/framework/Helper/src/sofa/helper/StringUtils.h b/Sofa/framework/Helper/src/sofa/helper/StringUtils.h index 8ee732f6bb5..8de84cde877 100644 --- a/Sofa/framework/Helper/src/sofa/helper/StringUtils.h +++ b/Sofa/framework/Helper/src/sofa/helper/StringUtils.h @@ -22,12 +22,12 @@ #pragma once #include +#include +#include #include #include #include -#include - namespace sofa::helper { @@ -109,4 +109,33 @@ SOFA_HELPER_API std::string_view removeTrailingCharacter(std::string_view sv, ch ///@brief Removes specified trailing characters from a string view. SOFA_HELPER_API std::string_view removeTrailingCharacters(std::string_view sv, std::initializer_list characters); +template +constexpr std::size_t numDigits(T n) +{ + std::size_t d = 1; + while (n >= 10) { n /= 10; ++d; } + return d; +} + +template +constexpr static auto makeFixedSizeTypeName() +{ + constexpr std::string_view prefix = Prefix::value; + constexpr std::size_t d = sofa::helper::numDigits(N); + constexpr auto suffix = type::TypeTrait::suffix; + + std::array s{}; + std::copy(prefix.begin(), prefix.end(), s.begin()); + int n = N; + for (int i = d - 1; i >= 0; --i) + { + s[prefix.size() + i] = static_cast('0' + n % 10); + n /= 10; + } + //suffix + std::copy(suffix.begin(), suffix.end(), s.begin() + prefix.size() + d); + s[prefix.size() + d + suffix.size()] = '\0'; + return s; +} + } // namespace sofa::helper diff --git a/Sofa/framework/Type/src/sofa/type/trait/TypeTrait.h b/Sofa/framework/Type/src/sofa/type/trait/TypeTrait.h index d6ac21ab500..78e49f93bb5 100644 --- a/Sofa/framework/Type/src/sofa/type/trait/TypeTrait.h +++ b/Sofa/framework/Type/src/sofa/type/trait/TypeTrait.h @@ -21,6 +21,7 @@ ******************************************************************************/ #pragma once +#include #include namespace sofa::type