Skip to content

Commit

Permalink
[Type] Support structured binding for tuple-like types (#5208)
Browse files Browse the repository at this point in the history
* [Type] Support structured binding for tuple-like types

* fix redefinition

* fix test
  • Loading branch information
alxbilger authored Jan 20, 2025
1 parent aedc7ff commit eb9fe59
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 6 deletions.
42 changes: 40 additions & 2 deletions Sofa/framework/Type/src/sofa/type/Quat.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -462,3 +486,17 @@ extern template class SOFA_TYPE_API Quat<float>;
#endif

} // namespace sofa::type

namespace std
{

template<class Real>
struct tuple_size<::sofa::type::Quat<Real> > : integral_constant<size_t, 4> {};

template<std::size_t I, class Real>
struct tuple_element<I, ::sofa::type::Quat<Real> >
{
using type = typename::sofa::type::Quat<Real>::value_type;
};

}
45 changes: 43 additions & 2 deletions Sofa/framework/Type/src/sofa/type/RGBAColor.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include <cassert>

#include <sofa/type/fixed_array_algorithms.h>
#include <sofa/type/StrongType.h>


namespace sofa::type
{
Expand All @@ -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<float, NumberOfComponents>;
using ComponentArray = std::array<value_type, NumberOfComponents>;

constexpr RGBAColor()
: m_components{ 1.f, 1.f, 1.f, 1.f } {}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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<size_t, ::sofa::type::RGBAColor::NumberOfComponents> {};

template<std::size_t I>
struct tuple_element<I, ::sofa::type::RGBAColor >
{
using type = ::sofa::type::RGBAColor::value_type;
};

}
33 changes: 33 additions & 0 deletions Sofa/framework/Type/src/sofa/type/Vec.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -782,4 +806,13 @@ struct less< sofa::type::Vec<N,T> >
}
};

template<sofa::Size N, class T>
struct tuple_size<::sofa::type::Vec<N,T> > : integral_constant<size_t, N> {};

template<std::size_t I, sofa::Size N, class T >
struct tuple_element<I, ::sofa::type::Vec<N,T> >
{
using type = T;
};

} // namespace std
10 changes: 9 additions & 1 deletion Sofa/framework/Type/test/Quater_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -707,4 +707,12 @@ TEST(QuaterTest, QuaterdFromUnitVectors)
EXPECT_NEAR(0.5894552112230939, quat1[3], errorThreshold);
}


TEST(QuaterTest, StructuredBindings)
{
Quat<double> 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);
}
15 changes: 15 additions & 0 deletions Sofa/framework/Type/test/RGBAColor_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class Color_Test : public BaseTest,
void checkStreamingOperator(const std::vector<std::string>&) ;
void checkDoubleStreamingOperator(const std::vector<std::string>&) ;
void testEnlight();
void testStructuredBindings();
};

void Color_Test::testEnlight()
Expand All @@ -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) ) ;
Expand Down Expand Up @@ -277,6 +287,11 @@ TEST_F(Color_Test, checkEnlight)
this->testEnlight() ;
}

TEST_F(Color_Test, testStructuredBindings)
{
this->testStructuredBindings();
}

std::vector<std::vector<std::string>> testvalues =
{
{" 0 0 0 0","0 0 0 0", "S"},
Expand Down
9 changes: 8 additions & 1 deletion Sofa/framework/Type/test/VecTypes_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,11 @@
#include <sofa/defaulttype/VecTypes.h>
#include <gtest/gtest.h>


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.);
}

0 comments on commit eb9fe59

Please sign in to comment.