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 @@
59 
61 // C++ Version
62 
-
63 // User defines: GLM_FORCE_CXX98, GLM_FORCE_CXX03, GLM_FORCE_CXX11, GLM_FORCE_CXX14, GLM_FORCE_CXX17, GLM_FORCE_CXX2A
+
63 // User defines: GLM_FORCE_CXX98, GLM_FORCE_CXX03, GLM_FORCE_CXX11, GLM_FORCE_CXX14, GLM_FORCE_CXX17, GLM_FORCE_CXX2A, GLM_FORCE_CXX23
64 
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)
74 
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
84 
@@ -159,6 +161,9 @@
92 
93 #if (defined(GLM_FORCE_CXX_UNKNOWN))
94 # define GLM_LANG 0
+
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
126 # endif
127 
-
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))
970 
971  // Report C++ language
-
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; +}