Skip to content

Commit 8af6652

Browse files
ZXShadychristophe
authored and
christophe
committed
Add C++17 structureed binding support
Add C++17 Structured Bindings support for vec,mat,quat types
1 parent 5847dd9 commit 8af6652

File tree

4 files changed

+514
-0
lines changed

4 files changed

+514
-0
lines changed

glm/gtx/structured_bindings.hpp

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/// @ref gtx_structured_bindings
2+
/// @file glm/gtx/structured_bindings.hpp
3+
///
4+
/// @defgroup gtx_structured_bindings GLM_GTX_structured_bindings
5+
/// @ingroup gtx
6+
///
7+
/// Include <glm/gtx/structured_bindings.hpp> to use the features of this extension.
8+
9+
#pragma once
10+
11+
// Dependency:
12+
#include "../glm.hpp"
13+
#include "../gtx/quaternion.hpp"
14+
15+
#ifdef __cpp_structured_bindings
16+
#if __cpp_structured_bindings >= 201606L
17+
#include <utility>
18+
#include <cstddef>
19+
namespace std {
20+
template<glm::length_t L,typename T,glm::qualifier Q>
21+
struct tuple_size<glm::vec<L, T, Q>> {
22+
static constexpr size_t value = L;
23+
};
24+
template<glm::length_t C,glm::length_t R, typename T, glm::qualifier Q>
25+
struct tuple_size<glm::mat<C,R, T, Q>> {
26+
static constexpr size_t value = C;
27+
};
28+
template<typename T, glm::qualifier Q>
29+
struct tuple_size<glm::qua<T, Q>> {
30+
static constexpr size_t value = 4;
31+
};
32+
template<std::size_t I,glm::length_t L,typename T,glm::qualifier Q>
33+
struct tuple_element<I, glm::vec<L,T,Q>>
34+
{
35+
GLM_STATIC_ASSERT(I < L,"Index out of bounds");
36+
typedef T type;
37+
};
38+
template<std::size_t I, glm::length_t C, glm::length_t R, typename T, glm::qualifier Q>
39+
struct tuple_element<I, glm::mat<C,R, T, Q>>
40+
{
41+
GLM_STATIC_ASSERT(I < C, "Index out of bounds");
42+
typedef glm::vec<R,T,Q> type;
43+
};
44+
template<std::size_t I, typename T, glm::qualifier Q>
45+
struct tuple_element<I, glm::qua<T, Q>>
46+
{
47+
GLM_STATIC_ASSERT(I < 4, "Index out of bounds");
48+
typedef T type;
49+
};
50+
51+
}
52+
#endif
53+
#endif
54+
55+
#ifndef GLM_ENABLE_EXPERIMENTAL
56+
# error "GLM: GLM_GTX_iteration is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
57+
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
58+
# pragma message("GLM: GLM_GTX_io extension included")
59+
#endif
60+
61+
namespace glm
62+
{
63+
/// @addtogroup gtx_structured_bindings
64+
/// @{
65+
66+
template<length_t I, length_t L, typename T, qualifier Q>
67+
GLM_FUNC_DECL GLM_CONSTEXPR T& get(vec<L, T, Q>& v);
68+
template<length_t I, length_t L, typename T, qualifier Q>
69+
GLM_FUNC_DECL GLM_CONSTEXPR T const& get(vec<L, T, Q> const& v);
70+
71+
template<length_t I, length_t C, length_t R, typename T, qualifier Q>
72+
GLM_FUNC_DECL GLM_CONSTEXPR vec<R, T, Q>& get(mat<C, R, T, Q>& m);
73+
template<length_t I, length_t C, length_t R, typename T, qualifier Q>
74+
GLM_FUNC_DECL GLM_CONSTEXPR vec<R, T, Q> const& get(mat<C, R, T, Q> const& m);
75+
76+
template<length_t I, typename T, qualifier Q>
77+
GLM_FUNC_DECL GLM_CONSTEXPR T& get(qua<T, Q>& q);
78+
template<length_t I, typename T, qualifier Q>
79+
GLM_FUNC_DECL GLM_CONSTEXPR T const& get(qua<T, Q> const& q);
80+
81+
#if GLM_HAS_RVALUE_REFERENCES
82+
template<length_t I, length_t L,typename T, qualifier Q>
83+
GLM_FUNC_DECL GLM_CONSTEXPR T get(vec<L,T, Q> const&& v);
84+
template<length_t I,length_t C,length_t R, typename T, qualifier Q>
85+
GLM_FUNC_DECL GLM_CONSTEXPR vec<R,T,Q> get(mat<C,R,T, Q> const&& m);
86+
template<length_t I, typename T, qualifier Q>
87+
GLM_FUNC_DECL GLM_CONSTEXPR T get(qua<T, Q> const&& q);
88+
#endif
89+
/// @}
90+
}//namespace glm
91+
92+
#include "structured_bindings.inl"

