2020# pragma message("GLM: GLM_GTX_span extension included")
2121#endif
2222
23- #if !(GLM_LANG & GLM_LANG_CXX11)
24- // This requirement is due to `std::enable_if`
23+ // `std::enable_if` support (and few more)
24+ // Required for all functions below
25+ #if !(GLM_LANG & GLM_LANG_CXX11_FLAG)
2526# error "GLM_GTX_span requiers at least C++11, using C++20 or C++23 is recommended for full functionality"
2627#endif
2728
29+ // GLM_MESSAGES info
2830#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
29- # if (GLM_LANG & GLM_LANG_CXX20 ) && defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
31+ # if (GLM_LANG & GLM_LANG_CXX20_FLAG ) && defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
3032# pragma message("GLM: GLM_GTX_span extension will include std::span")
3133# endif
32- # if (GLM_LANG & GLM_LANG_CXX23 ) && defined(__cpp_lib_mdspan) && __cpp_lib_mdspan >= 202207L
34+ # if (GLM_LANG & GLM_LANG_CXX23_FLAG ) && defined(__cpp_lib_mdspan) && __cpp_lib_mdspan >= 202207L
3335# pragma message("GLM: GLM_GTX_span extension will include std::mdspan")
3436# endif
3537#endif
3638
37- #include " ../gtc/type_precision.hpp"
3839#include " ../gtc/type_ptr.hpp"
40+ #include " type_trait.hpp"
3941
4042#include < valarray>
41- #include < type_traits>
4243
43- #if GLM_LANG & GLM_LANG_CXX20
44+ // Version-specific includes
45+ #if GLM_LANG & GLM_LANG_CXX20_FLAG
4446// Feature testing
4547# include < version>
4648
@@ -60,141 +62,80 @@ namespace glm
6062 // / @addtogroup gtx_span
6163 // / @{
6264
65+ # if (GLM_LANG & GLM_LANG_CXX20_FLAG)
6366 template <typename T>
64- struct is_vec : std::false_type {};
65- template <length_t L, typename T, qualifier Q>
66- struct is_vec <vec<L, T, Q>> : std::true_type {};
67-
68- template <typename T>
69- struct is_quat : std::false_type {};
70- template <typename T, qualifier Q>
71- struct is_quat <qua<T, Q>> : std::true_type {};
72-
73- template <typename T>
74- struct is_mat : std::false_type {};
75- template <length_t L1, length_t L2, typename T, qualifier Q>
76- struct is_mat <mat<L1, L2, T, Q>> : std::true_type {};
77-
78- #if (GLM_LANG & GLM_LANG_CXX17)
79- template <typename T>
80- inline constexpr bool is_vec_v = is_vec<T>::value;
81- template <typename T>
82- inline constexpr bool is_quat_v = is_quat<T>::value;
83- template <typename T>
84- inline constexpr bool is_mat_v = is_mat<T>::value;
85- #endif
86-
87- #if (GLM_LANG & GLM_LANG_CXX20)
88- template <typename T>
89- requires is_vec<T>::value || is_quat<T>::value
90- #else
91- template <typename T, typename = typename std::enable_if<is_vec<T>::value || is_quat<T>::value>::type>
92- #endif
93- GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR length_t components ()
94- {
95- return T::length ();
96- }
97- #if (GLM_LANG & GLM_LANG_CXX20)
98- template <typename T>
99- requires is_mat<T>::value
100- #else
101- template <typename T, typename = typename std::enable_if<is_mat<T>::value>::type>
102- #endif
103- GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR length_t components ()
104- {
105- return T::length () * T::col_type::length ();
106- }
107- # if GLM_COMPILER & GLM_COMPILER_VC
108- # pragma warning(push)
109- # pragma warning(disable : 4100) // unreferenced formal parameter
110- # endif
111-
112- // / Utility function if you don't have the type and dont use `decltype` (it is from C++11 so this function won't exist for earlier anyway)
113- #if (GLM_LANG & GLM_LANG_CXX20)
114- template <typename T>
115- requires is_vec<T>::value || is_quat<T>::value
116- #else
117- template <typename T, typename = typename std::enable_if<is_vec<T>::value || is_quat<T>::value>::type>
118- #endif
119- GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR length_t components (T const &)
120- {
121- return components<T>();
122- }
123- # if GLM_COMPILER & GLM_COMPILER_VC
124- # pragma warning(pop)
67+ requires (type<std::remove_cvref_t <T>>::elements > 0 )
68+ # else
69+ template <typename T, typename = typename std::enable_if<
70+ (
71+ type<
72+ typename std::remove_reference<
73+ typename std::remove_cv<T>::type
74+ >::type
75+ >::elements > 0
76+ )>::type>
12577# endif
126-
127- #if (GLM_LANG & GLM_LANG_CXX20)
128- template <typename T>
129- requires is_vec<T>::value || is_quat<T>::value || is_mat<T>::value
130- #else
131- template <typename T, typename = typename std::enable_if<is_vec<T>::value || is_quat<T>::value || is_mat<T>::value>::type>
132- #endif
13378 GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::valarray<typename T::value_type> valarray (T const & v)
13479 {
135- return std::valarray<typename T::value_type>(value_ptr (v), components <T>() );
80+ return std::valarray<typename T::value_type>(value_ptr (v), type <T>::elements );
13681 }
13782
138- #if (GLM_LANG & GLM_LANG_CXX20 ) && defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
83+ #if (GLM_LANG & GLM_LANG_CXX20_FLAG ) && defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
13984
140- #if (GLM_LANG & GLM_LANG_CXX20)
14185 template <typename T>
142- requires is_vec<T>::value || is_quat<T>::value || is_mat<T>::value
143- #else
144- template <typename T, typename = typename std::enable_if<is_vec<T>::value || is_quat<T>::value || is_mat<T>::value>::type>
145- #endif
86+ requires (type<std::remove_cvref_t <T>>::elements > 0 )
14687 GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::span<typename T::value_type> span(T & v)
14788 {
148- return std::span<typename T::value_type>(value_ptr (v), components<T>());
89+ using TN = std::remove_cvref_t <T>;
90+ return std::span<typename T::value_type>(value_ptr (v), type<TN>::elements);
14991 }
15092
151- #if (GLM_LANG & GLM_LANG_CXX20)
15293 template <typename T>
153- requires is_vec<T>::value || is_quat<T>::value || is_mat<T>::value
154- #else
155- template <typename T, typename = typename std::enable_if<is_vec<T>::value || is_quat<T>::value || is_mat<T>::value>::type>
156- #endif
94+ requires (type<std::remove_cvref_t <T>>::elements > 0 )
15795 GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::span<const typename T::value_type> span(T const & v)
15896 {
159- return std::span<const typename T::value_type>(value_ptr (v), components<T>());
97+ using TN = std::remove_cvref_t <T>;
98+ return std::span<const typename T::value_type>(value_ptr (v), type<TN>::elements);
16099 }
161100
162101#endif
163102
164- #if (GLM_LANG & GLM_LANG_CXX23 ) && defined(__cpp_lib_mdspan) && __cpp_lib_mdspan >= 202207L
103+ #if (GLM_LANG & GLM_LANG_CXX23_FLAG ) && defined(__cpp_lib_mdspan) && __cpp_lib_mdspan >= 202207L
165104
166- #if (GLM_LANG & GLM_LANG_CXX20)
167105 template <typename T>
168- requires is_vec<T>::value || is_quat<T>::value
169- #else
170- template <typename T, typename = typename std::enable_if<is_vec<T>::value || is_quat<T>::value>::type>
171- #endif
106+ requires (type<std::remove_cvref_t <T>>::rows == 1 )
172107 GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::mdspan<typename T::value_type> span(T & v)
173108 {
174- return std::mdspan<typename T::value_type>(value_ptr (v), components<T>());
109+ using TN = std::remove_cvref_t <T>;
110+ static_assert (type<TN>::cols >= 1 );
111+ return std::mdspan<typename T::value_type>(value_ptr (v), type<TN>::cols);
175112 }
176113
177- #if (GLM_LANG & GLM_LANG_CXX20)
178114 template <typename T>
179- requires is_vec<T>::value || is_quat<T>::value
180- #else
181- template <typename T, typename = typename std::enable_if<is_vec<T>::value || is_quat<T>::value>::type>
182- #endif
115+ requires (type<std::remove_cvref_t <T>>::rows == 1 )
183116 GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::mdspan<const typename T::value_type> span(T const & v)
184117 {
185- return std::mdspan<const typename T::value_type>(value_ptr (v), components<T>());
118+ using TN = std::remove_cvref_t <T>;
119+ static_assert (type<TN>::cols >= 1 );
120+ return std::mdspan<const typename T::value_type>(value_ptr (v), type<TN>::cols);
186121 }
187122
188- template <length_t L1, length_t L2, typename T, qualifier Q>
189- GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR auto mdspan (mat<L1, L2, T, Q> & m)
123+ template <typename T>
124+ requires (type<std::remove_cvref_t <T>>::rows > 1 )
125+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR auto mdspan(T & m)
190126 {
191- return std::mdspan<T>(value_ptr (m), L1, L2);
127+ using TN = std::remove_cvref_t <T>;
128+ static_assert (type<TN>::cols >= 1 );
129+ return std::mdspan<typename T::value_type>(value_ptr (m), type<TN>::cols, type<TN>::rows);
192130 }
193131
194- template <length_t L1, length_t L2, typename T, qualifier Q>
195- GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR auto mdspan (mat<L1, L2, T, Q> const & m)
132+ template <typename T>
133+ requires (type<std::remove_cvref_t <T>>::rows > 1 )
134+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR auto mdspan(T const & m)
196135 {
197- return std::mdspan<const T>(value_ptr (m), L1, L2);
136+ using TN = std::remove_cvref_t <T>;
137+ static_assert (type<TN>::cols >= 1 );
138+ return std::mdspan<const typename T::value_type>(value_ptr (m), type<TN>::cols, type<TN>::rows);
198139 }
199140
200141#endif
0 commit comments