diff --git a/CMakeLists.txt b/CMakeLists.txt
index 44b74714e3..b05bb87704 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,10 +32,23 @@ option(GLM_ENABLE_CXX_11 "Enable C++ 11" OFF)
option(GLM_ENABLE_CXX_14 "Enable C++ 14" OFF)
option(GLM_ENABLE_CXX_17 "Enable C++ 17" OFF)
option(GLM_ENABLE_CXX_20 "Enable C++ 20" OFF)
+option(GLM_ENABLE_CXX_23 "Enable C++ 23" OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
-if(GLM_ENABLE_CXX_20)
+if(GLM_ENABLE_CXX_23)
+ set(CMAKE_CXX_STANDARD 23)
+ add_definitions(-DGLM_FORCE_CXX23)
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ message(STATUS "GLM: Disable -Wc++98-compat warnings")
+ add_compile_options(-Wno-c++98-compat)
+ add_compile_options(-Wno-c++98-compat-pedantic)
+ endif()
+ if(NOT GLM_QUIET)
+ message(STATUS "GLM: Build with C++23 features")
+ endif()
+
+elseif(GLM_ENABLE_CXX_20)
set(CMAKE_CXX_STANDARD 20)
add_definitions(-DGLM_FORCE_CXX20)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/doc/api/a00032_source.html b/doc/api/a00032_source.html
index b4b0df53ed..ce6848bfa0 100644
--- a/doc/api/a00032_source.html
+++ b/doc/api/a00032_source.html
@@ -127,7 +127,7 @@
-
+
65 #define GLM_LANG_CXX98_FLAG (1 << 1)
66 #define GLM_LANG_CXX03_FLAG (1 << 2)
@@ -138,6 +138,7 @@
71 #define GLM_LANG_CXX20_FLAG (1 << 7)
72 #define GLM_LANG_CXXMS_FLAG (1 << 8)
73 #define GLM_LANG_CXXGNU_FLAG (1 << 9)
+ 71 #define GLM_LANG_CXX23_FLAG (1 << 10)
75 #define GLM_LANG_CXX98 GLM_LANG_CXX98_FLAG
76 #define GLM_LANG_CXX03 (GLM_LANG_CXX98 | GLM_LANG_CXX03_FLAG)
@@ -146,6 +147,7 @@
79 #define GLM_LANG_CXX14 (GLM_LANG_CXX11 | GLM_LANG_CXX14_FLAG)
80 #define GLM_LANG_CXX17 (GLM_LANG_CXX14 | GLM_LANG_CXX17_FLAG)
81 #define GLM_LANG_CXX20 (GLM_LANG_CXX17 | GLM_LANG_CXX20_FLAG)
+ 81 #define GLM_LANG_CXX23 (GLM_LANG_CXX20 | GLM_LANG_CXX23_FLAG)
82 #define GLM_LANG_CXXMS GLM_LANG_CXXMS_FLAG
83 #define GLM_LANG_CXXGNU GLM_LANG_CXXGNU_FLAG
@@ -159,6 +161,9 @@
93 #if (defined(GLM_FORCE_CXX_UNKNOWN))
+ 95 #elif defined(GLM_FORCE_CXX23)
+ 96 # define GLM_LANG (GLM_LANG_CXX23 | GLM_LANG_EXT)
+ 97 # define GLM_LANG_STL11_FORCED
95 #elif defined(GLM_FORCE_CXX20)
96 # define GLM_LANG (GLM_LANG_CXX20 | GLM_LANG_EXT)
97 # define GLM_LANG_STL11_FORCED
@@ -192,7 +197,9 @@
125 # define GLM_LANG_PLATFORM 0
- 128 # if __cplusplus > 201703L || GLM_LANG_PLATFORM > 201703L
+ 128 # if __cplusplus > 202002L || GLM_LANG_PLATFORM > 202002L
+ 129 # define GLM_LANG (GLM_LANG_CXX23 | GLM_LANG_EXT)
+ 128 # elif __cplusplus > 201703L || GLM_LANG_PLATFORM > 201703L
129 # define GLM_LANG (GLM_LANG_CXX20 | GLM_LANG_EXT)
130 # elif __cplusplus == 201703L || GLM_LANG_PLATFORM == 201703L
131 # define GLM_LANG (GLM_LANG_CXX17 | GLM_LANG_EXT)
@@ -1010,7 +1017,11 @@
969 # pragma message (GLM_STR(GLM_VERSION_MESSAGE))
- 972 # if (GLM_LANG & GLM_LANG_CXX20_FLAG) && (GLM_LANG & GLM_LANG_EXT)
+ 972 # if (GLM_LANG & GLM_LANG_CXX23_FLAG) && (GLM_LANG & GLM_LANG_EXT)
+ 973 # pragma message("GLM: C++ 23 with extensions")
+ 974 # elif (GLM_LANG & GLM_LANG_CXX23_FLAG)
+ 975 # pragma message("GLM: C++ 2B")
+ 972 # elif (GLM_LANG & GLM_LANG_CXX20_FLAG) && (GLM_LANG & GLM_LANG_EXT)
973 # pragma message("GLM: C++ 20 with extensions")
974 # elif (GLM_LANG & GLM_LANG_CXX20_FLAG)
975 # pragma message("GLM: C++ 2A")
diff --git a/glm/detail/setup.hpp b/glm/detail/setup.hpp
index 9596122b9e..0910e7a85a 100644
--- a/glm/detail/setup.hpp
+++ b/glm/detail/setup.hpp
@@ -70,6 +70,7 @@
#define GLM_LANG_CXX20_FLAG (1 << 7)
#define GLM_LANG_CXXMS_FLAG (1 << 8)
#define GLM_LANG_CXXGNU_FLAG (1 << 9)
+#define GLM_LANG_CXX23_FLAG (1 << 10)
#define GLM_LANG_CXX98 GLM_LANG_CXX98_FLAG
#define GLM_LANG_CXX03 (GLM_LANG_CXX98 | GLM_LANG_CXX03_FLAG)
@@ -78,6 +79,7 @@
#define GLM_LANG_CXX14 (GLM_LANG_CXX11 | GLM_LANG_CXX14_FLAG)
#define GLM_LANG_CXX17 (GLM_LANG_CXX14 | GLM_LANG_CXX17_FLAG)
#define GLM_LANG_CXX20 (GLM_LANG_CXX17 | GLM_LANG_CXX20_FLAG)
+#define GLM_LANG_CXX23 (GLM_LANG_CXX20 | GLM_LANG_CXX23_FLAG)
#define GLM_LANG_CXXMS GLM_LANG_CXXMS_FLAG
#define GLM_LANG_CXXGNU GLM_LANG_CXXGNU_FLAG
@@ -91,6 +93,9 @@
#if (defined(GLM_FORCE_CXX_UNKNOWN))
# define GLM_LANG 0
+#elif defined(GLM_FORCE_CXX23)
+# define GLM_LANG (GLM_LANG_CXX23 | GLM_LANG_EXT)
+# define GLM_LANG_STL11_FORCED
#elif defined(GLM_FORCE_CXX20)
# define GLM_LANG (GLM_LANG_CXX20 | GLM_LANG_EXT)
# define GLM_LANG_STL11_FORCED
@@ -124,7 +129,9 @@
# define GLM_LANG_PLATFORM 0
# endif
-# if __cplusplus > 201703L || GLM_LANG_PLATFORM > 201703L
+# if __cplusplus > 202002L || GLM_LANG_PLATFORM > 202002L
+# define GLM_LANG (GLM_LANG_CXX23 | GLM_LANG_EXT)
+# elif __cplusplus > 201703L || GLM_LANG_PLATFORM > 201703L
# define GLM_LANG (GLM_LANG_CXX20 | GLM_LANG_EXT)
# elif __cplusplus == 201703L || GLM_LANG_PLATFORM == 201703L
# define GLM_LANG (GLM_LANG_CXX17 | GLM_LANG_EXT)
@@ -980,7 +987,11 @@ namespace detail
# pragma message ("GLM: version " GLM_STR(GLM_VERSION_MAJOR) "." GLM_STR(GLM_VERSION_MINOR) "." GLM_STR(GLM_VERSION_PATCH))
// Report C++ language
-# if (GLM_LANG & GLM_LANG_CXX20_FLAG) && (GLM_LANG & GLM_LANG_EXT)
+# if (GLM_LANG & GLM_LANG_CXX23_FLAG) && (GLM_LANG & GLM_LANG_EXT)
+# pragma message("GLM: C++ 23 with extensions")
+# elif (GLM_LANG & GLM_LANG_CXX23_FLAG)
+# pragma message("GLM: C++ 2B")
+# elif (GLM_LANG & GLM_LANG_CXX20_FLAG) && (GLM_LANG & GLM_LANG_EXT)
# pragma message("GLM: C++ 20 with extensions")
# elif (GLM_LANG & GLM_LANG_CXX20_FLAG)
# pragma message("GLM: C++ 2A")
diff --git a/glm/ext.hpp b/glm/ext.hpp
index f9ac3699d8..e07eacfe8b 100644
--- a/glm/ext.hpp
+++ b/glm/ext.hpp
@@ -245,6 +245,7 @@
#include "./gtx/raw_data.hpp"
#include "./gtx/rotate_normalized_axis.hpp"
#include "./gtx/rotate_vector.hpp"
+#include "./gtx/span.hpp"
#include "./gtx/spline.hpp"
#include "./gtx/std_based_type.hpp"
#if !((GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP))
diff --git a/glm/gtx/range.hpp b/glm/gtx/range.hpp
index 50c5e57be6..e9188ca6fa 100644
--- a/glm/gtx/range.hpp
+++ b/glm/gtx/range.hpp
@@ -22,75 +22,53 @@
#endif
#include "../gtc/type_ptr.hpp"
-#include "../gtc/vec1.hpp"
+#include
+#include "type_trait.hpp"
namespace glm
{
/// @addtogroup gtx_range
/// @{
-# if GLM_COMPILER & GLM_COMPILER_VC
-# pragma warning(push)
-# pragma warning(disable : 4100) // unreferenced formal parameter
-# endif
-
- template
- inline length_t components(vec<1, T, Q> const& v)
- {
- return v.length();
- }
-
- template
- inline length_t components(vec<2, T, Q> const& v)
- {
- return v.length();
- }
-
- template
- inline length_t components(vec<3, T, Q> const& v)
- {
- return v.length();
- }
-
- template
- inline length_t components(vec<4, T, Q> const& v)
- {
- return v.length();
- }
+#if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(push)
+# pragma warning(disable : 4100) // unreferenced formal parameter
+#endif
+ /// @warning This is not same as `type::components`, calling this returns total elements (for mat4 returns 16 instead of 4).
template
- inline length_t components(genType const& m)
+ /*GLM_DEPRECATED*/ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR length_t components(genType const& v)
{
- return m.length() * m[0].length();
+ return type::elements;
}
+#if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(pop)
+#endif
+
template
- inline typename genType::value_type const * begin(genType const& v)
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename genType::value_type const * begin(genType const& v)
{
return value_ptr(v);
}
template
- inline typename genType::value_type const * end(genType const& v)
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename genType::value_type const * end(genType const& v)
{
- return begin(v) + components(v);
+ return begin(v) + type::elements;
}
template
- inline typename genType::value_type * begin(genType& v)
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename genType::value_type * begin(genType& v)
{
return value_ptr(v);
}
template
- inline typename genType::value_type * end(genType& v)
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename genType::value_type * end(genType& v)
{
- return begin(v) + components(v);
+ return begin(v) + type::elements;
}
-# if GLM_COMPILER & GLM_COMPILER_VC
-# pragma warning(pop)
-# endif
-
/// @}
}//namespace glm
diff --git a/glm/gtx/span.hpp b/glm/gtx/span.hpp
new file mode 100644
index 0000000000..39f614c7f7
--- /dev/null
+++ b/glm/gtx/span.hpp
@@ -0,0 +1,144 @@
+/// @ref gtx_span
+/// @file glm/gtx/span.hpp
+/// @author Abit Gray
+///
+/// @defgroup gtx_span GLM_GTX_span
+/// @ingroup gtx
+///
+/// Include to use the features of this extension.
+///
+/// Defines functions to convert glm types to std::valarray or view them using C++20 std::span and C++23 std::mdspan.
+
+#pragma once
+
+// Dependencies
+#include "../detail/setup.hpp"
+
+#ifndef GLM_ENABLE_EXPERIMENTAL
+# error "GLM: GLM_GTX_span 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."
+#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
+# pragma message("GLM: GLM_GTX_span extension included")
+#endif
+
+// `std::enable_if` support (and few more)
+// Required for all functions below
+#if !(GLM_LANG & GLM_LANG_CXX11_FLAG)
+# error "GLM_GTX_span requiers at least C++11, using C++20 or C++23 is recommended for full functionality"
+#endif
+
+// GLM_MESSAGES info
+#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
+# if (GLM_LANG & GLM_LANG_CXX20_FLAG) && defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
+# pragma message("GLM: GLM_GTX_span extension will include std::span")
+# endif
+# if (GLM_LANG & GLM_LANG_CXX23_FLAG) && defined(__cpp_lib_mdspan) && __cpp_lib_mdspan >= 202207L
+# pragma message("GLM: GLM_GTX_span extension will include std::mdspan")
+# endif
+#endif
+
+#include "../gtc/type_ptr.hpp"
+#include "type_trait.hpp"
+
+#include
+
+// Version-specific includes
+#if GLM_LANG & GLM_LANG_CXX20_FLAG
+// Feature testing
+# include
+
+// C++20 std::span
+# if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
+# include
+# endif
+
+// C++23 std::mdspan
+# if (GLM_LANG & GLM_LANG_CXX23) && defined(__cpp_lib_mdspan) && __cpp_lib_mdspan >= 202207L
+# include
+# endif
+#endif
+
+namespace glm
+{
+ /// @addtogroup gtx_span
+ /// @{
+
+# if (GLM_LANG & GLM_LANG_CXX20_FLAG)
+ template
+ requires (type>::elements > 0)
+# else
+ template::type
+ >::type
+ >::elements > 0
+ )>::type>
+# endif
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::valarray valarray(T const& v)
+ {
+ return std::valarray(value_ptr(v), type::elements);
+ }
+
+#if (GLM_LANG & GLM_LANG_CXX20_FLAG) && defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
+
+ template
+ requires (type>::elements > 0)
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::span span(T & v)
+ {
+ using TN = std::remove_cvref_t;
+ return std::span(value_ptr(v), type::elements);
+ }
+
+ template
+ requires (type>::elements > 0)
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::span span(T const& v)
+ {
+ using TN = std::remove_cvref_t;
+ return std::span(value_ptr(v), type::elements);
+ }
+
+#endif
+
+#if (GLM_LANG & GLM_LANG_CXX23_FLAG) && defined(__cpp_lib_mdspan) && __cpp_lib_mdspan >= 202207L
+
+ template
+ requires (type>::rows == 1)
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::mdspan span(T & v)
+ {
+ using TN = std::remove_cvref_t;
+ static_assert(type::cols >= 1);
+ return std::mdspan(value_ptr(v), type::cols);
+ }
+
+ template
+ requires (type>::rows == 1)
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::mdspan span(T const& v)
+ {
+ using TN = std::remove_cvref_t;
+ static_assert(type::cols >= 1);
+ return std::mdspan(value_ptr(v), type::cols);
+ }
+
+ template
+ requires (type>::rows > 1)
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR auto mdspan(T & m)
+ {
+ using TN = std::remove_cvref_t;
+ static_assert(type::cols >= 1);
+ return std::mdspan(value_ptr(m), type::cols, type::rows);
+ }
+
+ template
+ requires (type>::rows > 1)
+ GLM_NODISCARD GLM_FUNC_QUALIFIER GLM_CONSTEXPR auto mdspan(T const& m)
+ {
+ using TN = std::remove_cvref_t;
+ static_assert(type::cols >= 1);
+ return std::mdspan(value_ptr(m), type::cols, type::rows);
+ }
+
+#endif
+
+ /// @}
+}//namespace glm
diff --git a/glm/gtx/type_trait.hpp b/glm/gtx/type_trait.hpp
index 17ddbad1b8..1dc818261d 100644
--- a/glm/gtx/type_trait.hpp
+++ b/glm/gtx/type_trait.hpp
@@ -31,12 +31,20 @@ namespace glm
template
struct type
{
+#if GLM_LANG & GLM_LANG_CXX11_FLAG
+ // with C++20, you can use std::remove_cvref for all of those
+ // with C++11, you can use std::remove_cv for the first two
+ static_assert(!std::is_const::value); // use std::remove_const
+ static_assert(!std::is_volatile::value); // use std::remove_volatile
+ static_assert(!std::is_reference::value); // use std::remove_reference
+#endif
static bool const is_vec = false;
static bool const is_mat = false;
static bool const is_quat = false;
static length_t const components = 0;
static length_t const cols = 0;
static length_t const rows = 0;
+ static length_t const elements = cols * rows;
};
template
@@ -46,6 +54,9 @@ namespace glm
static bool const is_mat = false;
static bool const is_quat = false;
static length_t const components = L;
+ static length_t const cols = L;
+ static length_t const rows = 1;
+ static length_t const elements = cols * rows;
};
template
@@ -57,6 +68,7 @@ namespace glm
static length_t const components = C;
static length_t const cols = C;
static length_t const rows = R;
+ static length_t const elements = cols * rows;
};
template
@@ -66,6 +78,9 @@ namespace glm
static bool const is_mat = false;
static bool const is_quat = true;
static length_t const components = 4;
+ static length_t const cols = components;
+ static length_t const rows = 1;
+ static length_t const elements = cols * rows;
};
template
@@ -75,6 +90,9 @@ namespace glm
static bool const is_mat = false;
static bool const is_quat = true;
static length_t const components = 8;
+ static length_t const cols = components;
+ static length_t const rows = 1;
+ static length_t const elements = cols * rows;
};
/// @}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index c250a780ea..901e4bedde 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -5,7 +5,7 @@ option(GLM_PERF_TEST_ENABLE "Build perf tests" OFF)
if(GLM_PERF_TEST_ENABLE)
add_definitions(-DGLM_TEST_PERF)
- endif()
+endif()
if (GLM_TEST_ENABLE_SIMD_FMA)
add_definitions(-DGLM_FORCE_FMA)
@@ -78,6 +78,43 @@ function(glmCreateTestGTC NAME)
NAME ${SAMPLE_NAME}
COMMAND $ )
target_link_libraries(${SAMPLE_NAME} PRIVATE glm::glm)
+
+ # Add labels for summary
+ if(NAME MATCHES "^bug_")
+ set_tests_properties(
+ ${SAMPLE_NAME}
+ PROPERTIES
+ LABELS "bug"
+ )
+ endif()
+ if(NAME MATCHES "^core_")
+ set_tests_properties(
+ ${SAMPLE_NAME}
+ PROPERTIES
+ LABELS "core"
+ )
+ endif()
+ if(NAME MATCHES "^ext_")
+ set_tests_properties(
+ ${SAMPLE_NAME}
+ PROPERTIES
+ LABELS "ext"
+ )
+ endif()
+ if(NAME MATCHES "^gtc_")
+ set_tests_properties(
+ ${SAMPLE_NAME}
+ PROPERTIES
+ LABELS "gtc"
+ )
+ endif()
+ if((NAME MATCHES "^gtx_") OR (NAME STREQUAL "gtx"))
+ set_tests_properties(
+ ${SAMPLE_NAME}
+ PROPERTIES
+ LABELS "gtx"
+ )
+ endif()
endfunction()
if(GLM_TEST_ENABLE)
diff --git a/test/core/core_setup_force_cxx03.cpp b/test/core/core_setup_force_cxx03.cpp
index ac8c04c084..7ddd3baf70 100644
--- a/test/core/core_setup_force_cxx03.cpp
+++ b/test/core/core_setup_force_cxx03.cpp
@@ -1,6 +1,9 @@
#ifdef GLM_FORCE_CXX_UNKNOWN
#undef GLM_FORCE_CXX_UNKNOWN
#endif
+#ifdef GLM_FORCE_CXX23
+#undef GLM_FORCE_CXX23
+#endif
#ifdef GLM_FORCE_CXX20
#undef GLM_FORCE_CXX20
#endif
diff --git a/test/gtx/CMakeLists.txt b/test/gtx/CMakeLists.txt
index b7686673cb..673605b3a5 100644
--- a/test/gtx/CMakeLists.txt
+++ b/test/gtx/CMakeLists.txt
@@ -48,6 +48,7 @@ glmCreateTestGTC(gtx_rotate_normalized_axis)
glmCreateTestGTC(gtx_rotate_vector)
glmCreateTestGTC(gtx_scalar_multiplication)
glmCreateTestGTC(gtx_scalar_relational)
+glmCreateTestGTC(gtx_span)
glmCreateTestGTC(gtx_spline)
glmCreateTestGTC(gtx_string_cast)
glmCreateTestGTC(gtx_structured_bindings)
diff --git a/test/gtx/gtx_range.cpp b/test/gtx/gtx_range.cpp
index 03523e90d4..a59c605b60 100644
--- a/test/gtx/gtx_range.cpp
+++ b/test/gtx/gtx_range.cpp
@@ -1,3 +1,4 @@
+#include
#include
#include
#include
@@ -5,10 +6,61 @@
#if GLM_HAS_RANGE_FOR
+#include
+#include
+
#define GLM_ENABLE_EXPERIMENTAL
#include
+#include
-static int test_vec()
+static int test_vec2()
+{
+ int Error = 0;
+
+ {
+ glm::ivec2 const v(1, 2);
+
+ int count = 0;
+ glm::ivec2 Result(0);
+ for(int x : v)
+ {
+ Result[count] = x;
+ count++;
+ }
+ Error += count == 2 ? 0 : 1;
+ Error += v == Result ? 0 : 1;
+ }
+
+ {
+ glm::ivec2 v(1, 2);
+ for(int& x : v)
+ x = 0;
+ Error += glm::all(glm::equal(v, glm::ivec2(0))) ? 0 : 1;
+ }
+
+ {
+ glm::ivec2 const v(1, 2);
+ if(std::accumulate(begin(v), end(v), 0) != 3) // Sum all elements
+ Error += 1;
+ if(std::distance(begin(v), end(v)) != 2) // Count number of elements
+ Error += 1;
+ }
+#if GLM_LANG & GLM_LANG_CXX20_FLAG
+ {
+ glm::ivec2 const v(1, 2);
+# ifdef __cpp_lib_ranges_fold
+ if(std::ranges::fold_left(v, 0, std::plus<>()) != 3) // Sum all elements
+ Error += 1;
+# endif
+ if(std::ranges::distance(begin(v), end(v)) != 2) // Count number of elements
+ Error += 1;
+ }
+#endif
+
+ return Error;
+}
+
+static int test_vec3()
{
int Error = 0;
@@ -33,10 +85,123 @@ static int test_vec()
Error += glm::all(glm::equal(v, glm::ivec3(0))) ? 0 : 1;
}
+ {
+ glm::ivec3 const v(1, 2, 3);
+ if(std::accumulate(begin(v), end(v), 0) != 6) // Sum all elements
+ Error += 1;
+ if(std::distance(begin(v), end(v)) != 3) // Count number of elements
+ Error += 1;
+ }
+#if GLM_LANG & GLM_LANG_CXX20_FLAG
+ {
+ glm::ivec3 const v(1, 2, 3);
+# ifdef __cpp_lib_ranges_fold
+ if(std::ranges::fold_left(v, 0, std::plus<>()) != 6) // Sum all elements
+ Error += 1;
+# endif
+ if(std::ranges::distance(begin(v), end(v)) != 3) // Count number of elements
+ Error += 1;
+ }
+#endif
+
+ return Error;
+}
+
+static int test_vec4()
+{
+ int Error = 0;
+
+ {
+ glm::ivec4 const v(1, 2, 3, 4);
+
+ int count = 0;
+ glm::ivec4 Result(0);
+ for(int x : v)
+ {
+ Result[count] = x;
+ count++;
+ }
+ Error += count == 4 ? 0 : 1;
+ Error += v == Result ? 0 : 1;
+ }
+
+ {
+ glm::ivec4 v(1, 2, 3, 4);
+ for(int& x : v)
+ x = 0;
+ Error += glm::all(glm::equal(v, glm::ivec4(0))) ? 0 : 1;
+ }
+
+ {
+ glm::ivec4 const v(1, 2, 3, 4);
+ if(std::accumulate(begin(v), end(v), 0) != 10) // Sum all elements
+ Error += 1;
+ if(std::distance(begin(v), end(v)) != 4) // Count number of elements
+ Error += 1;
+ }
+#if GLM_LANG & GLM_LANG_CXX20_FLAG
+ {
+ glm::ivec4 const v(1, 2, 3, 4);
+# ifdef __cpp_lib_ranges_fold
+ if(std::ranges::fold_left(v, 0, std::plus<>()) != 10) // Sum all elements
+ Error += 1;
+# endif
+ if(std::ranges::distance(begin(v), end(v)) != 4) // Count number of elements
+ Error += 1;
+ }
+#endif
+
return Error;
}
-static int test_mat()
+static int test_quat()
+{
+ int Error = 0;
+
+ {
+ glm::quat const q(1, 2, 3, 4);
+
+ int count = 0;
+ glm::quat Result(0, 0, 0, 0);
+ for(float x : q)
+ {
+ Result[count] = x;
+ count++;
+ }
+ Error += count == 4 ? 0 : 1;
+ Error += q == Result ? 0 : 1;
+ }
+
+ {
+ glm::quat q(1, 2, 3, 4);
+ for(float& x : q)
+ x = 0;
+ Error += glm::all(glm::equal(q, glm::quat(0, 0, 0, 0))) ? 0 : 1;
+ }
+
+ {
+ glm::quat const q(1, 2, 3, 4);
+ if(std::accumulate(begin(q), end(q), 0.0f) != 10.0f) // Sum all elements
+ Error += 1;
+ if(std::distance(begin(q), end(q)) != 4) // Count number of elements
+ Error += 1;
+ }
+#if GLM_LANG & GLM_LANG_CXX20_FLAG
+ {
+ glm::quat const q(1, 2, 3, 4);
+# ifdef __cpp_lib_ranges_fold
+ if(std::ranges::fold_left(q, 0.0f, std::plus<>()) != 10.0f) // Sum all elements
+ Error += 1;
+# endif
+ if(std::ranges::distance(begin(q), end(q)) != 4) // Count number of elements
+ Error += 1;
+ }
+#endif
+
+ return Error;
+}
+
+static int test_mat4x3()
{
int Error = 0;
@@ -57,19 +222,98 @@ static int test_mat()
{
glm::mat4x3 m(1.0f);
- for (float& x : m) { x = 0; }
+ for(float& x : m)
+ {
+ x = 0;
+ }
glm::vec4 v(1, 1, 1, 1);
Error += glm::all(glm::equal(m*v, glm::vec3(0, 0, 0), glm::epsilon())) ? 0 : 1;
}
+ // Sum all using std::accumulate
+ {
+ glm::mat4x3 const m(1.0f);
+ if(std::accumulate(begin(m), end(m), 0.0f) != 3.0f) // Sum all elements
+ Error += 1;
+ if(std::distance(begin(m), end(m)) != 12) // Count number of elements
+ Error += 1;
+ }
+#if GLM_LANG & GLM_LANG_CXX20_FLAG
+ // Sum all using ranges
+ {
+ glm::mat4x3 const m(1.0f);
+# ifdef __cpp_lib_ranges_fold
+ if(std::ranges::fold_left(m, 0.0f, std::plus<>()) != 3.0f) // Sum all elements
+ Error += 1;
+# endif
+ if(std::ranges::distance(begin(m), end(m)) != 12) // Count number of elements
+ Error += 1;
+ }
+#endif
+
+ return Error;
+}
+
+static int test_mat4()
+{
+ int Error = 0;
+
+ {
+ glm::mat4 m(1.0f);
+
+ int count = 0;
+ float Sum = 0.0f;
+ for(float x : m)
+ {
+ count++;
+ Sum += x;
+ }
+ Error += count == 16 ? 0 : 1;
+ Error += glm::equal(Sum, 4.0f, 0.001f) ? 0 : 1;
+ }
+
+ {
+ glm::mat4 m(1.0f);
+
+ for(float& x : m)
+ {
+ x = 0;
+ }
+ glm::vec4 v(1, 1, 1, 1);
+ Error += glm::all(glm::equal(m*v, glm::vec4(0, 0, 0, 0), glm::epsilon())) ? 0 : 1;
+ }
+
+ {
+ glm::mat4 const m(1.0f);
+ if(std::accumulate(begin(m), end(m), 0.0f) != 4.0f) // Sum all elements
+ Error += 1;
+ if(std::distance(begin(m), end(m)) != 16) // Count number of elements
+ Error += 1;
+ }
+#if GLM_LANG & GLM_LANG_CXX20_FLAG
+ {
+ glm::mat4 const m(1.0f);
+# ifdef __cpp_lib_ranges_fold
+ if(std::ranges::fold_left(m, 0, std::plus<>()) != 4.0f) // Sum all elements
+ Error += 1;
+# endif
+ if(std::ranges::distance(begin(m), end(m)) != 16) // Count number of elements
+ Error += 1;
+ }
+#endif
+
return Error;
}
int main()
{
int Error = 0;
- Error += test_vec();
- Error += test_mat();
+ Error += test_vec2();
+ Error += test_vec3();
+ Error += test_vec4();
+ Error += test_quat();
+ Error += test_mat4x3();
+ Error += test_mat4();
return Error;
}
diff --git a/test/gtx/gtx_span.cpp b/test/gtx/gtx_span.cpp
new file mode 100644
index 0000000000..4ef0dbc9ae
--- /dev/null
+++ b/test/gtx/gtx_span.cpp
@@ -0,0 +1,167 @@
+#include
+#include
+#include
+#include
+
+#if (GLM_LANG & GLM_LANG_CXX20_FLAG) && defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
+
+#define GLM_ENABLE_EXPERIMENTAL
+#include
+
+static int test_span_vec2()
+{
+ int Error = 0;
+
+ {
+ glm::ivec2 const v(1, 2);
+
+ int count = 0;
+ glm::ivec2 Result(0);
+ for(int x : glm::span(v))
+ {
+ Result[count] = x;
+ count++;
+ }
+ Error += count == 2 ? 0 : 1;
+ Error += v == Result ? 0 : 1;
+ }
+
+ {
+ glm::ivec2 v(1, 2);
+ for(int& x : glm::span(v))
+ x = 0;
+ Error += glm::all(glm::equal(v, glm::ivec2(0))) ? 0 : 1;
+ }
+
+ return Error;
+}
+
+static int test_span_vec3()
+{
+ int Error = 0;
+
+ {
+ glm::ivec3 const v(1, 2, 3);
+
+ int count = 0;
+ glm::ivec3 Result(0);
+ for(int x : glm::span(v))
+ {
+ Result[count] = x;
+ count++;
+ }
+ Error += count == 3 ? 0 : 1;
+ Error += v == Result ? 0 : 1;
+ }
+
+ {
+ glm::ivec3 v(1, 2, 3);
+ for(int& x : glm::span(v))
+ x = 0;
+ Error += glm::all(glm::equal(v, glm::ivec3(0))) ? 0 : 1;
+ }
+
+ return Error;
+}
+
+static int test_span_vec4()
+{
+ int Error = 0;
+
+ {
+ glm::ivec4 const v(1, 2, 3, 4);
+
+ int count = 0;
+ glm::ivec4 Result(0);
+ for(int x : glm::span(v))
+ {
+ Result[count] = x;
+ count++;
+ }
+ Error += count == 4 ? 0 : 1;
+ Error += v == Result ? 0 : 1;
+ }
+
+ {
+ glm::ivec4 v(1, 2, 3, 4);
+ for(int& x : glm::span(v))
+ x = 0;
+ Error += glm::all(glm::equal(v, glm::ivec4(0))) ? 0 : 1;
+ }
+
+ return Error;
+}
+
+static int test_span_quat()
+{
+ int Error = 0;
+
+ {
+ glm::quat const q(1, 2, 3, 4);
+
+ int count = 0;
+ glm::quat Result(0, 0, 0, 0);
+ for(float x : glm::span(q))
+ {
+ Result[count] = x;
+ count++;
+ }
+ Error += count == 4 ? 0 : 1;
+ Error += q == Result ? 0 : 1;
+ }
+
+ {
+ glm::quat q(1, 2, 3, 4);
+ for(float& x : glm::span(q))
+ x = 0;
+ Error += glm::all(glm::equal(q, glm::quat(0, 0, 0, 0))) ? 0 : 1;
+ }
+
+ return Error;
+}
+
+static int test_span_mat()
+{
+ int Error = 0;
+
+ {
+ glm::mat4x3 m(1.0f);
+
+ int count = 0;
+ float Sum = 0.0f;
+ for(float x : glm::span(m))
+ {
+ count++;
+ Sum += x;
+ }
+ Error += count == 12 ? 0 : 1;
+ Error += glm::equal(Sum, 3.0f, 0.001f) ? 0 : 1;
+ }
+
+ {
+ glm::mat4x3 m(1.0f);
+
+ for(float& x : glm::span(m))
+ x = 0;
+ glm::vec4 v(1, 1, 1, 1);
+ Error += glm::all(glm::equal(m*v, glm::vec3(0, 0, 0), glm::epsilon())) ? 0 : 1;
+ }
+
+ return Error;
+}
+#endif
+
+int main()
+{
+ int Error = 0;
+ //TODO std::valarray
+#if (GLM_LANG & GLM_LANG_CXX20_FLAG) && defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
+ Error += test_span_vec2();
+ Error += test_span_vec3();
+ Error += test_span_vec4();
+ Error += test_span_quat();
+ Error += test_span_mat();
+#endif
+ //TODO std::mdspan
+ return Error;
+}