glm/gtx/structured_bindings.inl

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
namespace glm
2+
{
3+
template<length_t I, length_t L, typename T, qualifier Q>
4+
GLM_CONSTEXPR T& get(vec<L, T, Q>& v) {
5+
GLM_STATIC_ASSERT(I < L, "Index out of bounds");
6+
return v[I];
7+
}
8+
template<length_t I, length_t L, typename T, qualifier Q>
9+
GLM_CONSTEXPR T const& get(vec<L, T, Q> const& v) {
10+
GLM_STATIC_ASSERT(I < L, "Index out of bounds");
11+
return v[I];
12+
}
13+
14+
template<length_t I, length_t C, length_t R, typename T, qualifier Q>
15+
GLM_CONSTEXPR vec<R, T, Q>& get(mat<C, R, T, Q>& m) {
16+
GLM_STATIC_ASSERT(I < C, "Index out of bounds");
17+
return m[I];
18+
}
19+
template<length_t I, length_t C, length_t R, typename T, qualifier Q>
20+
GLM_CONSTEXPR vec<R, T, Q> const& get(mat<C, R, T, Q> const& m) {
21+
GLM_STATIC_ASSERT(I < C, "Index out of bounds");
22+
return m[I];
23+
}
24+
25+
template<length_t I, typename T, qualifier Q>
26+
GLM_CONSTEXPR T& get(qua<T, Q>& q) {
27+
GLM_STATIC_ASSERT(I < 4, "Index out of bounds");
28+
return q[I];
29+
}
30+
template<length_t I, typename T, qualifier Q>
31+
GLM_CONSTEXPR T const& get(qua<T, Q> const& q) {
32+
GLM_STATIC_ASSERT(I < 4, "Index out of bounds");
33+
return q[I];
34+
}
35+
36+
#if GLM_HAS_RVALUE_REFERENCES
37+
template<length_t I, length_t L, typename T, qualifier Q>
38+
GLM_CONSTEXPR T get(vec<L, T, Q> const&& v)
39+
{
40+
GLM_STATIC_ASSERT(I < L, "Index out of bounds");
41+
return v[I];
42+
}
43+
template<length_t I, length_t C, length_t R, typename T, qualifier Q>
44+
GLM_CONSTEXPR vec<R, T, Q> get(mat<C, R, T, Q> const&& m) {
45+
GLM_STATIC_ASSERT(I < C, "Index out of bounds");
46+
return m[I];
47+
}
48+
template<length_t I, typename T, qualifier Q>
49+
GLM_CONSTEXPR T get(qua<T, Q> const&& q) {
50+
GLM_STATIC_ASSERT(I < 4, "Index out of bounds");
51+
return q[I];
52+
}
53+
#endif
54+
}//namespace glm
55+

test/gtx/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ glmCreateTestGTC(gtx_scalar_multiplication)
5050
glmCreateTestGTC(gtx_scalar_relational)
5151
glmCreateTestGTC(gtx_spline)
5252
glmCreateTestGTC(gtx_string_cast)
53+
glmCreateTestGTC(gtx_structured_bindings)
5354
glmCreateTestGTC(gtx_texture)
5455
glmCreateTestGTC(gtx_type_aligned)
5556
glmCreateTestGTC(gtx_type_trait)

0 commit comments

Comments
 (0)