diff --git a/Sofa/framework/Type/src/sofa/type/Quat.h b/Sofa/framework/Type/src/sofa/type/Quat.h index 739fa6e5f59..05b534d7e33 100644 --- a/Sofa/framework/Type/src/sofa/type/Quat.h +++ b/Sofa/framework/Type/src/sofa/type/Quat.h @@ -116,7 +116,7 @@ class Quat static Quat identity() { - return Quat(0,0,0,1); + return Quat(0, 0, 0, 1); } void set(Real x, Real y, Real z, Real w) @@ -147,7 +147,7 @@ class Quat void clear() { - set(0.0,0.0,0.0,1); + set(0, 0, 0, 1); } /// Convert the reference frame orientation into an orientation quaternion @@ -311,6 +311,30 @@ class Quat return _q[index]; } + template< std::size_t I > + [[nodiscard]] constexpr Real& get() & noexcept requires (I < 4) + { + return _q[I]; + } + + template< std::size_t I > + [[nodiscard]] constexpr const Real& get() const& noexcept requires (I < 4) + { + return _q[I]; + } + + template< std::size_t I > + [[nodiscard]] constexpr Real&& get() && noexcept requires (I < 4) + { + return std::move(_q[I]); + } + + template< std::size_t I > + [[nodiscard]] constexpr const Real&& get() const&& noexcept requires (I < 4) + { + return std::move(_q[I]); + } + auto inverse() const -> Quat; auto quatToRotationVector() const -> Vec3; @@ -462,3 +486,17 @@ extern template class SOFA_TYPE_API Quat; #endif } // namespace sofa::type + +namespace std +{ + +template +struct tuple_size<::sofa::type::Quat > : integral_constant {}; + +template +struct tuple_element > +{ + using type = typename::sofa::type::Quat::value_type; +}; + +} diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.h b/Sofa/framework/Type/src/sofa/type/RGBAColor.h index 44fefc4eacc..0d4af4739a8 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.h +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.h @@ -33,6 +33,8 @@ #include #include +#include + namespace sofa::type { @@ -45,8 +47,9 @@ namespace sofa::type class SOFA_TYPE_API RGBAColor { public: + using value_type = float; static constexpr sofa::Size NumberOfComponents = 4; - using ComponentArray = std::array; + using ComponentArray = std::array; constexpr RGBAColor() : m_components{ 1.f, 1.f, 1.f, 1.f } {} @@ -132,6 +135,30 @@ class SOFA_TYPE_API RGBAColor return m_components[i]; } + template< std::size_t I > + [[nodiscard]] constexpr float& get() & noexcept requires (I < 4) + { + return m_components[I]; + } + + template< std::size_t I > + [[nodiscard]] constexpr const float& get() const& noexcept requires (I < 4) + { + return m_components[I]; + } + + template< std::size_t I > + [[nodiscard]] constexpr float&& get() && noexcept requires (I < 4) + { + return std::move(m_components[I]); + } + + template< std::size_t I > + [[nodiscard]] constexpr const float&& get() const&& noexcept requires (I < 4) + { + return std::move(m_components[I]); + } + void set(float r, float g, float b, float a) ; bool operator==(const RGBAColor& b) const @@ -209,7 +236,6 @@ class SOFA_TYPE_API RGBAColor static constexpr sofa::Size static_size = NumberOfComponents; static constexpr sofa::Size size() { return static_size; } - using value_type = float; using size_type = sofa::Size; private: @@ -285,3 +311,18 @@ constexpr const RGBAColor& RGBAColor::gold() { return g_gold ; } } // namespace sofa::type + + +namespace std +{ + +template<> +struct tuple_size<::sofa::type::RGBAColor > : integral_constant {}; + +template +struct tuple_element +{ + using type = ::sofa::type::RGBAColor::value_type; +}; + +} diff --git a/Sofa/framework/Type/src/sofa/type/Vec.h b/Sofa/framework/Type/src/sofa/type/Vec.h index 48e38f038b2..7c0b5a7ff23 100644 --- a/Sofa/framework/Type/src/sofa/type/Vec.h +++ b/Sofa/framework/Type/src/sofa/type/Vec.h @@ -613,6 +613,30 @@ class Vec return elems[i]; } + template< std::size_t I > + [[nodiscard]] constexpr reference get() & noexcept requires( I < N ) + { + return elems[I]; + } + + template< std::size_t I > + [[nodiscard]] constexpr const_reference get() const& noexcept requires( I < N ) + { + return elems[I]; + } + + template< std::size_t I > + [[nodiscard]] constexpr ValueType&& get() && noexcept requires( I < N ) + { + return std::move(elems[I]); + } + + template< std::size_t I > + [[nodiscard]] constexpr const ValueType&& get() const&& noexcept requires( I < N ) + { + return std::move(elems[I]); + } + // direct access to data constexpr const ValueType* data() const noexcept { @@ -782,4 +806,13 @@ struct less< sofa::type::Vec > } }; +template +struct tuple_size<::sofa::type::Vec > : integral_constant {}; + +template +struct tuple_element > +{ + using type = T; +}; + } // namespace std diff --git a/Sofa/framework/Type/test/Quater_test.cpp b/Sofa/framework/Type/test/Quater_test.cpp index 7fdf2a0849b..408dfa53a01 100644 --- a/Sofa/framework/Type/test/Quater_test.cpp +++ b/Sofa/framework/Type/test/Quater_test.cpp @@ -707,4 +707,12 @@ TEST(QuaterTest, QuaterdFromUnitVectors) EXPECT_NEAR(0.5894552112230939, quat1[3], errorThreshold); } - +TEST(QuaterTest, StructuredBindings) +{ + Quat quat1; + const auto& [a,b,c,d] = quat1; + EXPECT_NEAR(0., a, errorThreshold); + EXPECT_NEAR(0., b, errorThreshold); + EXPECT_NEAR(0., c, errorThreshold); + EXPECT_NEAR(1., d, errorThreshold); +} diff --git a/Sofa/framework/Type/test/RGBAColor_test.cpp b/Sofa/framework/Type/test/RGBAColor_test.cpp index 1f4d37dc5b1..a31e3582a96 100644 --- a/Sofa/framework/Type/test/RGBAColor_test.cpp +++ b/Sofa/framework/Type/test/RGBAColor_test.cpp @@ -44,6 +44,7 @@ class Color_Test : public BaseTest, void checkStreamingOperator(const std::vector&) ; void checkDoubleStreamingOperator(const std::vector&) ; void testEnlight(); + void testStructuredBindings(); }; void Color_Test::testEnlight() @@ -54,6 +55,15 @@ void Color_Test::testEnlight() EXPECT_EQ( RGBAColor::lighten(RGBAColor::red(), 0.5), RGBAColor(1.0,0.5,0.5,1.0) ) ; } +void Color_Test::testStructuredBindings() +{ + const auto& [r, g, b, a] = RGBAColor::red(); + EXPECT_EQ(r, 1.); + EXPECT_EQ(g, 0.); + EXPECT_EQ(b, 0.); + EXPECT_EQ(a, 1.); +} + void Color_Test::checkCreateFromString() { EXPECT_EQ( RGBAColor::fromString("white"), RGBAColor(1.0,1.0,1.0,1.0) ) ; @@ -277,6 +287,11 @@ TEST_F(Color_Test, checkEnlight) this->testEnlight() ; } +TEST_F(Color_Test, testStructuredBindings) +{ + this->testStructuredBindings(); +} + std::vector> testvalues = { {" 0 0 0 0","0 0 0 0", "S"}, diff --git a/Sofa/framework/Type/test/VecTypes_test.cpp b/Sofa/framework/Type/test/VecTypes_test.cpp index a4f10dab1ab..ed3460a56ce 100644 --- a/Sofa/framework/Type/test/VecTypes_test.cpp +++ b/Sofa/framework/Type/test/VecTypes_test.cpp @@ -23,4 +23,11 @@ #include #include - +TEST(VecTest, StructuredBindings) +{ + constexpr sofa::type::Vec3 vec { 1.0, 2.0, 3.0 }; + const auto& [a, b, c] = vec; + EXPECT_EQ(a, 1.); + EXPECT_EQ(b, 2.); + EXPECT_EQ(c, 3.); +}