From 4255eb8d9e3946eb4abf7cc7fa3d10edaf03c568 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Sun, 7 Sep 2025 23:23:32 +0200 Subject: [PATCH 01/34] [linalg] Rename internal header concepts.hpp to exposition.hpp --- include/etl/_linalg/blas1_add.hpp | 2 +- include/etl/_linalg/blas1_copy.hpp | 2 +- include/etl/_linalg/blas1_matrix_frob_norm.hpp | 2 +- include/etl/_linalg/blas1_scale.hpp | 2 +- include/etl/_linalg/blas1_scaled.hpp | 2 +- include/etl/_linalg/blas1_swap_elements.hpp | 2 +- include/etl/_linalg/blas1_vector_abs_sum.hpp | 2 +- include/etl/_linalg/blas1_vector_idx_abs_max.hpp | 2 +- include/etl/_linalg/blas1_vector_two_norm.hpp | 2 +- include/etl/_linalg/blas2_matrix_vector_product.hpp | 2 +- include/etl/_linalg/conjugated.hpp | 2 +- include/etl/_linalg/conjugated_scalar.hpp | 2 +- include/etl/_linalg/{concepts.hpp => exposition.hpp} | 6 +++--- include/etl/_linalg/layout_transpose.hpp | 2 +- include/etl/_linalg/proxy_reference.hpp | 2 +- 15 files changed, 17 insertions(+), 17 deletions(-) rename include/etl/_linalg/{concepts.hpp => exposition.hpp} (98%) diff --git a/include/etl/_linalg/blas1_add.hpp b/include/etl/_linalg/blas1_add.hpp index 38ebee3e8..07c4e71c5 100644 --- a/include/etl/_linalg/blas1_add.hpp +++ b/include/etl/_linalg/blas1_add.hpp @@ -5,7 +5,7 @@ #define TETL_LINALG_BLAS1_ADD_HPP #include -#include +#include #include namespace etl::linalg { diff --git a/include/etl/_linalg/blas1_copy.hpp b/include/etl/_linalg/blas1_copy.hpp index ffad9eac0..022cc0dd3 100644 --- a/include/etl/_linalg/blas1_copy.hpp +++ b/include/etl/_linalg/blas1_copy.hpp @@ -5,7 +5,7 @@ #define TETL_LINALG_BLAS1_COPY_HPP #include -#include +#include #include namespace etl::linalg { diff --git a/include/etl/_linalg/blas1_matrix_frob_norm.hpp b/include/etl/_linalg/blas1_matrix_frob_norm.hpp index 4a92c0653..61912ca98 100644 --- a/include/etl/_linalg/blas1_matrix_frob_norm.hpp +++ b/include/etl/_linalg/blas1_matrix_frob_norm.hpp @@ -5,7 +5,7 @@ #define TETL_LINALG_BLAS1_MATRIX_FROB_NORM_HPP #include -#include +#include #include #include diff --git a/include/etl/_linalg/blas1_scale.hpp b/include/etl/_linalg/blas1_scale.hpp index 5dafca259..dd53abfbe 100644 --- a/include/etl/_linalg/blas1_scale.hpp +++ b/include/etl/_linalg/blas1_scale.hpp @@ -4,7 +4,7 @@ #ifndef TETL_LINALG_BLAS1_SCALE_HPP #define TETL_LINALG_BLAS1_SCALE_HPP -#include +#include #include namespace etl::linalg { diff --git a/include/etl/_linalg/blas1_scaled.hpp b/include/etl/_linalg/blas1_scaled.hpp index af0709cba..e42687e31 100644 --- a/include/etl/_linalg/blas1_scaled.hpp +++ b/include/etl/_linalg/blas1_scaled.hpp @@ -5,7 +5,7 @@ #define TETL_LINALG_BLAS1_SCALED_HPP #include -#include +#include namespace etl::linalg { diff --git a/include/etl/_linalg/blas1_swap_elements.hpp b/include/etl/_linalg/blas1_swap_elements.hpp index 07ebf10ae..25bc96e79 100644 --- a/include/etl/_linalg/blas1_swap_elements.hpp +++ b/include/etl/_linalg/blas1_swap_elements.hpp @@ -5,7 +5,7 @@ #define TETL_LINALG_BLAS1_SWAP_ELEMENTS_HPP #include -#include +#include #include #include diff --git a/include/etl/_linalg/blas1_vector_abs_sum.hpp b/include/etl/_linalg/blas1_vector_abs_sum.hpp index f10ca660d..11ba51a34 100644 --- a/include/etl/_linalg/blas1_vector_abs_sum.hpp +++ b/include/etl/_linalg/blas1_vector_abs_sum.hpp @@ -4,7 +4,7 @@ #ifndef TETL_LINALG_BLAS1_VECTOR_ABS_SUM #define TETL_LINALG_BLAS1_VECTOR_ABS_SUM -#include +#include #include #include diff --git a/include/etl/_linalg/blas1_vector_idx_abs_max.hpp b/include/etl/_linalg/blas1_vector_idx_abs_max.hpp index f2638d436..621227821 100644 --- a/include/etl/_linalg/blas1_vector_idx_abs_max.hpp +++ b/include/etl/_linalg/blas1_vector_idx_abs_max.hpp @@ -5,7 +5,7 @@ #define TETL_LINALG_BLAS1_VECTOR_IDX_ABS_MAX_HPP #include -#include +#include #include #include diff --git a/include/etl/_linalg/blas1_vector_two_norm.hpp b/include/etl/_linalg/blas1_vector_two_norm.hpp index 3c11db6a8..aad2a4ecf 100644 --- a/include/etl/_linalg/blas1_vector_two_norm.hpp +++ b/include/etl/_linalg/blas1_vector_two_norm.hpp @@ -5,7 +5,7 @@ #define TETL_LINALG_BLAS1_VECTOR_TWO_NORM_HPP #include -#include +#include #include #include diff --git a/include/etl/_linalg/blas2_matrix_vector_product.hpp b/include/etl/_linalg/blas2_matrix_vector_product.hpp index 2d9b338b0..979efcc0b 100644 --- a/include/etl/_linalg/blas2_matrix_vector_product.hpp +++ b/include/etl/_linalg/blas2_matrix_vector_product.hpp @@ -5,7 +5,7 @@ #define TETL_LINALG_BLAS2_MATRIX_VECTOR_PRODUCT_HPP #include -#include +#include #include namespace etl::linalg { diff --git a/include/etl/_linalg/conjugated.hpp b/include/etl/_linalg/conjugated.hpp index 4ac5c6b72..3a5f7ce72 100644 --- a/include/etl/_linalg/conjugated.hpp +++ b/include/etl/_linalg/conjugated.hpp @@ -5,7 +5,7 @@ #define TETL_LINALG_CONJUGATED_HPP #include -#include +#include #include #include diff --git a/include/etl/_linalg/conjugated_scalar.hpp b/include/etl/_linalg/conjugated_scalar.hpp index 076a255d1..913b8f6fc 100644 --- a/include/etl/_linalg/conjugated_scalar.hpp +++ b/include/etl/_linalg/conjugated_scalar.hpp @@ -5,7 +5,7 @@ #define TETL_LINALG_CONJUGATED_SCALAR_HPP #include -#include +#include #include #include diff --git a/include/etl/_linalg/concepts.hpp b/include/etl/_linalg/exposition.hpp similarity index 98% rename from include/etl/_linalg/concepts.hpp rename to include/etl/_linalg/exposition.hpp index 932c2d610..0068daaf6 100644 --- a/include/etl/_linalg/concepts.hpp +++ b/include/etl/_linalg/exposition.hpp @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BSL-1.0 // SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch -#ifndef TETL_LINALG_CONCEPTS_HPP -#define TETL_LINALG_CONCEPTS_HPP +#ifndef TETL_LINALG_EXPOSITION_HPP +#define TETL_LINALG_EXPOSITION_HPP #include #include @@ -182,4 +182,4 @@ concept inout_object = detail::is_mdspan::value } // namespace etl::linalg -#endif // TETL_LINALG_CONCEPTS_HPP +#endif // TETL_LINALG_EXPOSITION_HPP diff --git a/include/etl/_linalg/layout_transpose.hpp b/include/etl/_linalg/layout_transpose.hpp index 4434d88a0..165305287 100644 --- a/include/etl/_linalg/layout_transpose.hpp +++ b/include/etl/_linalg/layout_transpose.hpp @@ -4,7 +4,7 @@ #ifndef TETL_LINALG_LAYOUT_TRANSPOSE_HPP #define TETL_LINALG_LAYOUT_TRANSPOSE_HPP -#include +#include #include namespace etl::linalg { diff --git a/include/etl/_linalg/proxy_reference.hpp b/include/etl/_linalg/proxy_reference.hpp index a3c5a8003..7aa13b770 100644 --- a/include/etl/_linalg/proxy_reference.hpp +++ b/include/etl/_linalg/proxy_reference.hpp @@ -4,7 +4,7 @@ #ifndef TETL_LINALG_PROXY_REFERENCE_HPP #define TETL_LINALG_PROXY_REFERENCE_HPP -#include +#include #include namespace etl::linalg::detail { From 70addb4ee9743cf1ce154a224b2a9d1282839317 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Mon, 8 Sep 2025 00:13:51 +0200 Subject: [PATCH 02/34] [linalg] Start BLAS3 matrix product --- include/etl/_linalg/blas3_matrix_product.hpp | 40 +++++ include/etl/_linalg/exposition.hpp | 155 ++++++++++++++----- include/etl/_mdspan/mdspan.hpp | 10 ++ include/etl/linalg.hpp | 1 + tests/CMakeLists.txt | 16 +- tests/linalg/CMakeLists.txt | 1 + tests/linalg/blas3_matrix_product.t.cpp | 104 +++++++++++++ 7 files changed, 278 insertions(+), 49 deletions(-) create mode 100644 include/etl/_linalg/blas3_matrix_product.hpp create mode 100644 tests/linalg/blas3_matrix_product.t.cpp diff --git a/include/etl/_linalg/blas3_matrix_product.hpp b/include/etl/_linalg/blas3_matrix_product.hpp new file mode 100644 index 000000000..76912d755 --- /dev/null +++ b/include/etl/_linalg/blas3_matrix_product.hpp @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: BSL-1.0 +// SPDX-FileCopyrightText: Copyright (C) 2025 Tobias Hienzsch + +#ifndef TETL_LINALG_BLAS3_MATRIX_PRODUCT_HPP +#define TETL_LINALG_BLAS3_MATRIX_PRODUCT_HPP + +#include +#include +#include + +namespace etl::linalg { + +/// Computes C = AB +/// \ingroup linalg +template + requires(detail::possibly_multipliable()) +constexpr auto matrix_product(InMat1 A, InMat2 B, OutMat C) -> void +{ + TETL_PRECONDITION(detail::multipliable(A, B, C)); + + using SumT = typename OutMat::element_type; + + auto const M = A.extent(0); + auto const K = A.extent(1); + auto const N = B.extent(1); + + for (auto i = 0zu; etl::cmp_less(i, M); ++i) { + for (auto j = 0zu; etl::cmp_less(j, N); ++j) { + auto acc = SumT{}; + for (auto k = 0zu; etl::cmp_less(k, K); ++k) { + acc += A(i, k) * B(k, j); + } + C(i, j) = acc; + } + } +} + +} // namespace etl::linalg + +#endif // TETL_LINALG_BLAS3_MATRIX_PRODUCT_HPP diff --git a/include/etl/_linalg/exposition.hpp b/include/etl/_linalg/exposition.hpp index 0068daaf6..af93adbc9 100644 --- a/include/etl/_linalg/exposition.hpp +++ b/include/etl/_linalg/exposition.hpp @@ -27,12 +27,6 @@ namespace etl::linalg::detail { -template -struct is_mdspan : false_type { }; - -template -struct is_mdspan> : true_type { }; - template using common_size_type_t = common_type_t; @@ -120,65 +114,144 @@ namespace etl::linalg { /// \ingroup linalg template -concept in_vector = detail::is_mdspan::value && T::rank() == 1; +concept in_vector = is_mdspan_v and T::rank() == 1; /// \ingroup linalg template -concept out_vector = detail::is_mdspan::value - && T::rank() == 1 - && same_as, typename T::element_type> - && T::is_always_unique(); +concept out_vector = is_mdspan_v + and T::rank() == 1 + and same_as, typename T::element_type> + and T::is_always_unique(); /// \ingroup linalg template -concept inout_vector = detail::is_mdspan::value - && T::rank() == 1 - && same_as, typename T::element_type> - && T::is_always_unique(); +concept inout_vector = is_mdspan_v + and T::rank() == 1 + and same_as, typename T::element_type> + and T::is_always_unique(); /// \ingroup linalg template -concept in_matrix = detail::is_mdspan::value && T::rank() == 2; +concept in_matrix = is_mdspan_v and T::rank() == 2; /// \ingroup linalg template -concept out_matrix = detail::is_mdspan::value - && T::rank() == 2 - && is_same_v, typename T::element_type> - && T::is_always_unique(); +concept out_matrix = is_mdspan_v + and T::rank() == 2 + and is_same_v, typename T::element_type> + and T::is_always_unique(); /// \ingroup linalg template -concept inout_matrix = detail::is_mdspan::value - && T::rank() == 2 - && is_same_v, typename T::element_type> - && T::is_always_unique(); - -// template -// concept possibly_packed_inout_matrix = -// detail::is_mdspan::value && T::rank() == 2 && -// is_same_v, -// typename T::element_type> && -// (T::is_always_unique() || -// is_same_v); +concept inout_matrix = is_mdspan_v + and T::rank() == 2 + and is_same_v, typename T::element_type> + and T::is_always_unique(); /// \ingroup linalg template -concept in_object = detail::is_mdspan::value && (T::rank() == 1 || T::rank() == 2); +concept in_object = is_mdspan_v and (T::rank() == 1 || T::rank() == 2); /// \ingroup linalg template -concept out_object = detail::is_mdspan::value - && (T::rank() == 1 || T::rank() == 2) - && is_same_v, typename T::element_type> - && T::is_always_unique(); +concept out_object = is_mdspan_v + and (T::rank() == 1 || T::rank() == 2) + and is_same_v, typename T::element_type> + and T::is_always_unique(); /// \ingroup linalg template -concept inout_object = detail::is_mdspan::value - && (T::rank() == 1 || T::rank() == 2) - && is_same_v, typename T::element_type> - && T::is_always_unique(); +concept inout_object = is_mdspan_v + and (T::rank() == 1 || T::rank() == 2) + and is_same_v, typename T::element_type> + and T::is_always_unique(); + +namespace detail { + +template + requires(is_mdspan_v and is_mdspan_v) +[[nodiscard]] constexpr auto compatible_static_extents(etl::size_t r1, etl::size_t r2) -> bool +{ + return MDS1::static_extent(r1) == dynamic_extent + or MDS2::static_extent(r2) == dynamic_extent + or MDS1::static_extent(r1) == MDS2::static_extent(r2); +} + +template +[[nodiscard]] constexpr auto possibly_addable() -> bool +{ + return compatible_static_extents(0, 0) + and compatible_static_extents(0, 0) + and compatible_static_extents(0, 0); +} + +template +[[nodiscard]] constexpr auto possibly_addable() -> bool +{ + return compatible_static_extents(0, 0) + and compatible_static_extents(1, 1) + and compatible_static_extents(0, 0) + and compatible_static_extents(1, 1) + and compatible_static_extents(0, 0) + and compatible_static_extents(1, 1); +} + +template +[[nodiscard]] constexpr auto possibly_multipliable() -> bool +{ + return compatible_static_extents(0, 0) and compatible_static_extents(1, 0); +} + +template +[[nodiscard]] constexpr auto possibly_multipliable() -> bool +{ + return compatible_static_extents(0, 1) and compatible_static_extents(0, 0); +} + +template +[[nodiscard]] constexpr auto possibly_multipliable() -> bool +{ + return compatible_static_extents(0, 0) + and compatible_static_extents(1, 1) + and compatible_static_extents(1, 0); +} + +[[nodiscard]] constexpr auto addable(in_vector auto const& in1, in_vector auto const& in2, in_vector auto const& out) + -> bool +{ + return out.extent(0) == in1.extent(0) and out.extent(0) == in2.extent(0); +} + +[[nodiscard]] constexpr auto addable(in_matrix auto const& in1, in_matrix auto const& in2, in_matrix auto const& out) + -> bool +{ + return out.extent(0) == in1.extent(0) + and out.extent(1) == in1.extent(1) + and out.extent(0) == in2.extent(0) + and out.extent(1) == in2.extent(1); +} + +[[nodiscard]] constexpr auto +multipliable(in_matrix auto const& in_mat, in_vector auto const& in_vec, in_vector auto const& out_vec) -> bool +{ + return out_vec.extent(0) == in_mat.extent(0) and in_mat.extent(1) == in_vec.extent(0); +} + +[[nodiscard]] constexpr auto +multipliable(in_vector auto const& in_vec, in_matrix auto const& in_mat, in_vector auto const& out_vec) -> bool +{ + return out_vec.extent(0) == in_mat.extent(1) and in_mat.extent(0) == in_vec.extent(0); +} + +[[nodiscard]] constexpr auto +multipliable(in_matrix auto const& in_mat1, in_matrix auto const& in_mat2, in_matrix auto const& out_mat) -> bool +{ + return out_mat.extent(0) == in_mat1.extent(0) + and out_mat.extent(1) == in_mat2.extent(1) + and in_mat1.extent(1) == in_mat2.extent(0); +} + +} // namespace detail } // namespace etl::linalg diff --git a/include/etl/_mdspan/mdspan.hpp b/include/etl/_mdspan/mdspan.hpp index bff5593e9..8c9990f95 100644 --- a/include/etl/_mdspan/mdspan.hpp +++ b/include/etl/_mdspan/mdspan.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -313,6 +314,15 @@ mdspan(mdarray) -> mdspan< typename decltype(declval>().to_mdspan())::accessor_type >; +template +struct is_mdspan : false_type { }; + +template +struct is_mdspan> : true_type { }; + +template +inline constexpr auto is_mdspan_v = is_mdspan::value; + } // namespace etl #endif // TETL_MDSPAN_MDSPAN_HPP diff --git a/include/etl/linalg.hpp b/include/etl/linalg.hpp index e3b560b6d..ec75b9649 100644 --- a/include/etl/linalg.hpp +++ b/include/etl/linalg.hpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9ab930ebc..79d4afa8f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,6 +7,14 @@ target_include_directories(tetl.etl-test-common INTERFACE "${CMAKE_SOURCE_DIR}/t target_compile_definitions(tetl.etl-test-common INTERFACE TETL_ENABLE_USER_CONFIG_HEADER_INCLUDE=1) target_link_libraries(tetl.etl-test-common INTERFACE tetl::compiler_warnings) +if(TETL_BUILD_CONTRACT_CHECKS) + target_compile_definitions(tetl.etl-test-common INTERFACE TETL_ENABLE_CONTRACT_CHECKS=1) +endif() + +if(TETL_BUILD_CONTRACT_CHECKS_SAFE) + target_compile_definitions(tetl.etl-test-common INTERFACE TETL_ENABLE_CONTRACT_CHECKS_SAFE=1) +endif() + if(TETL_BUILD_CXX_MODULES) tetl_add_module_target(tetl.etl-module-for-tests) target_link_libraries(tetl.etl-module-for-tests PUBLIC tetl.etl-test-common) @@ -21,14 +29,6 @@ function(tetl_add_test _header _target) add_executable("${target_name}" "${_target}.t.cpp") target_link_libraries("${target_name}" PRIVATE tetl.etl-test-common) - if(TETL_BUILD_CONTRACT_CHECKS) - target_compile_definitions("${target_name}" PRIVATE TETL_ENABLE_CONTRACT_CHECKS=1) - endif() - - if(TETL_BUILD_CONTRACT_CHECKS_SAFE) - target_compile_definitions("${target_name}" PRIVATE TETL_ENABLE_CONTRACT_CHECKS_SAFE=1) - endif() - if(TETL_BUILD_CXX_MODULES) target_link_libraries("${target_name}" PRIVATE tetl.etl-module-for-tests) target_compile_definitions("${target_name}" PRIVATE TETL_ENABLE_CXX_MODULES=1) diff --git a/tests/linalg/CMakeLists.txt b/tests/linalg/CMakeLists.txt index 1e18f104f..0e276e297 100644 --- a/tests/linalg/CMakeLists.txt +++ b/tests/linalg/CMakeLists.txt @@ -13,6 +13,7 @@ tetl_add_test(${PROJECT_NAME} blas1_vector_abs_sum) tetl_add_test(${PROJECT_NAME} blas1_vector_idx_abs_max) tetl_add_test(${PROJECT_NAME} blas1_vector_two_norm) tetl_add_test(${PROJECT_NAME} blas2_matrix_vector_product) +tetl_add_test(${PROJECT_NAME} blas3_matrix_product) tetl_add_test(${PROJECT_NAME} concepts) tetl_add_test(${PROJECT_NAME} conjugated) tetl_add_test(${PROJECT_NAME} layout_transpose) diff --git a/tests/linalg/blas3_matrix_product.t.cpp b/tests/linalg/blas3_matrix_product.t.cpp new file mode 100644 index 000000000..8c2ff07b8 --- /dev/null +++ b/tests/linalg/blas3_matrix_product.t.cpp @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: BSL-1.0 +// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch + +#include "testing/testing.hpp" + +#if defined(TETL_ENABLE_CXX_MODULES) +import etl; +#else + #include + #include + #include + #include + #include +#endif + +template +[[nodiscard]] static constexpr auto test_linalg_matrix_product() -> bool +{ + { + // zeros + auto const aBuf = etl::array{T(0), T(0), T(0), T(0)}; + auto const bBuf = etl::array{T(0), T(0), T(0), T(0)}; + auto cBuf = etl::array{T(0), T(0), T(0), T(0)}; + + auto const a = etl::mdspan>(aBuf.data()); + auto const b = etl::mdspan>(bBuf.data()); + auto const c = etl::mdspan>(cBuf.data()); + + etl::linalg::matrix_product(a, b, c); + CHECK(c(0, 0) == T(0)); + CHECK(c(0, 1) == T(0)); + CHECK(c(1, 0) == T(0)); + CHECK(c(1, 1) == T(0)); + + etl::linalg::matrix_product(etl::linalg::scaled(T(2), a), b, c); + CHECK(c(0, 0) == T(0)); + CHECK(c(0, 1) == T(0)); + CHECK(c(1, 0) == T(0)); + CHECK(c(1, 1) == T(0)); + + etl::linalg::matrix_product(a, etl::linalg::scaled(T(2), b), c); + CHECK(c(0, 0) == T(0)); + CHECK(c(0, 1) == T(0)); + CHECK(c(1, 0) == T(0)); + CHECK(c(1, 1) == T(0)); + } + + { + // ones + auto const aBuf = etl::array{T(1), T(1), T(1), T(1)}; + auto const bBuf = etl::array{T(1), T(1), T(1), T(1)}; + auto cBuf = etl::array{T(0), T(0), T(0), T(0)}; + + auto const a = etl::mdspan>(aBuf.data()); + auto const b = etl::mdspan>(bBuf.data()); + auto const c = etl::mdspan>(cBuf.data()); + + etl::linalg::matrix_product(a, b, c); + CHECK(c(0, 0) == T(2)); + CHECK(c(0, 1) == T(2)); + CHECK(c(1, 0) == T(2)); + CHECK(c(1, 1) == T(2)); + + etl::linalg::matrix_product(etl::linalg::scaled(T(2), a), b, c); + CHECK(c(0, 0) == T(4)); + CHECK(c(0, 1) == T(4)); + CHECK(c(1, 0) == T(4)); + CHECK(c(1, 1) == T(4)); + + etl::linalg::matrix_product(a, etl::linalg::scaled(T(2), b), c); + CHECK(c(0, 0) == T(4)); + CHECK(c(0, 1) == T(4)); + CHECK(c(1, 0) == T(4)); + CHECK(c(1, 1) == T(4)); + } + + return true; +} + +[[nodiscard]] static constexpr auto test_all() -> bool +{ + CHECK(test_linalg_matrix_product()); + CHECK(test_linalg_matrix_product()); + CHECK(test_linalg_matrix_product()); + CHECK(test_linalg_matrix_product()); + CHECK(test_linalg_matrix_product()); + + CHECK(test_linalg_matrix_product()); + CHECK(test_linalg_matrix_product()); + CHECK(test_linalg_matrix_product()); + CHECK(test_linalg_matrix_product()); + CHECK(test_linalg_matrix_product()); + + CHECK(test_linalg_matrix_product()); + CHECK(test_linalg_matrix_product()); + + return true; +} + +auto main() -> int +{ + STATIC_CHECK(test_all()); + return 0; +} From 90da1b2419234b05c45c5a282b9aaac678e01eba Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Mon, 8 Sep 2025 05:36:55 +0200 Subject: [PATCH 03/34] [linalg] Rename common_size_type_t to common_index_type_t --- include/etl/_linalg/blas1_add.hpp | 8 ++++---- include/etl/_linalg/blas1_copy.hpp | 8 ++++---- include/etl/_linalg/blas1_swap_elements.hpp | 13 +++++++++---- include/etl/_linalg/blas2_matrix_vector_product.hpp | 6 +++--- include/etl/_linalg/exposition.hpp | 2 +- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/include/etl/_linalg/blas1_add.hpp b/include/etl/_linalg/blas1_add.hpp index 07c4e71c5..6a3a82068 100644 --- a/include/etl/_linalg/blas1_add.hpp +++ b/include/etl/_linalg/blas1_add.hpp @@ -18,16 +18,16 @@ constexpr auto add(InObj1 x, InObj2 y, OutObj z) -> void TETL_PRECONDITION(x.extents() == y.extents()); TETL_PRECONDITION(x.extents() == z.extents()); - using size_type = detail::common_size_type_t; + using index_type = detail::common_index_type_t; if constexpr (OutObj::rank() == 1) { - for (size_type row{0}; etl::cmp_less(row, x.extent(0)); ++row) { + for (index_type row{0}; etl::cmp_less(row, x.extent(0)); ++row) { z(row) = x(row) + y(row); } } else { static_assert(OutObj::rank() == 2); - for (size_type row{0}; etl::cmp_less(row, x.extent(0)); ++row) { - for (size_type col{0}; etl::cmp_less(col, x.extent(1)); ++col) { + for (index_type row{0}; etl::cmp_less(row, x.extent(0)); ++row) { + for (index_type col{0}; etl::cmp_less(col, x.extent(1)); ++col) { z(row, col) = x(row, col) + y(row, col); } } diff --git a/include/etl/_linalg/blas1_copy.hpp b/include/etl/_linalg/blas1_copy.hpp index 022cc0dd3..b70c5cfd6 100644 --- a/include/etl/_linalg/blas1_copy.hpp +++ b/include/etl/_linalg/blas1_copy.hpp @@ -17,16 +17,16 @@ constexpr auto copy(InObj x, OutObj y) -> void { TETL_PRECONDITION(x.extents() == y.extents()); - using size_type = detail::common_size_type_t; + using index_type = detail::common_index_type_t; if constexpr (InObj::rank() == 1) { - for (size_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { + for (index_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { y(i) = x(i); } } else { static_assert(InObj::rank() == 2); - for (size_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { - for (size_type j{0}; etl::cmp_less(j, x.extent(1)); ++j) { + for (index_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { + for (index_type j{0}; etl::cmp_less(j, x.extent(1)); ++j) { y(i, j) = x(i, j); } } diff --git a/include/etl/_linalg/blas1_swap_elements.hpp b/include/etl/_linalg/blas1_swap_elements.hpp index 25bc96e79..71e2c08d2 100644 --- a/include/etl/_linalg/blas1_swap_elements.hpp +++ b/include/etl/_linalg/blas1_swap_elements.hpp @@ -18,17 +18,22 @@ constexpr auto swap_elements(InOutObj1 x, InOutObj2 y) -> void { TETL_PRECONDITION(x.extents() == y.extents()); - using size_type = detail::common_size_type_t; + using index_type = detail::common_index_type_t; if constexpr (InOutObj1::rank() == 1) { - for (size_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { + static_assert(detail::compatible_static_extents(0, 0)); + + for (index_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { using etl::swap; swap(x(i), y(i)); } } else { static_assert(InOutObj1::rank() == 2); - for (size_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { - for (size_type j{0}; etl::cmp_less(j, x.extent(1)); ++j) { + static_assert(detail::compatible_static_extents(0, 0)); + static_assert(detail::compatible_static_extents(1, 1)); + + for (index_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { + for (index_type j{0}; etl::cmp_less(j, x.extent(1)); ++j) { using etl::swap; swap(x(i, j), y(i, j)); } diff --git a/include/etl/_linalg/blas2_matrix_vector_product.hpp b/include/etl/_linalg/blas2_matrix_vector_product.hpp index 979efcc0b..762802fee 100644 --- a/include/etl/_linalg/blas2_matrix_vector_product.hpp +++ b/include/etl/_linalg/blas2_matrix_vector_product.hpp @@ -17,11 +17,11 @@ constexpr auto matrix_vector_product(InMat a, InVec x, OutVec y) noexcept -> voi TETL_PRECONDITION(a.extent(1) == x.extent(0)); TETL_PRECONDITION(a.extent(0) == y.extent(0)); - using size_type = detail::common_size_type_t; + using index_type = detail::common_index_type_t; - for (size_type i(0); etl::cmp_less(i, a.extent(0)); ++i) { + for (index_type i(0); etl::cmp_less(i, a.extent(0)); ++i) { y(i) = typename OutVec::element_type{}; - for (size_type j(0); etl::cmp_less(j, a.extent(1)); ++j) { + for (index_type j(0); etl::cmp_less(j, a.extent(1)); ++j) { y(i) += a(i, j) * x(j); } } diff --git a/include/etl/_linalg/exposition.hpp b/include/etl/_linalg/exposition.hpp index af93adbc9..ecb41a2af 100644 --- a/include/etl/_linalg/exposition.hpp +++ b/include/etl/_linalg/exposition.hpp @@ -28,7 +28,7 @@ namespace etl::linalg::detail { template -using common_size_type_t = common_type_t; +using common_index_type_t = common_type_t; namespace linalg_adl_checks { From 02f72b802810ec813d87d3fd077b078753b232e6 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Mon, 8 Sep 2025 06:10:57 +0200 Subject: [PATCH 04/34] [linalg] Naming cleanup --- include/etl/_linalg/blas1_add.hpp | 4 ++-- include/etl/_linalg/blas1_copy.hpp | 4 ++++ include/etl/_linalg/blas3_matrix_product.hpp | 25 +++++++++----------- include/etl/_linalg/exposition.hpp | 16 ++++++------- include/etl/_mdspan/mdspan.hpp | 12 +++++----- 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/include/etl/_linalg/blas1_add.hpp b/include/etl/_linalg/blas1_add.hpp index 6a3a82068..3cb83f018 100644 --- a/include/etl/_linalg/blas1_add.hpp +++ b/include/etl/_linalg/blas1_add.hpp @@ -15,8 +15,8 @@ template requires(InObj1::rank() == OutObj::rank() and InObj2::rank() == OutObj::rank()) constexpr auto add(InObj1 x, InObj2 y, OutObj z) -> void { - TETL_PRECONDITION(x.extents() == y.extents()); - TETL_PRECONDITION(x.extents() == z.extents()); + static_assert(detail::possibly_addable()); + TETL_PRECONDITION(detail::addable(x, y, z)); using index_type = detail::common_index_type_t; diff --git a/include/etl/_linalg/blas1_copy.hpp b/include/etl/_linalg/blas1_copy.hpp index b70c5cfd6..8666a51ed 100644 --- a/include/etl/_linalg/blas1_copy.hpp +++ b/include/etl/_linalg/blas1_copy.hpp @@ -20,11 +20,15 @@ constexpr auto copy(InObj x, OutObj y) -> void using index_type = detail::common_index_type_t; if constexpr (InObj::rank() == 1) { + static_assert(detail::compatible_static_extents(0, 0)); for (index_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { y(i) = x(i); } } else { static_assert(InObj::rank() == 2); + static_assert(detail::compatible_static_extents(0, 0)); + static_assert(detail::compatible_static_extents(1, 1)); + for (index_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { for (index_type j{0}; etl::cmp_less(j, x.extent(1)); ++j) { y(i, j) = x(i, j); diff --git a/include/etl/_linalg/blas3_matrix_product.hpp b/include/etl/_linalg/blas3_matrix_product.hpp index 76912d755..f48a899a8 100644 --- a/include/etl/_linalg/blas3_matrix_product.hpp +++ b/include/etl/_linalg/blas3_matrix_product.hpp @@ -13,24 +13,21 @@ namespace etl::linalg { /// Computes C = AB /// \ingroup linalg template - requires(detail::possibly_multipliable()) -constexpr auto matrix_product(InMat1 A, InMat2 B, OutMat C) -> void +constexpr auto matrix_product(InMat1 a, InMat2 b, OutMat c) -> void { - TETL_PRECONDITION(detail::multipliable(A, B, C)); + static_assert(detail::possibly_multipliable()); + TETL_PRECONDITION(detail::multipliable(a, b, c)); - using SumT = typename OutMat::element_type; + using index_type = detail::common_index_type_t; + using sum_type = typename OutMat::element_type; - auto const M = A.extent(0); - auto const K = A.extent(1); - auto const N = B.extent(1); - - for (auto i = 0zu; etl::cmp_less(i, M); ++i) { - for (auto j = 0zu; etl::cmp_less(j, N); ++j) { - auto acc = SumT{}; - for (auto k = 0zu; etl::cmp_less(k, K); ++k) { - acc += A(i, k) * B(k, j); + for (auto i = index_type{0}; etl::cmp_less(i, a.extent(0)); ++i) { + for (auto j = index_type{0}; etl::cmp_less(j, b.extent(1)); ++j) { + auto acc = sum_type{}; + for (auto k = index_type{0}; etl::cmp_less(k, a.extent(1)); ++k) { + acc += a(i, k) * b(k, j); } - C(i, j) = acc; + c(i, j) = acc; } } } diff --git a/include/etl/_linalg/exposition.hpp b/include/etl/_linalg/exposition.hpp index ecb41a2af..709a8b1b7 100644 --- a/include/etl/_linalg/exposition.hpp +++ b/include/etl/_linalg/exposition.hpp @@ -232,23 +232,23 @@ template } [[nodiscard]] constexpr auto -multipliable(in_matrix auto const& in_mat, in_vector auto const& in_vec, in_vector auto const& out_vec) -> bool +multipliable(in_matrix auto const& inMat, in_vector auto const& inVec, in_vector auto const& outVec) -> bool { - return out_vec.extent(0) == in_mat.extent(0) and in_mat.extent(1) == in_vec.extent(0); + return outVec.extent(0) == inMat.extent(0) and inMat.extent(1) == inVec.extent(0); } [[nodiscard]] constexpr auto -multipliable(in_vector auto const& in_vec, in_matrix auto const& in_mat, in_vector auto const& out_vec) -> bool +multipliable(in_vector auto const& inVec, in_matrix auto const& inMat, in_vector auto const& outVec) -> bool { - return out_vec.extent(0) == in_mat.extent(1) and in_mat.extent(0) == in_vec.extent(0); + return outVec.extent(0) == inMat.extent(1) and inMat.extent(0) == inVec.extent(0); } [[nodiscard]] constexpr auto -multipliable(in_matrix auto const& in_mat1, in_matrix auto const& in_mat2, in_matrix auto const& out_mat) -> bool +multipliable(in_matrix auto const& inMat1, in_matrix auto const& inMat2, in_matrix auto const& outMat) -> bool { - return out_mat.extent(0) == in_mat1.extent(0) - and out_mat.extent(1) == in_mat2.extent(1) - and in_mat1.extent(1) == in_mat2.extent(0); + return outMat.extent(0) == inMat1.extent(0) + and outMat.extent(1) == inMat2.extent(1) + and inMat1.extent(1) == inMat2.extent(0); } } // namespace detail diff --git a/include/etl/_mdspan/mdspan.hpp b/include/etl/_mdspan/mdspan.hpp index 8c9990f95..83cde8607 100644 --- a/include/etl/_mdspan/mdspan.hpp +++ b/include/etl/_mdspan/mdspan.hpp @@ -149,12 +149,12 @@ struct mdspan { } template - requires((is_constructible_v const&> - and is_constructible_v)) - explicit(( + requires(is_constructible_v const&> + and is_constructible_v) + explicit( not is_convertible_v const&, mapping_type> or not is_convertible_v - )) constexpr mdspan(mdspan const& other) + ) constexpr mdspan(mdspan const& other) : _ptr(other.data_handle()) , _map(other.mapping()) , _acc(other.accessor()) @@ -168,8 +168,8 @@ struct mdspan { template requires( - (is_convertible_v && ...) - and (is_nothrow_constructible_v && ...) + (is_convertible_v and ...) + and (is_nothrow_constructible_v and ...) and sizeof...(OtherIndexTypes) == rank() ) [[nodiscard]] constexpr auto operator()(OtherIndexTypes... indices) const -> reference From 9146f3fef916529b167b66f1d7109c90657f5ffd Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Mon, 8 Sep 2025 12:28:44 +0200 Subject: [PATCH 05/34] [linalg] Use common index_type for loop counters --- include/etl/_linalg/blas1_add.hpp | 7 +++---- include/etl/_linalg/blas1_copy.hpp | 7 +++---- include/etl/_linalg/blas1_matrix_frob_norm.hpp | 5 ++--- include/etl/_linalg/blas1_scale.hpp | 9 ++++----- include/etl/_linalg/blas1_swap_elements.hpp | 7 +++---- include/etl/_linalg/blas1_vector_abs_sum.hpp | 3 +-- include/etl/_linalg/blas1_vector_idx_abs_max.hpp | 5 ++--- include/etl/_linalg/blas1_vector_two_norm.hpp | 3 +-- include/etl/_linalg/blas2_matrix_vector_product.hpp | 5 ++--- include/etl/_linalg/blas3_matrix_product.hpp | 7 +++---- 10 files changed, 24 insertions(+), 34 deletions(-) diff --git a/include/etl/_linalg/blas1_add.hpp b/include/etl/_linalg/blas1_add.hpp index 3cb83f018..3a79f5708 100644 --- a/include/etl/_linalg/blas1_add.hpp +++ b/include/etl/_linalg/blas1_add.hpp @@ -6,7 +6,6 @@ #include #include -#include namespace etl::linalg { @@ -21,13 +20,13 @@ constexpr auto add(InObj1 x, InObj2 y, OutObj z) -> void using index_type = detail::common_index_type_t; if constexpr (OutObj::rank() == 1) { - for (index_type row{0}; etl::cmp_less(row, x.extent(0)); ++row) { + for (index_type row{0}; row < x.extent(0); ++row) { z(row) = x(row) + y(row); } } else { static_assert(OutObj::rank() == 2); - for (index_type row{0}; etl::cmp_less(row, x.extent(0)); ++row) { - for (index_type col{0}; etl::cmp_less(col, x.extent(1)); ++col) { + for (index_type row{0}; row < x.extent(0); ++row) { + for (index_type col{0}; col < x.extent(1); ++col) { z(row, col) = x(row, col) + y(row, col); } } diff --git a/include/etl/_linalg/blas1_copy.hpp b/include/etl/_linalg/blas1_copy.hpp index 8666a51ed..3b2bb75d7 100644 --- a/include/etl/_linalg/blas1_copy.hpp +++ b/include/etl/_linalg/blas1_copy.hpp @@ -6,7 +6,6 @@ #include #include -#include namespace etl::linalg { @@ -21,7 +20,7 @@ constexpr auto copy(InObj x, OutObj y) -> void if constexpr (InObj::rank() == 1) { static_assert(detail::compatible_static_extents(0, 0)); - for (index_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { + for (index_type i{0}; i < x.extent(0); ++i) { y(i) = x(i); } } else { @@ -29,8 +28,8 @@ constexpr auto copy(InObj x, OutObj y) -> void static_assert(detail::compatible_static_extents(0, 0)); static_assert(detail::compatible_static_extents(1, 1)); - for (index_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { - for (index_type j{0}; etl::cmp_less(j, x.extent(1)); ++j) { + for (index_type i{0}; i < x.extent(0); ++i) { + for (index_type j{0}; j < x.extent(1); ++j) { y(i, j) = x(i, j); } } diff --git a/include/etl/_linalg/blas1_matrix_frob_norm.hpp b/include/etl/_linalg/blas1_matrix_frob_norm.hpp index 61912ca98..55a413350 100644 --- a/include/etl/_linalg/blas1_matrix_frob_norm.hpp +++ b/include/etl/_linalg/blas1_matrix_frob_norm.hpp @@ -7,7 +7,6 @@ #include #include #include -#include namespace etl::linalg { @@ -16,8 +15,8 @@ template [[nodiscard]] constexpr auto matrix_frob_norm(InMat a, Scalar init) -> Scalar { auto result = init; - for (typename InMat::size_type row{0}; etl::cmp_less(row, a.extent(0)); ++row) { - for (typename InMat::size_type col{0}; etl::cmp_less(col, a.extent(1)); ++col) { + for (typename InMat::index_type row{0}; row < a.extent(0); ++row) { + for (typename InMat::index_type col{0}; col < a.extent(1); ++col) { result += detail::abs_if_needed(a(row, col)); } } diff --git a/include/etl/_linalg/blas1_scale.hpp b/include/etl/_linalg/blas1_scale.hpp index dd53abfbe..28b91100f 100644 --- a/include/etl/_linalg/blas1_scale.hpp +++ b/include/etl/_linalg/blas1_scale.hpp @@ -5,7 +5,6 @@ #define TETL_LINALG_BLAS1_SCALE_HPP #include -#include namespace etl::linalg { @@ -13,16 +12,16 @@ namespace etl::linalg { template constexpr auto scale(Scalar alpha, InOutObj x) -> void { - using size_type = typename InOutObj::size_type; + using index_type = typename InOutObj::index_type; if constexpr (InOutObj::rank() == 1) { - for (size_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { + for (index_type i{0}; i < x.extent(0); ++i) { x(i) = x(i) * alpha; } } else { static_assert(InOutObj::rank() == 2); - for (size_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { - for (size_type j{0}; etl::cmp_less(j, x.extent(1)); ++j) { + for (index_type i{0}; i < x.extent(0); ++i) { + for (index_type j{0}; j < x.extent(1); ++j) { x(i, j) = x(i, j) * alpha; } } diff --git a/include/etl/_linalg/blas1_swap_elements.hpp b/include/etl/_linalg/blas1_swap_elements.hpp index 71e2c08d2..86995fcb4 100644 --- a/include/etl/_linalg/blas1_swap_elements.hpp +++ b/include/etl/_linalg/blas1_swap_elements.hpp @@ -6,7 +6,6 @@ #include #include -#include #include namespace etl::linalg { @@ -23,7 +22,7 @@ constexpr auto swap_elements(InOutObj1 x, InOutObj2 y) -> void if constexpr (InOutObj1::rank() == 1) { static_assert(detail::compatible_static_extents(0, 0)); - for (index_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { + for (index_type i{0}; i < static_cast(x.extent(0)); ++i) { using etl::swap; swap(x(i), y(i)); } @@ -32,8 +31,8 @@ constexpr auto swap_elements(InOutObj1 x, InOutObj2 y) -> void static_assert(detail::compatible_static_extents(0, 0)); static_assert(detail::compatible_static_extents(1, 1)); - for (index_type i{0}; etl::cmp_less(i, x.extent(0)); ++i) { - for (index_type j{0}; etl::cmp_less(j, x.extent(1)); ++j) { + for (index_type i{0}; i < static_cast(x.extent(0)); ++i) { + for (index_type j{0}; j < static_cast(x.extent(1)); ++j) { using etl::swap; swap(x(i, j), y(i, j)); } diff --git a/include/etl/_linalg/blas1_vector_abs_sum.hpp b/include/etl/_linalg/blas1_vector_abs_sum.hpp index 11ba51a34..10210c72a 100644 --- a/include/etl/_linalg/blas1_vector_abs_sum.hpp +++ b/include/etl/_linalg/blas1_vector_abs_sum.hpp @@ -6,7 +6,6 @@ #include #include -#include namespace etl::linalg { @@ -15,7 +14,7 @@ template constexpr auto vector_abs_sum(InVec v, Scalar init) noexcept -> Scalar { auto sum = init; - for (typename InVec::size_type i{0}; etl::cmp_less(i, v.extent(0)); ++i) { + for (typename InVec::index_type i{0}; i < v.extent(0); ++i) { if constexpr (is_arithmetic_v) { sum += detail::abs_if_needed(v(i)); } else { diff --git a/include/etl/_linalg/blas1_vector_idx_abs_max.hpp b/include/etl/_linalg/blas1_vector_idx_abs_max.hpp index 621227821..33016ea69 100644 --- a/include/etl/_linalg/blas1_vector_idx_abs_max.hpp +++ b/include/etl/_linalg/blas1_vector_idx_abs_max.hpp @@ -7,7 +7,6 @@ #include #include #include -#include namespace etl::linalg { @@ -28,9 +27,9 @@ constexpr auto idx_abs_max(InVec v) -> typename InVec::size_type auto idx = numeric_limits::max(); auto maxV = numeric_limits::min(); - for (typename InVec::size_type i{0}; etl::cmp_less(i, v.extent(0)); ++i) { + for (typename InVec::index_type i{0}; i < v.extent(0); ++i) { if (auto const val = getValue(v(i)); val > maxV) { - idx = i; + idx = static_cast(i); maxV = val; } } diff --git a/include/etl/_linalg/blas1_vector_two_norm.hpp b/include/etl/_linalg/blas1_vector_two_norm.hpp index aad2a4ecf..0ac20a595 100644 --- a/include/etl/_linalg/blas1_vector_two_norm.hpp +++ b/include/etl/_linalg/blas1_vector_two_norm.hpp @@ -7,7 +7,6 @@ #include #include #include -#include namespace etl::linalg { @@ -16,7 +15,7 @@ template constexpr auto vector_two_norm(InVec v, Scalar init) noexcept -> Scalar { auto sum = init; - for (typename InVec::size_type i{0}; etl::cmp_less(i, v.extent(0)); ++i) { + for (typename InVec::index_type i{0}; i < v.extent(0); ++i) { auto const val = detail::abs_if_needed(v(i)); auto const square = val * val; sum += square; diff --git a/include/etl/_linalg/blas2_matrix_vector_product.hpp b/include/etl/_linalg/blas2_matrix_vector_product.hpp index 762802fee..473acf015 100644 --- a/include/etl/_linalg/blas2_matrix_vector_product.hpp +++ b/include/etl/_linalg/blas2_matrix_vector_product.hpp @@ -6,7 +6,6 @@ #include #include -#include namespace etl::linalg { @@ -19,9 +18,9 @@ constexpr auto matrix_vector_product(InMat a, InVec x, OutVec y) noexcept -> voi using index_type = detail::common_index_type_t; - for (index_type i(0); etl::cmp_less(i, a.extent(0)); ++i) { + for (index_type i{0}; i < static_cast(a.extent(0)); ++i) { y(i) = typename OutVec::element_type{}; - for (index_type j(0); etl::cmp_less(j, a.extent(1)); ++j) { + for (index_type j{0}; j < static_cast(a.extent(1)); ++j) { y(i) += a(i, j) * x(j); } } diff --git a/include/etl/_linalg/blas3_matrix_product.hpp b/include/etl/_linalg/blas3_matrix_product.hpp index f48a899a8..2103c6360 100644 --- a/include/etl/_linalg/blas3_matrix_product.hpp +++ b/include/etl/_linalg/blas3_matrix_product.hpp @@ -6,7 +6,6 @@ #include #include -#include namespace etl::linalg { @@ -21,10 +20,10 @@ constexpr auto matrix_product(InMat1 a, InMat2 b, OutMat c) -> void using index_type = detail::common_index_type_t; using sum_type = typename OutMat::element_type; - for (auto i = index_type{0}; etl::cmp_less(i, a.extent(0)); ++i) { - for (auto j = index_type{0}; etl::cmp_less(j, b.extent(1)); ++j) { + for (auto i = index_type{0}; i < static_cast(a.extent(0)); ++i) { + for (auto j = index_type{0}; j < static_cast(b.extent(1)); ++j) { auto acc = sum_type{}; - for (auto k = index_type{0}; etl::cmp_less(k, a.extent(1)); ++k) { + for (auto k = index_type{0}; k < static_cast(a.extent(1)); ++k) { acc += a(i, k) * b(k, j); } c(i, j) = acc; From ce610a4f300e411e746ef6524893649285612d42 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Mon, 8 Sep 2025 12:29:01 +0200 Subject: [PATCH 06/34] [cmath] Use more gcc & clang builtins --- include/etl/_cmath/acos.hpp | 2 +- include/etl/_cmath/acosh.hpp | 2 +- include/etl/_cmath/asin.hpp | 2 +- include/etl/_cmath/asinh.hpp | 2 +- include/etl/_cmath/atan.hpp | 2 +- include/etl/_cmath/atan2.hpp | 34 ++++++++++++++++++++---- include/etl/_cmath/atanh.hpp | 38 ++++++++++++++++++++++----- include/etl/_cmath/ceil.hpp | 36 +++++++++++++++++++++----- include/etl/_cmath/cos.hpp | 2 +- include/etl/_cmath/cosh.hpp | 36 +++++++++++++++++++++----- include/etl/_cmath/erf.hpp | 36 +++++++++++++++++++++----- include/etl/_cmath/exp.hpp | 2 +- include/etl/_cmath/floor.hpp | 2 +- include/etl/_cmath/fmod.hpp | 34 ++++++++++++++++++++---- include/etl/_cmath/lgamma.hpp | 36 +++++++++++++++++++++----- include/etl/_cmath/log.hpp | 2 +- include/etl/_cmath/log10.hpp | 4 +-- include/etl/_cmath/log1p.hpp | 36 +++++++++++++++++++++----- include/etl/_cmath/log2.hpp | 2 +- include/etl/_cmath/remainder.hpp | 44 ++++++++++++++++++++++++++++---- include/etl/_cmath/round.hpp | 26 ++++++++++--------- include/etl/_cmath/sin.hpp | 2 +- include/etl/_cmath/sinh.hpp | 36 +++++++++++++++++++++----- include/etl/_cmath/sqrt.hpp | 36 +++++++++++++++++++++----- include/etl/_cmath/tan.hpp | 2 +- include/etl/_cmath/tanh.hpp | 2 +- include/etl/_cmath/tgamma.hpp | 36 +++++++++++++++++++++----- include/etl/_cmath/trunc.hpp | 2 +- 28 files changed, 399 insertions(+), 97 deletions(-) diff --git a/include/etl/_cmath/acos.hpp b/include/etl/_cmath/acos.hpp index 0f5e4f164..5a288fd85 100644 --- a/include/etl/_cmath/acos.hpp +++ b/include/etl/_cmath/acos.hpp @@ -64,7 +64,7 @@ inline constexpr struct acos { } [[nodiscard]] constexpr auto acos(integral auto arg) noexcept -> double { - return etl::detail::acos(double(arg)); + return etl::detail::acos(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/acosh.hpp b/include/etl/_cmath/acosh.hpp index a7eeabe64..46331fa47 100644 --- a/include/etl/_cmath/acosh.hpp +++ b/include/etl/_cmath/acosh.hpp @@ -66,7 +66,7 @@ inline constexpr struct acosh { } [[nodiscard]] constexpr auto acosh(integral auto arg) noexcept -> double { - return etl::detail::acosh(double(arg)); + return etl::detail::acosh(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/asin.hpp b/include/etl/_cmath/asin.hpp index 2c825da7f..71a34945d 100644 --- a/include/etl/_cmath/asin.hpp +++ b/include/etl/_cmath/asin.hpp @@ -64,7 +64,7 @@ inline constexpr struct asin { } [[nodiscard]] constexpr auto asin(integral auto arg) noexcept -> double { - return etl::detail::asin(double(arg)); + return etl::detail::asin(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/asinh.hpp b/include/etl/_cmath/asinh.hpp index 63b0ba07a..db8d5384b 100644 --- a/include/etl/_cmath/asinh.hpp +++ b/include/etl/_cmath/asinh.hpp @@ -66,7 +66,7 @@ inline constexpr struct asinh { } [[nodiscard]] constexpr auto asinh(integral auto arg) noexcept -> double { - return etl::detail::asinh(double(arg)); + return etl::detail::asinh(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/atan.hpp b/include/etl/_cmath/atan.hpp index 17a43fa9b..e462499a3 100644 --- a/include/etl/_cmath/atan.hpp +++ b/include/etl/_cmath/atan.hpp @@ -64,7 +64,7 @@ inline constexpr struct atan { } [[nodiscard]] constexpr auto atan(integral auto arg) noexcept -> double { - return etl::detail::atan(double(arg)); + return etl::detail::atan(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/atan2.hpp b/include/etl/_cmath/atan2.hpp index f90117f8e..043db5170 100644 --- a/include/etl/_cmath/atan2.hpp +++ b/include/etl/_cmath/atan2.hpp @@ -8,6 +8,30 @@ namespace etl { +namespace detail { + +inline constexpr struct atan2 { + template + [[nodiscard]] constexpr auto operator()(Float x, Float y) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_atan2f) + if constexpr (etl::same_as) { + return __builtin_atan2f(x, y); + } +#endif +#if __has_builtin(__builtin_atan2) + if constexpr (etl::same_as) { + return __builtin_atan2(x, y); + } +#endif + } + return etl::detail::gcem::atan2(x, y); + } +} atan2; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -15,27 +39,27 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/atan2 [[nodiscard]] constexpr auto atan2(float x, float y) noexcept -> float { - return etl::detail::gcem::atan2(x, y); + return etl::detail::atan2(x, y); } [[nodiscard]] constexpr auto atan2f(float x, float y) noexcept -> float { - return etl::detail::gcem::atan2(x, y); + return etl::detail::atan2(x, y); } [[nodiscard]] constexpr auto atan2(double x, double y) noexcept -> double { - return etl::detail::gcem::atan2(x, y); + return etl::detail::atan2(x, y); } [[nodiscard]] constexpr auto atan2(long double x, long double y) noexcept -> long double { - return etl::detail::gcem::atan2(x, y); + return etl::detail::atan2(x, y); } [[nodiscard]] constexpr auto atan2l(long double x, long double y) noexcept -> long double { - return etl::detail::gcem::atan2(x, y); + return etl::detail::atan2(x, y); } /// @} diff --git a/include/etl/_cmath/atanh.hpp b/include/etl/_cmath/atanh.hpp index ed42d7a56..445d1b551 100644 --- a/include/etl/_cmath/atanh.hpp +++ b/include/etl/_cmath/atanh.hpp @@ -9,6 +9,32 @@ namespace etl { +namespace detail { + +inline constexpr struct atanh { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { +#if not defined(__AVR__) + if (not is_constant_evaluated()) { + #if __has_builtin(__builtin_atanhf) + if constexpr (etl::same_as) { + return __builtin_atanhf(arg); + } + #endif + #if __has_builtin(__builtin_atanh) + if constexpr (etl::same_as) { + return __builtin_atanh(arg); + } + #endif + } +#endif + return etl::detail::gcem::atanh(arg); + } +} atanh; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -16,27 +42,27 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/atanh [[nodiscard]] constexpr auto atanh(float arg) noexcept -> float { - return etl::detail::gcem::atanh(arg); + return etl::detail::atanh(arg); } [[nodiscard]] constexpr auto atanhf(float arg) noexcept -> float { - return etl::detail::gcem::atanh(arg); + return etl::detail::atanh(arg); } [[nodiscard]] constexpr auto atanh(double arg) noexcept -> double { - return etl::detail::gcem::atanh(arg); + return etl::detail::atanh(arg); } [[nodiscard]] constexpr auto atanh(long double arg) noexcept -> long double { - return etl::detail::gcem::atanh(arg); + return etl::detail::atanh(arg); } [[nodiscard]] constexpr auto atanhl(long double arg) noexcept -> long double { - return etl::detail::gcem::atanh(arg); + return etl::detail::atanh(arg); } [[nodiscard]] constexpr auto atanh(integral auto arg) noexcept -> double { - return etl::detail::gcem::atanh(double(arg)); + return etl::detail::atanh(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/ceil.hpp b/include/etl/_cmath/ceil.hpp index eb1079409..6e3bb5b4e 100644 --- a/include/etl/_cmath/ceil.hpp +++ b/include/etl/_cmath/ceil.hpp @@ -9,6 +9,30 @@ namespace etl { +namespace detail { + +inline constexpr struct ceil { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_ceilf) + if constexpr (etl::same_as) { + return __builtin_ceilf(arg); + } +#endif +#if __has_builtin(__builtin_ceil) + if constexpr (etl::same_as) { + return __builtin_ceil(arg); + } +#endif + } + return etl::detail::gcem::ceil(arg); + } +} ceil; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -16,27 +40,27 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/ceil [[nodiscard]] constexpr auto ceil(float arg) noexcept -> float { - return etl::detail::gcem::ceil(arg); + return etl::detail::ceil(arg); } [[nodiscard]] constexpr auto ceilf(float arg) noexcept -> float { - return etl::detail::gcem::ceil(arg); + return etl::detail::ceil(arg); } [[nodiscard]] constexpr auto ceil(double arg) noexcept -> double { - return etl::detail::gcem::ceil(arg); + return etl::detail::ceil(arg); } [[nodiscard]] constexpr auto ceil(long double arg) noexcept -> long double { - return etl::detail::gcem::ceil(arg); + return etl::detail::ceil(arg); } [[nodiscard]] constexpr auto ceill(long double arg) noexcept -> long double { - return etl::detail::gcem::ceil(arg); + return etl::detail::ceil(arg); } [[nodiscard]] constexpr auto ceil(integral auto arg) noexcept -> double { - return etl::detail::gcem::ceil(double(arg)); + return etl::detail::ceil(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/cos.hpp b/include/etl/_cmath/cos.hpp index f214afa44..73ddf87b6 100644 --- a/include/etl/_cmath/cos.hpp +++ b/include/etl/_cmath/cos.hpp @@ -64,7 +64,7 @@ inline constexpr struct cos { } [[nodiscard]] constexpr auto cos(integral auto arg) noexcept -> double { - return etl::detail::cos(double(arg)); + return etl::detail::cos(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/cosh.hpp b/include/etl/_cmath/cosh.hpp index 534718e78..d2d966bc8 100644 --- a/include/etl/_cmath/cosh.hpp +++ b/include/etl/_cmath/cosh.hpp @@ -9,6 +9,30 @@ namespace etl { +namespace detail { + +inline constexpr struct cosh { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_coshf) + if constexpr (etl::same_as) { + return __builtin_coshf(arg); + } +#endif +#if __has_builtin(__builtin_cosh) + if constexpr (etl::same_as) { + return __builtin_cosh(arg); + } +#endif + } + return etl::detail::gcem::cosh(arg); + } +} cosh; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -16,27 +40,27 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/cosh [[nodiscard]] constexpr auto cosh(float arg) noexcept -> float { - return etl::detail::gcem::cosh(arg); + return etl::detail::cosh(arg); } [[nodiscard]] constexpr auto coshf(float arg) noexcept -> float { - return etl::detail::gcem::cosh(arg); + return etl::detail::cosh(arg); } [[nodiscard]] constexpr auto cosh(double arg) noexcept -> double { - return etl::detail::gcem::cosh(arg); + return etl::detail::cosh(arg); } [[nodiscard]] constexpr auto cosh(long double arg) noexcept -> long double { - return etl::detail::gcem::cosh(arg); + return etl::detail::cosh(arg); } [[nodiscard]] constexpr auto coshl(long double arg) noexcept -> long double { - return etl::detail::gcem::cosh(arg); + return etl::detail::cosh(arg); } [[nodiscard]] constexpr auto cosh(integral auto arg) noexcept -> double { - return etl::detail::gcem::cosh(double(arg)); + return etl::detail::cosh(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/erf.hpp b/include/etl/_cmath/erf.hpp index 6e1573160..2e471e9da 100644 --- a/include/etl/_cmath/erf.hpp +++ b/include/etl/_cmath/erf.hpp @@ -9,6 +9,30 @@ namespace etl { +namespace detail { + +inline constexpr struct erf { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_erff) + if constexpr (etl::same_as) { + return __builtin_erff(arg); + } +#endif +#if __has_builtin(__builtin_erf) + if constexpr (etl::same_as) { + return __builtin_erf(arg); + } +#endif + } + return etl::detail::gcem::erf(arg); + } +} erf; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -16,27 +40,27 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/erf [[nodiscard]] constexpr auto erf(float arg) noexcept -> float { - return etl::detail::gcem::erf(arg); + return etl::detail::erf(arg); } [[nodiscard]] constexpr auto erff(float arg) noexcept -> float { - return etl::detail::gcem::erf(arg); + return etl::detail::erf(arg); } [[nodiscard]] constexpr auto erf(double arg) noexcept -> double { - return etl::detail::gcem::erf(arg); + return etl::detail::erf(arg); } [[nodiscard]] constexpr auto erf(long double arg) noexcept -> long double { - return etl::detail::gcem::erf(arg); + return etl::detail::erf(arg); } [[nodiscard]] constexpr auto erfl(long double arg) noexcept -> long double { - return etl::detail::gcem::erf(arg); + return etl::detail::erf(arg); } [[nodiscard]] constexpr auto erf(integral auto arg) noexcept -> double { - return etl::detail::gcem::erf(double(arg)); + return etl::detail::erf(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/exp.hpp b/include/etl/_cmath/exp.hpp index d5ffd41d9..52c0216e2 100644 --- a/include/etl/_cmath/exp.hpp +++ b/include/etl/_cmath/exp.hpp @@ -64,7 +64,7 @@ inline constexpr struct exp { } [[nodiscard]] constexpr auto exp(integral auto arg) noexcept -> double { - return etl::detail::exp(double(arg)); + return etl::detail::exp(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/floor.hpp b/include/etl/_cmath/floor.hpp index 93180c6d2..9e4d23dbe 100644 --- a/include/etl/_cmath/floor.hpp +++ b/include/etl/_cmath/floor.hpp @@ -64,7 +64,7 @@ inline constexpr struct floor { } [[nodiscard]] constexpr auto floor(integral auto arg) noexcept -> double { - return etl::detail::floor(double(arg)); + return etl::detail::floor(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/fmod.hpp b/include/etl/_cmath/fmod.hpp index 81ac8b0b4..2023eb25f 100644 --- a/include/etl/_cmath/fmod.hpp +++ b/include/etl/_cmath/fmod.hpp @@ -8,6 +8,30 @@ namespace etl { +namespace detail { + +inline constexpr struct fmod { + template + [[nodiscard]] constexpr auto operator()(Float x, Float y) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_fmodf) + if constexpr (etl::same_as) { + return __builtin_fmodf(x, y); + } +#endif +#if __has_builtin(__builtin_fmod) + if constexpr (etl::same_as) { + return __builtin_fmod(x, y); + } +#endif + } + return etl::detail::gcem::fmod(x, y); + } +} fmod; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -15,23 +39,23 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/fmod [[nodiscard]] constexpr auto fmod(float x, float y) noexcept -> float { - return etl::detail::gcem::fmod(x, y); + return etl::detail::fmod(x, y); } [[nodiscard]] constexpr auto fmodf(float x, float y) noexcept -> float { - return etl::detail::gcem::fmod(x, y); + return etl::detail::fmod(x, y); } [[nodiscard]] constexpr auto fmod(double x, double y) noexcept -> double { - return etl::detail::gcem::fmod(x, y); + return etl::detail::fmod(x, y); } [[nodiscard]] constexpr auto fmod(long double x, long double y) noexcept -> long double { - return etl::detail::gcem::fmod(x, y); + return etl::detail::fmod(x, y); } [[nodiscard]] constexpr auto fmodl(long double x, long double y) noexcept -> long double { - return etl::detail::gcem::fmod(x, y); + return etl::detail::fmod(x, y); } /// @} diff --git a/include/etl/_cmath/lgamma.hpp b/include/etl/_cmath/lgamma.hpp index 9730136ff..b95b6853d 100644 --- a/include/etl/_cmath/lgamma.hpp +++ b/include/etl/_cmath/lgamma.hpp @@ -9,12 +9,36 @@ namespace etl { +namespace detail { + +inline constexpr struct lgamma { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_lgammaf) + if constexpr (etl::same_as) { + return __builtin_lgammaf(arg); + } +#endif +#if __has_builtin(__builtin_lgamma) + if constexpr (etl::same_as) { + return __builtin_lgamma(arg); + } +#endif + } + return etl::detail::gcem::lgamma(arg); + } +} lgamma; + +} // namespace detail + /// Computes the natural logarithm of the absolute value of the gamma function of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/lgamma /// \ingroup cmath [[nodiscard]] constexpr auto lgamma(float arg) noexcept -> float { - return etl::detail::gcem::lgamma(arg); + return etl::detail::lgamma(arg); } /// Computes the natural logarithm of the absolute value of the gamma function of arg. @@ -22,7 +46,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto lgammaf(float arg) noexcept -> float { - return etl::detail::gcem::lgamma(arg); + return etl::detail::lgamma(arg); } /// Computes the natural logarithm of the absolute value of the gamma function of arg. @@ -30,7 +54,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto lgamma(double arg) noexcept -> double { - return etl::detail::gcem::lgamma(arg); + return etl::detail::lgamma(arg); } /// Computes the natural logarithm of the absolute value of the gamma function of arg. @@ -38,7 +62,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto lgamma(long double arg) noexcept -> long double { - return etl::detail::gcem::lgamma(arg); + return etl::detail::lgamma(arg); } /// Computes the natural logarithm of the absolute value of the gamma function of arg. @@ -46,7 +70,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto lgammal(long double arg) noexcept -> long double { - return etl::detail::gcem::lgamma(arg); + return etl::detail::lgamma(arg); } /// Computes the natural logarithm of the absolute value of the gamma function of arg. @@ -55,7 +79,7 @@ namespace etl { template [[nodiscard]] constexpr auto lgamma(T arg) noexcept -> double { - return etl::detail::gcem::lgamma(static_cast(arg)); + return etl::detail::lgamma(static_cast(arg)); } } // namespace etl diff --git a/include/etl/_cmath/log.hpp b/include/etl/_cmath/log.hpp index 6310a6adc..eb5d3da85 100644 --- a/include/etl/_cmath/log.hpp +++ b/include/etl/_cmath/log.hpp @@ -64,7 +64,7 @@ inline constexpr struct log { } [[nodiscard]] constexpr auto log(integral auto arg) noexcept -> double { - return etl::detail::log(double(arg)); + return etl::detail::log(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/log10.hpp b/include/etl/_cmath/log10.hpp index 00b729d54..f3dfd8a1d 100644 --- a/include/etl/_cmath/log10.hpp +++ b/include/etl/_cmath/log10.hpp @@ -48,7 +48,7 @@ inline constexpr struct log10 { } [[nodiscard]] constexpr auto log10f(float arg) noexcept -> float { - return etl::log10(arg); + return etl::detail::log10(arg); } [[nodiscard]] constexpr auto log10(double arg) noexcept -> double { @@ -64,7 +64,7 @@ inline constexpr struct log10 { } [[nodiscard]] constexpr auto log10(integral auto arg) noexcept -> double { - return etl::detail::log10(double(arg)); + return etl::detail::log10(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/log1p.hpp b/include/etl/_cmath/log1p.hpp index 9e4abcd6d..2ca5ccc31 100644 --- a/include/etl/_cmath/log1p.hpp +++ b/include/etl/_cmath/log1p.hpp @@ -9,6 +9,30 @@ namespace etl { +namespace detail { + +inline constexpr struct log1p { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_log1pf) + if constexpr (etl::same_as) { + return __builtin_log1pf(arg); + } +#endif +#if __has_builtin(__builtin_log1p) + if constexpr (etl::same_as) { + return __builtin_log1p(arg); + } +#endif + } + return etl::detail::gcem::log1p(arg); + } +} log1p; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -17,27 +41,27 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/log1p [[nodiscard]] constexpr auto log1p(float v) noexcept -> float { - return etl::detail::gcem::log1p(v); + return etl::detail::log1p(v); } [[nodiscard]] constexpr auto log1pf(float v) noexcept -> float { - return etl::detail::gcem::log1p(v); + return etl::detail::log1p(v); } [[nodiscard]] constexpr auto log1p(double v) noexcept -> double { - return etl::detail::gcem::log1p(v); + return etl::detail::log1p(v); } [[nodiscard]] constexpr auto log1p(long double v) noexcept -> long double { - return etl::detail::gcem::log1p(v); + return etl::detail::log1p(v); } [[nodiscard]] constexpr auto log1pl(long double v) noexcept -> long double { - return etl::detail::gcem::log1p(v); + return etl::detail::log1p(v); } [[nodiscard]] constexpr auto log1p(integral auto arg) noexcept -> double { - return etl::detail::gcem::log1p(double(arg)); + return etl::detail::log1p(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/log2.hpp b/include/etl/_cmath/log2.hpp index 763ce58ff..a964c0344 100644 --- a/include/etl/_cmath/log2.hpp +++ b/include/etl/_cmath/log2.hpp @@ -64,7 +64,7 @@ inline constexpr struct log2 { } [[nodiscard]] constexpr auto log2(integral auto arg) noexcept -> double { - return etl::detail::log2(double(arg)); + return etl::detail::log2(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/remainder.hpp b/include/etl/_cmath/remainder.hpp index b00515bde..57c9c9bd4 100644 --- a/include/etl/_cmath/remainder.hpp +++ b/include/etl/_cmath/remainder.hpp @@ -5,15 +5,40 @@ #define TETL_CMATH_REMAINDER_HPP #include +#include namespace etl { +namespace detail { + +inline constexpr struct remainder { + template + [[nodiscard]] constexpr auto operator()(Float x, Float y) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_remainderf) + if constexpr (etl::same_as) { + return __builtin_remainderf(x, y); + } +#endif +#if __has_builtin(__builtin_remainder) + if constexpr (etl::same_as) { + return __builtin_remainder(x, y); + } +#endif + } + return etl::detail::gcem::fmod(x, y); + } +} remainder; + +} // namespace detail + /// Computes the remainder of the floating point division operation x/y. /// \details https://en.cppreference.com/w/cpp/numeric/math/remainder /// \ingroup cmath [[nodiscard]] constexpr auto remainder(float x, float y) noexcept -> float { - return etl::detail::gcem::fmod(x, y); + return etl::detail::remainder(x, y); } /// Computes the remainder of the floating point division operation x/y. @@ -21,7 +46,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto remainderf(float x, float y) noexcept -> float { - return etl::detail::gcem::fmod(x, y); + return etl::detail::remainder(x, y); } /// Computes the remainder of the floating point division operation x/y. @@ -29,7 +54,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto remainder(double x, double y) noexcept -> double { - return etl::detail::gcem::fmod(x, y); + return etl::detail::remainder(x, y); } /// Computes the remainder of the floating point division operation x/y. @@ -37,7 +62,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto remainder(long double x, long double y) noexcept -> long double { - return etl::detail::gcem::fmod(x, y); + return etl::detail::remainder(x, y); } /// Computes the remainder of the floating point division operation x/y. @@ -45,7 +70,16 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto remainderl(long double x, long double y) noexcept -> long double { - return etl::detail::gcem::fmod(x, y); + return etl::detail::remainder(x, y); +} + +/// Computes the remainder of the floating point division operation x/y. +/// \details https://en.cppreference.com/w/cpp/numeric/math/remainder +/// \ingroup cmath +template +[[nodiscard]] constexpr auto remainder(Int x, Int y) noexcept -> double +{ + return etl::detail::remainder(static_cast(x), static_cast(y)); } } // namespace etl diff --git a/include/etl/_cmath/round.hpp b/include/etl/_cmath/round.hpp index c27cb34d7..42f8e135b 100644 --- a/include/etl/_cmath/round.hpp +++ b/include/etl/_cmath/round.hpp @@ -15,23 +15,25 @@ namespace etl { namespace detail { -template -[[nodiscard]] constexpr auto round(T arg) noexcept -> T -{ - if (not is_constant_evaluated()) { - if constexpr (is_same_v) { +inline constexpr struct round { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { + if (not is_constant_evaluated()) { #if __has_builtin(__builtin_roundf) - return __builtin_roundf(arg); + if constexpr (etl::same_as) { + return __builtin_roundf(arg); + } #endif - } - if constexpr (is_same_v) { #if __has_builtin(__builtin_round) - return __builtin_round(arg); + if constexpr (etl::same_as) { + return __builtin_round(arg); + } #endif } + return etl::detail::gcem::round(arg); } - return detail::gcem::round(arg); -} +} round; } // namespace detail @@ -65,7 +67,7 @@ template } [[nodiscard]] constexpr auto round(integral auto arg) noexcept -> double { - return etl::detail::round(double(arg)); + return etl::detail::round(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/sin.hpp b/include/etl/_cmath/sin.hpp index cf9d4e7bf..45fd66b94 100644 --- a/include/etl/_cmath/sin.hpp +++ b/include/etl/_cmath/sin.hpp @@ -64,7 +64,7 @@ inline constexpr struct sin { } [[nodiscard]] constexpr auto sin(integral auto arg) noexcept -> double { - return etl::detail::sin(double(arg)); + return etl::detail::sin(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/sinh.hpp b/include/etl/_cmath/sinh.hpp index 6d6e993ec..2c4c45573 100644 --- a/include/etl/_cmath/sinh.hpp +++ b/include/etl/_cmath/sinh.hpp @@ -9,12 +9,36 @@ namespace etl { +namespace detail { + +inline constexpr struct sinh { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_sinhf) + if constexpr (etl::same_as) { + return __builtin_sinhf(arg); + } +#endif +#if __has_builtin(__builtin_sinh) + if constexpr (etl::same_as) { + return __builtin_sinh(arg); + } +#endif + } + return etl::detail::gcem::sinh(arg); + } +} sinh; + +} // namespace detail + /// Computes the hyperbolic sine of arg /// \details https://en.cppreference.com/w/cpp/numeric/math/sinh /// \ingroup cmath [[nodiscard]] constexpr auto sinh(float arg) noexcept -> float { - return etl::detail::gcem::sinh(arg); + return etl::detail::sinh(arg); } /// Computes the hyperbolic sine of arg @@ -22,7 +46,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto sinhf(float arg) noexcept -> float { - return etl::detail::gcem::sinh(arg); + return etl::detail::sinh(arg); } /// Computes the hyperbolic sine of arg @@ -30,7 +54,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto sinh(double arg) noexcept -> double { - return etl::detail::gcem::sinh(arg); + return etl::detail::sinh(arg); } /// Computes the hyperbolic sine of arg @@ -38,7 +62,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto sinh(long double arg) noexcept -> long double { - return etl::detail::gcem::sinh(arg); + return etl::detail::sinh(arg); } /// Computes the hyperbolic sine of arg @@ -46,7 +70,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto sinhl(long double arg) noexcept -> long double { - return etl::detail::gcem::sinh(arg); + return etl::detail::sinh(arg); } /// Computes the hyperbolic sine of arg @@ -55,7 +79,7 @@ namespace etl { template [[nodiscard]] constexpr auto sinh(T arg) noexcept -> double { - return etl::detail::gcem::sinh(static_cast(arg)); + return etl::detail::sinh(static_cast(arg)); } } // namespace etl diff --git a/include/etl/_cmath/sqrt.hpp b/include/etl/_cmath/sqrt.hpp index 8a2641090..3efa0f366 100644 --- a/include/etl/_cmath/sqrt.hpp +++ b/include/etl/_cmath/sqrt.hpp @@ -9,12 +9,36 @@ namespace etl { +namespace detail { + +inline constexpr struct sqrt { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_sqrtf) + if constexpr (etl::same_as) { + return __builtin_sqrtf(arg); + } +#endif +#if __has_builtin(__builtin_sqrt) + if constexpr (etl::same_as) { + return __builtin_sqrt(arg); + } +#endif + } + return etl::detail::gcem::sqrt(arg); + } +} sqrt; + +} // namespace detail + /// Computes the square root of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/sqrt /// \ingroup cmath [[nodiscard]] constexpr auto sqrt(float arg) noexcept -> float { - return etl::detail::gcem::sqrt(arg); + return etl::detail::sqrt(arg); } /// Computes the square root of arg. @@ -22,7 +46,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto sqrtf(float arg) noexcept -> float { - return etl::detail::gcem::sqrt(arg); + return etl::detail::sqrt(arg); } /// Computes the square root of arg. @@ -30,7 +54,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto sqrt(double arg) noexcept -> double { - return etl::detail::gcem::sqrt(arg); + return etl::detail::sqrt(arg); } /// Computes the square root of arg. @@ -38,7 +62,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto sqrt(long double arg) noexcept -> long double { - return etl::detail::gcem::sqrt(arg); + return etl::detail::sqrt(arg); } /// Computes the square root of arg. @@ -46,7 +70,7 @@ namespace etl { /// \ingroup cmath [[nodiscard]] constexpr auto sqrtl(long double arg) noexcept -> long double { - return etl::detail::gcem::sqrt(arg); + return etl::detail::sqrt(arg); } /// Computes the square root of arg. @@ -55,7 +79,7 @@ namespace etl { template [[nodiscard]] constexpr auto sqrt(T arg) noexcept -> double { - return etl::detail::gcem::sqrt(static_cast(arg)); + return etl::detail::sqrt(static_cast(arg)); } } // namespace etl diff --git a/include/etl/_cmath/tan.hpp b/include/etl/_cmath/tan.hpp index 88a8ed37f..dad843a75 100644 --- a/include/etl/_cmath/tan.hpp +++ b/include/etl/_cmath/tan.hpp @@ -64,7 +64,7 @@ inline constexpr struct tan { } [[nodiscard]] constexpr auto tan(integral auto arg) noexcept -> double { - return etl::detail::tan(double(arg)); + return etl::detail::tan(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/tanh.hpp b/include/etl/_cmath/tanh.hpp index ab4d99a4c..869686069 100644 --- a/include/etl/_cmath/tanh.hpp +++ b/include/etl/_cmath/tanh.hpp @@ -64,7 +64,7 @@ inline constexpr struct tanh { } [[nodiscard]] constexpr auto tanh(integral auto arg) noexcept -> double { - return etl::detail::tanh(double(arg)); + return etl::detail::tanh(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/tgamma.hpp b/include/etl/_cmath/tgamma.hpp index b63166c22..c15f4dead 100644 --- a/include/etl/_cmath/tgamma.hpp +++ b/include/etl/_cmath/tgamma.hpp @@ -9,6 +9,30 @@ namespace etl { +namespace detail { + +inline constexpr struct tgamma { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_tgammaf) + if constexpr (etl::same_as) { + return __builtin_tgammaf(arg); + } +#endif +#if __has_builtin(__builtin_tgamma) + if constexpr (etl::same_as) { + return __builtin_tgamma(arg); + } +#endif + } + return etl::detail::gcem::tgamma(arg); + } +} tgamma; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -16,27 +40,27 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/tgamma [[nodiscard]] constexpr auto tgamma(float arg) noexcept -> float { - return etl::detail::gcem::tgamma(arg); + return etl::detail::tgamma(arg); } [[nodiscard]] constexpr auto tgammaf(float arg) noexcept -> float { - return etl::detail::gcem::tgamma(arg); + return etl::detail::tgamma(arg); } [[nodiscard]] constexpr auto tgamma(double arg) noexcept -> double { - return etl::detail::gcem::tgamma(arg); + return etl::detail::tgamma(arg); } [[nodiscard]] constexpr auto tgamma(long double arg) noexcept -> long double { - return etl::detail::gcem::tgamma(arg); + return etl::detail::tgamma(arg); } [[nodiscard]] constexpr auto tgammal(long double arg) noexcept -> long double { - return etl::detail::gcem::tgamma(arg); + return etl::detail::tgamma(arg); } [[nodiscard]] constexpr auto tgamma(integral auto arg) noexcept -> double { - return etl::tgamma(double(arg)); + return etl::detail::tgamma(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/trunc.hpp b/include/etl/_cmath/trunc.hpp index 9e42beb66..a05511f30 100644 --- a/include/etl/_cmath/trunc.hpp +++ b/include/etl/_cmath/trunc.hpp @@ -62,7 +62,7 @@ template } [[nodiscard]] constexpr auto trunc(integral auto arg) noexcept -> double { - return detail::trunc(double(arg)); + return detail::trunc(static_cast(arg)); } /// @} From b3cf576be26fabf73014a3085a8b408b6b3932aa Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Mon, 8 Sep 2025 22:05:16 +0200 Subject: [PATCH 07/34] [linalg] Add BLAS1 dot --- include/etl/_linalg/blas1_dot.hpp | 37 ++++++++++++++ include/etl/linalg.hpp | 1 + src/inc/linalg.inc | 3 ++ tests/linalg/CMakeLists.txt | 1 + tests/linalg/blas1_dot.t.cpp | 84 +++++++++++++++++++++++++++++++ 5 files changed, 126 insertions(+) create mode 100644 include/etl/_linalg/blas1_dot.hpp create mode 100644 tests/linalg/blas1_dot.t.cpp diff --git a/include/etl/_linalg/blas1_dot.hpp b/include/etl/_linalg/blas1_dot.hpp new file mode 100644 index 000000000..60a6626ee --- /dev/null +++ b/include/etl/_linalg/blas1_dot.hpp @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: BSL-1.0 +// SPDX-FileCopyrightText: Copyright (C) 2025 Tobias Hienzsch +#ifndef TETL_LINALG_BLAS1_DOT_HPP +#define TETL_LINALG_BLAS1_DOT_HPP + +#include +#include +#include +#include + +namespace etl::linalg { + +/// \ingroup linalg +template +[[nodiscard]] constexpr auto dot(InVec1 v1, InVec2 v2, Scalar init) -> Scalar +{ + static_assert(detail::compatible_static_extents(0, 0)); + TETL_PRECONDITION(etl::cmp_equal(v1.extent(0), v2.extent(0))); + + using index_type = detail::common_index_type_t; + for (index_type i{0}; i < static_cast(v1.extent(0)); ++i) { + init += static_cast(v1(i)) * static_cast(v2(i)); + } + return init; +} + +/// \ingroup linalg +template +[[nodiscard]] constexpr auto dot(InVec1 v1, InVec2 v2) +{ + using scalar_type = decltype(declval() * declval()); + return etl::linalg::dot(v1, v2, scalar_type{}); +} + +} // namespace etl::linalg + +#endif // TETL_LINALG_BLAS1_DOT_HPP diff --git a/include/etl/linalg.hpp b/include/etl/linalg.hpp index ec75b9649..42ea1699e 100644 --- a/include/etl/linalg.hpp +++ b/include/etl/linalg.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/src/inc/linalg.inc b/src/inc/linalg.inc index 26942ef1e..3767868df 100644 --- a/src/inc/linalg.inc +++ b/src/inc/linalg.inc @@ -4,6 +4,7 @@ export namespace etl { namespace linalg { + using etl::linalg::accessor_conjugate; using etl::linalg::accessor_scaled; using etl::linalg::add; @@ -11,6 +12,7 @@ using etl::linalg::column_major; using etl::linalg::column_major_t; using etl::linalg::conjugated; using etl::linalg::copy; +using etl::linalg::dot; using etl::linalg::explicit_diagonal; using etl::linalg::explicit_diagonal_t; using etl::linalg::idx_abs_max; @@ -20,6 +22,7 @@ using etl::linalg::layout_transpose; using etl::linalg::lower_triangle; using etl::linalg::lower_triangle_t; using etl::linalg::matrix_frob_norm; +using etl::linalg::matrix_product; using etl::linalg::matrix_vector_product; using etl::linalg::row_major; using etl::linalg::row_major_t; diff --git a/tests/linalg/CMakeLists.txt b/tests/linalg/CMakeLists.txt index 0e276e297..26fec4ce2 100644 --- a/tests/linalg/CMakeLists.txt +++ b/tests/linalg/CMakeLists.txt @@ -4,6 +4,7 @@ project(linalg) tetl_add_test(${PROJECT_NAME} blas1_add) tetl_add_test(${PROJECT_NAME} blas1_copy) +tetl_add_test(${PROJECT_NAME} blas1_dot) tetl_add_test(${PROJECT_NAME} blas1_matrix_frob_norm) tetl_add_test(${PROJECT_NAME} blas1_scale) tetl_add_test(${PROJECT_NAME} blas1_scaled) diff --git a/tests/linalg/blas1_dot.t.cpp b/tests/linalg/blas1_dot.t.cpp new file mode 100644 index 000000000..7ac0965c2 --- /dev/null +++ b/tests/linalg/blas1_dot.t.cpp @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: BSL-1.0 +// SPDX-FileCopyrightText: Copyright (C) 2025 Tobias Hienzsch + +#include "testing/approx.hpp" +#include "testing/testing.hpp" + +#if defined(TETL_ENABLE_CXX_MODULES) +import etl; +#else + #include + #include + #include + #include +#endif + +template +[[nodiscard]] static constexpr auto test_dot() -> bool +{ + { + auto lBuf = etl::array{T(1), T(3), T(5)}; + auto lhs = etl::mdspan>{lBuf.data()}; + + auto rBuf = etl::array{T(4), T(2), T(1)}; + auto rhs = etl::mdspan>{rBuf.data()}; + + { + auto const dot = etl::linalg::dot(lhs, rhs, T{0}); + CHECK_SAME_TYPE(decltype(dot), T const); + CHECK(dot == T{15}); + } + + { + auto const dot = etl::linalg::dot(lhs, rhs); + CHECK_SAME_TYPE(decltype(dot), etl::add_const_t); + CHECK(dot == T{15}); + } + } + + return true; +} + +template +[[nodiscard]] static constexpr auto test_index_type() -> bool +{ + CHECK(test_dot()); + CHECK(test_dot()); + CHECK(test_dot()); + CHECK(test_dot()); + CHECK(test_dot()); + + CHECK(test_dot()); + CHECK(test_dot()); + CHECK(test_dot()); + CHECK(test_dot()); + CHECK(test_dot()); + + CHECK(test_dot()); + CHECK(test_dot()); + + return true; +} + +[[nodiscard]] static constexpr auto test_all() -> bool +{ + CHECK(test_index_type()); + CHECK(test_index_type()); + CHECK(test_index_type()); + CHECK(test_index_type()); + CHECK(test_index_type()); + + CHECK(test_index_type()); + CHECK(test_index_type()); + CHECK(test_index_type()); + CHECK(test_index_type()); + CHECK(test_index_type()); + + return true; +} + +auto main() -> int +{ + STATIC_CHECK(test_all()); + return EXIT_SUCCESS; +} From fc54c0676413e034a101e95ab966968632f842bc Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 9 Sep 2025 01:23:48 +0200 Subject: [PATCH 08/34] [mpl] Add doxygen group tags --- include/etl/_mpl/at.hpp | 5 +++++ include/etl/_mpl/contains.hpp | 5 +++++ include/etl/_mpl/count.hpp | 5 +++++ include/etl/_mpl/head.hpp | 5 +++++ include/etl/_mpl/index_of.hpp | 5 +++++ include/etl/_mpl/push_back.hpp | 6 ++++-- include/etl/_mpl/push_front.hpp | 5 +++++ include/etl/_mpl/tail.hpp | 5 +++++ 8 files changed, 39 insertions(+), 2 deletions(-) diff --git a/include/etl/_mpl/at.hpp b/include/etl/_mpl/at.hpp index 93d9c76cf..284e66866 100644 --- a/include/etl/_mpl/at.hpp +++ b/include/etl/_mpl/at.hpp @@ -9,6 +9,9 @@ namespace etl::mpl { +/// \ingroup mpl +/// @{ + template struct at; @@ -25,6 +28,8 @@ struct at> { template using at_t = typename at::type; +/// @} + } // namespace etl::mpl #endif // TETL_MPL_AT_HPP diff --git a/include/etl/_mpl/contains.hpp b/include/etl/_mpl/contains.hpp index 45a1448c4..f363df6a0 100644 --- a/include/etl/_mpl/contains.hpp +++ b/include/etl/_mpl/contains.hpp @@ -10,6 +10,9 @@ namespace etl::mpl { +/// \ingroup mpl +/// @{ + template struct contains; @@ -19,6 +22,8 @@ struct contains> : etl::bool_constant<(etl::is_same_v inline constexpr auto contains_v = contains::value; +/// @} + } // namespace etl::mpl #endif // TETL_MPL_CONTAINS_HPP diff --git a/include/etl/_mpl/count.hpp b/include/etl/_mpl/count.hpp index 1c7448765..c637589b6 100644 --- a/include/etl/_mpl/count.hpp +++ b/include/etl/_mpl/count.hpp @@ -11,6 +11,9 @@ namespace etl::mpl { +/// \ingroup mpl +/// @{ + template struct count; @@ -20,6 +23,8 @@ struct count> : etl::integral_constant inline constexpr auto count_v = count::value; +/// @} + } // namespace etl::mpl #endif // TETL_MPL_COUNT_HPP diff --git a/include/etl/_mpl/head.hpp b/include/etl/_mpl/head.hpp index 1cd1f0bac..bb07f19c8 100644 --- a/include/etl/_mpl/head.hpp +++ b/include/etl/_mpl/head.hpp @@ -8,6 +8,9 @@ namespace etl::mpl { +/// \ingroup mpl +/// @{ + template struct head; @@ -19,6 +22,8 @@ struct head> { template using head_t = typename head::type; +/// @} + } // namespace etl::mpl #endif // TETL_MPL_HEAD_HPP diff --git a/include/etl/_mpl/index_of.hpp b/include/etl/_mpl/index_of.hpp index 1bc1e225a..3b5f2f827 100644 --- a/include/etl/_mpl/index_of.hpp +++ b/include/etl/_mpl/index_of.hpp @@ -10,6 +10,9 @@ namespace etl::mpl { +/// \ingroup mpl +/// @{ + template struct index_of; @@ -22,6 +25,8 @@ struct index_of> : etl::integral_constant struct index_of> : etl::integral_constant> + 1> { }; +/// @} + } // namespace etl::mpl #endif // TETL_MPL_INDEX_OF_HPP diff --git a/include/etl/_mpl/push_back.hpp b/include/etl/_mpl/push_back.hpp index 0af3bb694..cfc0233a4 100644 --- a/include/etl/_mpl/push_back.hpp +++ b/include/etl/_mpl/push_back.hpp @@ -9,19 +9,21 @@ namespace etl::mpl { /// \ingroup mpl +/// @{ + template struct push_back; -/// \ingroup mpl template struct push_back> { using type = list; }; -/// \ingroup mpl template using push_back_t = typename push_back::type; +/// @} + } // namespace etl::mpl #endif // TETL_MPL_PUSH_BACK_HPP diff --git a/include/etl/_mpl/push_front.hpp b/include/etl/_mpl/push_front.hpp index 12e6452c3..4ee66c3af 100644 --- a/include/etl/_mpl/push_front.hpp +++ b/include/etl/_mpl/push_front.hpp @@ -8,6 +8,9 @@ namespace etl::mpl { +/// \ingroup mpl +/// @{ + template struct push_front; @@ -19,6 +22,8 @@ struct push_front> { template using push_front_t = typename push_front::type; +/// @} + } // namespace etl::mpl #endif // TETL_MPL_PUSH_FRONT_HPP diff --git a/include/etl/_mpl/tail.hpp b/include/etl/_mpl/tail.hpp index 3ce22f2b9..f6cf26210 100644 --- a/include/etl/_mpl/tail.hpp +++ b/include/etl/_mpl/tail.hpp @@ -8,6 +8,9 @@ namespace etl::mpl { +/// \ingroup mpl +/// @{ + template struct tail; @@ -19,6 +22,8 @@ struct tail> { template using tail_t = typename tail::type; +/// @} + } // namespace etl::mpl #endif // TETL_MPL_TAIL_HPP From cdf1d93d29cc2ef61d206f0a17e06da18457cb42 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 9 Sep 2025 01:24:19 +0200 Subject: [PATCH 09/34] [cmath] Add doxygen group tags --- include/etl/_cmath/isfinite.hpp | 8 +++++--- include/etl/_cmath/isinf.hpp | 9 +++++---- include/etl/_cmath/isnan.hpp | 9 +++++---- include/etl/_cmath/lgamma.hpp | 11 +++++------ include/etl/_cmath/lrint.hpp | 17 +++++------------ include/etl/_cmath/pow.hpp | 13 +++++-------- include/etl/_cmath/remainder.hpp | 11 +++++------ include/etl/_cmath/rint.hpp | 11 +++++------ include/etl/_cmath/signbit.hpp | 11 +++++------ include/etl/_cmath/sinh.hpp | 11 +++++------ include/etl/_cmath/sqrt.hpp | 11 +++++------ include/etl/_cmath/typedefs.hpp | 5 +++++ 12 files changed, 60 insertions(+), 67 deletions(-) diff --git a/include/etl/_cmath/isfinite.hpp b/include/etl/_cmath/isfinite.hpp index ce0b68139..9e74f0b93 100644 --- a/include/etl/_cmath/isfinite.hpp +++ b/include/etl/_cmath/isfinite.hpp @@ -9,27 +9,29 @@ namespace etl { +/// \ingroup cmath +/// @{ + /// Determines if the given floating point number arg has finite value /// i.e. it is normal, subnormal or zero, but not infinite or NaN. /// \details https://en.cppreference.com/w/cpp/numeric/math/isfinite -/// \ingroup cmath [[nodiscard]] constexpr auto isfinite(float arg) -> bool { return not etl::isnan(arg) and not etl::isinf(arg); } -/// \ingroup cmath [[nodiscard]] constexpr auto isfinite(double arg) -> bool { return not etl::isnan(arg) and not etl::isinf(arg); } -/// \ingroup cmath [[nodiscard]] constexpr auto isfinite(long double arg) -> bool { return not etl::isnan(arg) and not etl::isinf(arg); } +/// @} + } // namespace etl #endif // TETL_CMATH_ISFINITE_HPP diff --git a/include/etl/_cmath/isinf.hpp b/include/etl/_cmath/isinf.hpp index 1de903c94..1e800e935 100644 --- a/include/etl/_cmath/isinf.hpp +++ b/include/etl/_cmath/isinf.hpp @@ -28,33 +28,34 @@ inline constexpr struct isinf { } // namespace detail +/// \ingroup cmath +/// @{ + /// Determines if the given floating point number arg is a positive or negative infinity. /// \details https://en.cppreference.com/w/cpp/numeric/math/isinf -/// \ingroup cmath [[nodiscard]] constexpr auto isinf(float arg) -> bool { return etl::detail::isinf(arg); } -/// \ingroup cmath [[nodiscard]] constexpr auto isinf(double arg) -> bool { return etl::detail::isinf(arg); } -/// \ingroup cmath [[nodiscard]] constexpr auto isinf(long double arg) -> bool { return etl::detail::isinf(arg); } -/// \ingroup cmath template [[nodiscard]] constexpr auto isinf(Int arg) -> bool { return etl::detail::isinf(static_cast(arg)); } +/// @} + } // namespace etl #endif // TETL_CMATH_ISINF_HPP diff --git a/include/etl/_cmath/isnan.hpp b/include/etl/_cmath/isnan.hpp index d832a804a..e20607ff8 100644 --- a/include/etl/_cmath/isnan.hpp +++ b/include/etl/_cmath/isnan.hpp @@ -11,9 +11,11 @@ namespace etl { +/// \ingroup cmath +/// @{ + /// Determines if the given floating point number arg is a not-a-number (NaN) value. /// \details https://en.cppreference.com/w/cpp/numeric/math/isnan -/// \ingroup cmath [[nodiscard]] constexpr auto isnan(float arg) -> bool { #if __has_builtin(__builtin_isnanf) or defined(TETL_COMPILER_GCC) @@ -23,7 +25,6 @@ namespace etl { #endif } -/// \ingroup cmath [[nodiscard]] constexpr auto isnan(double arg) -> bool { #if __has_builtin(__builtin_isnan) or defined(TETL_COMPILER_GCC) @@ -33,7 +34,6 @@ namespace etl { #endif } -/// \ingroup cmath [[nodiscard]] constexpr auto isnan(long double arg) -> bool { #if __has_builtin(__builtin_isnanl) or defined(TETL_COMPILER_GCC) @@ -45,13 +45,14 @@ namespace etl { /// Determines if the given floating point number arg is a not-a-number (NaN) value. /// \details https://en.cppreference.com/w/cpp/numeric/math/isnan -/// \ingroup cmath template [[nodiscard]] constexpr auto isnan(Int arg) -> bool { return isnan(static_cast(arg)); } +/// @} + } // namespace etl #endif // TETL_CMATH_ISNAN_HPP diff --git a/include/etl/_cmath/lgamma.hpp b/include/etl/_cmath/lgamma.hpp index b95b6853d..11649d9ea 100644 --- a/include/etl/_cmath/lgamma.hpp +++ b/include/etl/_cmath/lgamma.hpp @@ -33,9 +33,11 @@ inline constexpr struct lgamma { } // namespace detail +/// \ingroup cmath +/// @{ + /// Computes the natural logarithm of the absolute value of the gamma function of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/lgamma -/// \ingroup cmath [[nodiscard]] constexpr auto lgamma(float arg) noexcept -> float { return etl::detail::lgamma(arg); @@ -43,7 +45,6 @@ inline constexpr struct lgamma { /// Computes the natural logarithm of the absolute value of the gamma function of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/lgamma -/// \ingroup cmath [[nodiscard]] constexpr auto lgammaf(float arg) noexcept -> float { return etl::detail::lgamma(arg); @@ -51,7 +52,6 @@ inline constexpr struct lgamma { /// Computes the natural logarithm of the absolute value of the gamma function of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/lgamma -/// \ingroup cmath [[nodiscard]] constexpr auto lgamma(double arg) noexcept -> double { return etl::detail::lgamma(arg); @@ -59,7 +59,6 @@ inline constexpr struct lgamma { /// Computes the natural logarithm of the absolute value of the gamma function of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/lgamma -/// \ingroup cmath [[nodiscard]] constexpr auto lgamma(long double arg) noexcept -> long double { return etl::detail::lgamma(arg); @@ -67,7 +66,6 @@ inline constexpr struct lgamma { /// Computes the natural logarithm of the absolute value of the gamma function of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/lgamma -/// \ingroup cmath [[nodiscard]] constexpr auto lgammal(long double arg) noexcept -> long double { return etl::detail::lgamma(arg); @@ -75,13 +73,14 @@ inline constexpr struct lgamma { /// Computes the natural logarithm of the absolute value of the gamma function of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/lgamma -/// \ingroup cmath template [[nodiscard]] constexpr auto lgamma(T arg) noexcept -> double { return etl::detail::lgamma(static_cast(arg)); } +/// @} + } // namespace etl #endif // TETL_CMATH_LGAMMA_HPP diff --git a/include/etl/_cmath/lrint.hpp b/include/etl/_cmath/lrint.hpp index 73f03f2fa..1aa7e9b8f 100644 --- a/include/etl/_cmath/lrint.hpp +++ b/include/etl/_cmath/lrint.hpp @@ -66,43 +66,40 @@ template } // namespace detail -/// Rounds the floating-point argument arg to an integer value, using the current rounding mode. /// \ingroup cmath +/// @{ + +/// Rounds the floating-point argument arg to an integer value, using the current rounding mode. [[nodiscard]] constexpr auto lrint(float arg) noexcept -> long { return detail::lrint_impl(arg); } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto lrintf(float arg) noexcept -> long { return detail::lrint_impl(arg); } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto lrint(double arg) noexcept -> long { return detail::lrint_impl(arg); } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto lrint(long double arg) noexcept -> long { return detail::lrint_impl(arg); } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto lrintl(long double arg) noexcept -> long { return detail::lrint_impl(arg); } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath template [[nodiscard]] constexpr auto lrint(T arg) noexcept -> long { @@ -110,48 +107,44 @@ template } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto llrint(float arg) noexcept -> long long { return detail::llrint_impl(arg); } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto llrintf(float arg) noexcept -> long long { return detail::llrint_impl(arg); } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto llrint(double arg) noexcept -> long long { return detail::llrint_impl(arg); } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto llrint(long double arg) noexcept -> long long { return detail::llrint_impl(arg); } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto llrintl(long double arg) noexcept -> long long { return detail::llrint_impl(arg); } /// Rounds the floating-point argument arg to an integer value, using the current rounding mode. -/// \ingroup cmath template [[nodiscard]] constexpr auto llrint(T arg) noexcept -> long long { return llrint(static_cast(arg)); } +/// @} + } // namespace etl #endif // TETL_CMATH_LRINT_HPP diff --git a/include/etl/_cmath/pow.hpp b/include/etl/_cmath/pow.hpp index 9ecc0c84a..3b0061388 100644 --- a/include/etl/_cmath/pow.hpp +++ b/include/etl/_cmath/pow.hpp @@ -11,9 +11,11 @@ namespace etl { +/// \ingroup cmath +/// @{ + /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow -/// \ingroup cmath [[nodiscard]] constexpr auto pow(float base, float exp) -> float { if (is_constant_evaluated()) { @@ -32,7 +34,6 @@ namespace etl { /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow -/// \ingroup cmath [[nodiscard]] constexpr auto powf(float base, float exp) -> float { return etl::pow(base, exp); @@ -40,7 +41,6 @@ namespace etl { /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow -/// \ingroup cmath [[nodiscard]] constexpr auto pow(double base, double exp) -> double { if (is_constant_evaluated()) { @@ -59,7 +59,6 @@ namespace etl { /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow -/// \ingroup cmath [[nodiscard]] constexpr auto pow(long double base, long double exp) -> long double { return detail::gcem::pow(base, exp); @@ -67,7 +66,6 @@ namespace etl { /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow -/// \ingroup cmath [[nodiscard]] constexpr auto powl(long double base, long double exp) -> long double { return etl::pow(base, exp); @@ -75,7 +73,6 @@ namespace etl { /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow -/// \ingroup cmath [[nodiscard]] constexpr auto pow(float base, int iexp) -> float { return etl::pow(base, static_cast(iexp)); @@ -83,7 +80,6 @@ namespace etl { /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow -/// \ingroup cmath [[nodiscard]] constexpr auto pow(double base, int iexp) -> double { return etl::pow(base, static_cast(iexp)); @@ -91,12 +87,13 @@ namespace etl { /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow -/// \ingroup cmath [[nodiscard]] constexpr auto pow(long double base, int iexp) -> long double { return etl::pow(base, static_cast(iexp)); } +/// @} + } // namespace etl #endif // TETL_CMATH_POW_HPP diff --git a/include/etl/_cmath/remainder.hpp b/include/etl/_cmath/remainder.hpp index 57c9c9bd4..0da249a8f 100644 --- a/include/etl/_cmath/remainder.hpp +++ b/include/etl/_cmath/remainder.hpp @@ -33,9 +33,11 @@ inline constexpr struct remainder { } // namespace detail +/// \ingroup cmath +/// @{ + /// Computes the remainder of the floating point division operation x/y. /// \details https://en.cppreference.com/w/cpp/numeric/math/remainder -/// \ingroup cmath [[nodiscard]] constexpr auto remainder(float x, float y) noexcept -> float { return etl::detail::remainder(x, y); @@ -43,7 +45,6 @@ inline constexpr struct remainder { /// Computes the remainder of the floating point division operation x/y. /// \details https://en.cppreference.com/w/cpp/numeric/math/remainder -/// \ingroup cmath [[nodiscard]] constexpr auto remainderf(float x, float y) noexcept -> float { return etl::detail::remainder(x, y); @@ -51,7 +52,6 @@ inline constexpr struct remainder { /// Computes the remainder of the floating point division operation x/y. /// \details https://en.cppreference.com/w/cpp/numeric/math/remainder -/// \ingroup cmath [[nodiscard]] constexpr auto remainder(double x, double y) noexcept -> double { return etl::detail::remainder(x, y); @@ -59,7 +59,6 @@ inline constexpr struct remainder { /// Computes the remainder of the floating point division operation x/y. /// \details https://en.cppreference.com/w/cpp/numeric/math/remainder -/// \ingroup cmath [[nodiscard]] constexpr auto remainder(long double x, long double y) noexcept -> long double { return etl::detail::remainder(x, y); @@ -67,7 +66,6 @@ inline constexpr struct remainder { /// Computes the remainder of the floating point division operation x/y. /// \details https://en.cppreference.com/w/cpp/numeric/math/remainder -/// \ingroup cmath [[nodiscard]] constexpr auto remainderl(long double x, long double y) noexcept -> long double { return etl::detail::remainder(x, y); @@ -75,13 +73,14 @@ inline constexpr struct remainder { /// Computes the remainder of the floating point division operation x/y. /// \details https://en.cppreference.com/w/cpp/numeric/math/remainder -/// \ingroup cmath template [[nodiscard]] constexpr auto remainder(Int x, Int y) noexcept -> double { return etl::detail::remainder(static_cast(x), static_cast(y)); } +/// @} + } // namespace etl #endif // TETL_CMATH_REMAINDER_HPP diff --git a/include/etl/_cmath/rint.hpp b/include/etl/_cmath/rint.hpp index eb816df40..d3e9946b3 100644 --- a/include/etl/_cmath/rint.hpp +++ b/include/etl/_cmath/rint.hpp @@ -47,9 +47,11 @@ template } // namespace detail +/// \ingroup cmath +/// @{ + /// Rounds the floating-point argument arg to an integer value /// (in floating-point format), using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto rint(float arg) noexcept -> float { return detail::rint_impl(arg); @@ -57,7 +59,6 @@ template /// Rounds the floating-point argument arg to an integer value /// (in floating-point format), using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto rintf(float arg) noexcept -> float { return detail::rint_impl(arg); @@ -65,7 +66,6 @@ template /// Rounds the floating-point argument arg to an integer value /// (in floating-point format), using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto rint(double arg) noexcept -> double { return detail::rint_impl(arg); @@ -73,7 +73,6 @@ template /// Rounds the floating-point argument arg to an integer value /// (in floating-point format), using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto rint(long double arg) noexcept -> long double { return detail::rint_impl(arg); @@ -81,7 +80,6 @@ template /// Rounds the floating-point argument arg to an integer value /// (in floating-point format), using the current rounding mode. -/// \ingroup cmath [[nodiscard]] constexpr auto rintl(long double arg) noexcept -> long double { return detail::rint_impl(arg); @@ -89,13 +87,14 @@ template /// Rounds the floating-point argument arg to an integer value /// (in floating-point format), using the current rounding mode. -/// \ingroup cmath template [[nodiscard]] constexpr auto rint(T arg) noexcept -> double { return rint(static_cast(arg)); } +/// @} + } // namespace etl #endif // TETL_CMATH_RINT_HPP diff --git a/include/etl/_cmath/signbit.hpp b/include/etl/_cmath/signbit.hpp index b10cb1156..0c12a2bd6 100644 --- a/include/etl/_cmath/signbit.hpp +++ b/include/etl/_cmath/signbit.hpp @@ -20,6 +20,9 @@ template } // namespace detail +/// \ingroup cmath +/// @{ + /// Determines if the given floating point number arg is negative. /// /// This function detects the sign bit of zeroes, infinities, and NaNs. @@ -27,8 +30,6 @@ template /// to examine the sign of a NaN. /// /// https://en.cppreference.com/w/cpp/numeric/math/signbit -/// -/// \ingroup cmath [[nodiscard]] constexpr auto signbit(float arg) noexcept -> bool { if (is_constant_evaluated()) { @@ -48,8 +49,6 @@ template /// to examine the sign of a NaN. /// /// https://en.cppreference.com/w/cpp/numeric/math/signbit -/// -/// \ingroup cmath [[nodiscard]] constexpr auto signbit(double arg) noexcept -> bool { if (is_constant_evaluated()) { @@ -69,8 +68,6 @@ template /// to examine the sign of a NaN. /// /// https://en.cppreference.com/w/cpp/numeric/math/signbit -/// -/// \ingroup cmath [[nodiscard]] constexpr auto signbit(long double arg) noexcept -> bool { if (is_constant_evaluated()) { @@ -83,6 +80,8 @@ template #endif } +/// @} + } // namespace etl #endif // TETL_CMATH_SIGNBIT_HPP diff --git a/include/etl/_cmath/sinh.hpp b/include/etl/_cmath/sinh.hpp index 2c4c45573..669b05baf 100644 --- a/include/etl/_cmath/sinh.hpp +++ b/include/etl/_cmath/sinh.hpp @@ -33,9 +33,11 @@ inline constexpr struct sinh { } // namespace detail +/// \ingroup cmath +/// @{ + /// Computes the hyperbolic sine of arg /// \details https://en.cppreference.com/w/cpp/numeric/math/sinh -/// \ingroup cmath [[nodiscard]] constexpr auto sinh(float arg) noexcept -> float { return etl::detail::sinh(arg); @@ -43,7 +45,6 @@ inline constexpr struct sinh { /// Computes the hyperbolic sine of arg /// \details https://en.cppreference.com/w/cpp/numeric/math/sinh -/// \ingroup cmath [[nodiscard]] constexpr auto sinhf(float arg) noexcept -> float { return etl::detail::sinh(arg); @@ -51,7 +52,6 @@ inline constexpr struct sinh { /// Computes the hyperbolic sine of arg /// \details https://en.cppreference.com/w/cpp/numeric/math/sinh -/// \ingroup cmath [[nodiscard]] constexpr auto sinh(double arg) noexcept -> double { return etl::detail::sinh(arg); @@ -59,7 +59,6 @@ inline constexpr struct sinh { /// Computes the hyperbolic sine of arg /// \details https://en.cppreference.com/w/cpp/numeric/math/sinh -/// \ingroup cmath [[nodiscard]] constexpr auto sinh(long double arg) noexcept -> long double { return etl::detail::sinh(arg); @@ -67,7 +66,6 @@ inline constexpr struct sinh { /// Computes the hyperbolic sine of arg /// \details https://en.cppreference.com/w/cpp/numeric/math/sinh -/// \ingroup cmath [[nodiscard]] constexpr auto sinhl(long double arg) noexcept -> long double { return etl::detail::sinh(arg); @@ -75,13 +73,14 @@ inline constexpr struct sinh { /// Computes the hyperbolic sine of arg /// \details https://en.cppreference.com/w/cpp/numeric/math/sinh -/// \ingroup cmath template [[nodiscard]] constexpr auto sinh(T arg) noexcept -> double { return etl::detail::sinh(static_cast(arg)); } +/// @} + } // namespace etl #endif // TETL_CMATH_SINH_HPP diff --git a/include/etl/_cmath/sqrt.hpp b/include/etl/_cmath/sqrt.hpp index 3efa0f366..943a1f88b 100644 --- a/include/etl/_cmath/sqrt.hpp +++ b/include/etl/_cmath/sqrt.hpp @@ -33,9 +33,11 @@ inline constexpr struct sqrt { } // namespace detail +/// \ingroup cmath +/// @{ + /// Computes the square root of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/sqrt -/// \ingroup cmath [[nodiscard]] constexpr auto sqrt(float arg) noexcept -> float { return etl::detail::sqrt(arg); @@ -43,7 +45,6 @@ inline constexpr struct sqrt { /// Computes the square root of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/sqrt -/// \ingroup cmath [[nodiscard]] constexpr auto sqrtf(float arg) noexcept -> float { return etl::detail::sqrt(arg); @@ -51,7 +52,6 @@ inline constexpr struct sqrt { /// Computes the square root of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/sqrt -/// \ingroup cmath [[nodiscard]] constexpr auto sqrt(double arg) noexcept -> double { return etl::detail::sqrt(arg); @@ -59,7 +59,6 @@ inline constexpr struct sqrt { /// Computes the square root of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/sqrt -/// \ingroup cmath [[nodiscard]] constexpr auto sqrt(long double arg) noexcept -> long double { return etl::detail::sqrt(arg); @@ -67,7 +66,6 @@ inline constexpr struct sqrt { /// Computes the square root of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/sqrt -/// \ingroup cmath [[nodiscard]] constexpr auto sqrtl(long double arg) noexcept -> long double { return etl::detail::sqrt(arg); @@ -75,13 +73,14 @@ inline constexpr struct sqrt { /// Computes the square root of arg. /// \details https://en.cppreference.com/w/cpp/numeric/math/sqrt -/// \ingroup cmath template [[nodiscard]] constexpr auto sqrt(T arg) noexcept -> double { return etl::detail::sqrt(static_cast(arg)); } +/// @} + } // namespace etl #endif // TETL_CMATH_SQRT_HPP diff --git a/include/etl/_cmath/typedefs.hpp b/include/etl/_cmath/typedefs.hpp index 9563fc881..dd38135e0 100644 --- a/include/etl/_cmath/typedefs.hpp +++ b/include/etl/_cmath/typedefs.hpp @@ -6,6 +6,9 @@ #include +/// \ingroup cmath +/// @{ + #if defined(TETL_COMPILER_MSVC) #include #else @@ -30,6 +33,8 @@ #endif #endif +/// @} + namespace etl { /// Most efficient floating-point type at least as wide as float. From b9b921aed9de5033071756cfad4dfef674e1bede Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 9 Sep 2025 08:20:45 +0200 Subject: [PATCH 10/34] [cmath] Use more builtins --- include/etl/_cmath/fdim.hpp | 34 ++++++++++++++++--- include/etl/_cmath/floor.hpp | 2 +- include/etl/_cmath/fmax.hpp | 34 ++++++++++++++++--- include/etl/_cmath/fmin.hpp | 34 ++++++++++++++++--- include/etl/_cmath/isfinite.hpp | 30 +++++++++++++++-- include/etl/_cmath/signbit.hpp | 60 +++++++++++++++++++-------------- include/etl/_cmath/sqrt.hpp | 1 + 7 files changed, 151 insertions(+), 44 deletions(-) diff --git a/include/etl/_cmath/fdim.hpp b/include/etl/_cmath/fdim.hpp index df75e3af8..d1864e98a 100644 --- a/include/etl/_cmath/fdim.hpp +++ b/include/etl/_cmath/fdim.hpp @@ -8,6 +8,30 @@ namespace etl { +namespace detail { + +inline constexpr struct fdim { + template + [[nodiscard]] constexpr auto operator()(Float x, Float y) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_fdimf) + if constexpr (etl::same_as) { + return __builtin_fdimf(x, y); + } +#endif +#if __has_builtin(__builtin_fdim) + if constexpr (etl::same_as) { + return __builtin_fdim(x, y); + } +#endif + } + return etl::fmax(x - y, static_cast(0)); + } +} fdim; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -16,23 +40,23 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/fdim [[nodiscard]] constexpr auto fdim(float x, float y) noexcept -> float { - return etl::fmax(x - y, 0); + return etl::detail::fdim(x, y); } [[nodiscard]] constexpr auto fdimf(float x, float y) noexcept -> float { - return etl::fmax(x - y, 0); + return etl::detail::fdim(x, y); } [[nodiscard]] constexpr auto fdim(double x, double y) noexcept -> double { - return etl::fmax(x - y, 0); + return etl::detail::fdim(x, y); } [[nodiscard]] constexpr auto fdim(long double x, long double y) noexcept -> long double { - return etl::fmax(x - y, 0); + return etl::detail::fdim(x, y); } [[nodiscard]] constexpr auto fdiml(long double x, long double y) noexcept -> long double { - return etl::fmax(x - y, 0); + return etl::detail::fdim(x, y); } /// @} diff --git a/include/etl/_cmath/floor.hpp b/include/etl/_cmath/floor.hpp index 9e4d23dbe..788f2c0a7 100644 --- a/include/etl/_cmath/floor.hpp +++ b/include/etl/_cmath/floor.hpp @@ -56,7 +56,7 @@ inline constexpr struct floor { } [[nodiscard]] constexpr auto floor(long double arg) noexcept -> long double { - return etl::detail::gcem::floor(arg); + return etl::detail::floor(arg); } [[nodiscard]] constexpr auto floorl(long double arg) noexcept -> long double { diff --git a/include/etl/_cmath/fmax.hpp b/include/etl/_cmath/fmax.hpp index bf09eeddd..d52f1ca34 100644 --- a/include/etl/_cmath/fmax.hpp +++ b/include/etl/_cmath/fmax.hpp @@ -8,6 +8,30 @@ namespace etl { +namespace detail { + +inline constexpr struct fmax { + template + [[nodiscard]] constexpr auto operator()(Float x, Float y) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_fmaxf) + if constexpr (etl::same_as) { + return __builtin_fmaxf(x, y); + } +#endif +#if __has_builtin(__builtin_fmax) + if constexpr (etl::same_as) { + return __builtin_fmax(x, y); + } +#endif + } + return etl::detail::gcem::max(x, y); + } +} fmax; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -17,27 +41,27 @@ namespace etl { /// https://en.cppreference.com/w/cpp/numeric/math/fmax [[nodiscard]] constexpr auto fmax(float x, float y) noexcept -> float { - return etl::detail::gcem::max(x, y); + return etl::detail::fmax(x, y); } [[nodiscard]] constexpr auto fmaxf(float x, float y) noexcept -> float { - return etl::detail::gcem::max(x, y); + return etl::detail::fmax(x, y); } [[nodiscard]] constexpr auto fmax(double x, double y) noexcept -> double { - return etl::detail::gcem::max(x, y); + return etl::detail::fmax(x, y); } [[nodiscard]] constexpr auto fmax(long double x, long double y) noexcept -> long double { - return etl::detail::gcem::max(x, y); + return etl::detail::fmax(x, y); } [[nodiscard]] constexpr auto fmaxl(long double x, long double y) noexcept -> long double { - return etl::detail::gcem::max(x, y); + return etl::detail::fmax(x, y); } /// @} diff --git a/include/etl/_cmath/fmin.hpp b/include/etl/_cmath/fmin.hpp index 271a4ca85..ea2df3975 100644 --- a/include/etl/_cmath/fmin.hpp +++ b/include/etl/_cmath/fmin.hpp @@ -8,6 +8,30 @@ namespace etl { +namespace detail { + +inline constexpr struct fmin { + template + [[nodiscard]] constexpr auto operator()(Float x, Float y) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_fminf) + if constexpr (etl::same_as) { + return __builtin_fminf(x, y); + } +#endif +#if __has_builtin(__builtin_fmin) + if constexpr (etl::same_as) { + return __builtin_fmin(x, y); + } +#endif + } + return etl::detail::gcem::min(x, y); + } +} fmin; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -18,27 +42,27 @@ namespace etl { /// https://en.cppreference.com/w/cpp/numeric/math/fmin [[nodiscard]] constexpr auto fmin(float x, float y) noexcept -> float { - return etl::detail::gcem::min(x, y); + return etl::detail::fmin(x, y); } [[nodiscard]] constexpr auto fminf(float x, float y) noexcept -> float { - return etl::detail::gcem::min(x, y); + return etl::detail::fmin(x, y); } [[nodiscard]] constexpr auto fmin(double x, double y) noexcept -> double { - return etl::detail::gcem::min(x, y); + return etl::detail::fmin(x, y); } [[nodiscard]] constexpr auto fmin(long double x, long double y) noexcept -> long double { - return etl::detail::gcem::min(x, y); + return etl::detail::fmin(x, y); } [[nodiscard]] constexpr auto fminl(long double x, long double y) noexcept -> long double { - return etl::detail::gcem::min(x, y); + return etl::detail::fmin(x, y); } /// @} diff --git a/include/etl/_cmath/isfinite.hpp b/include/etl/_cmath/isfinite.hpp index 9e74f0b93..6fbf89f57 100644 --- a/include/etl/_cmath/isfinite.hpp +++ b/include/etl/_cmath/isfinite.hpp @@ -9,6 +9,30 @@ namespace etl { +namespace detail { + +inline constexpr struct isfinite { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> bool + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_isfinitef) + if constexpr (etl::same_as) { + return __builtin_isfinitef(arg); + } +#endif +#if __has_builtin(__builtin_isfinite) + if constexpr (etl::same_as) { + return __builtin_isfinite(arg); + } +#endif + } + return not etl::isnan(arg) and not etl::isinf(arg); + } +} isfinite; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -17,17 +41,17 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/isfinite [[nodiscard]] constexpr auto isfinite(float arg) -> bool { - return not etl::isnan(arg) and not etl::isinf(arg); + return etl::detail::isfinite(arg); } [[nodiscard]] constexpr auto isfinite(double arg) -> bool { - return not etl::isnan(arg) and not etl::isinf(arg); + return etl::detail::isfinite(arg); } [[nodiscard]] constexpr auto isfinite(long double arg) -> bool { - return not etl::isnan(arg) and not etl::isinf(arg); + return etl::detail::isfinite(arg); } /// @} diff --git a/include/etl/_cmath/signbit.hpp b/include/etl/_cmath/signbit.hpp index 0c12a2bd6..363cf667e 100644 --- a/include/etl/_cmath/signbit.hpp +++ b/include/etl/_cmath/signbit.hpp @@ -6,6 +6,7 @@ #include +#include #include namespace etl { @@ -15,7 +16,25 @@ namespace detail { template [[nodiscard]] constexpr auto signbit_fallback(T arg) noexcept -> bool { - return arg == T(-0.0) || arg < T(0); + return arg == T(-0.0) or arg < T(0); +} + +template +[[nodiscard]] constexpr auto signbit(T arg) noexcept -> bool +{ + if (not is_constant_evaluated()) { + if constexpr (is_same_v) { +#if __has_builtin(__builtin_signbitf) + return __builtin_signbitf(arg); +#endif + } + if constexpr (is_same_v) { +#if __has_builtin(__builtin_signbit) + return __builtin_signbit(arg); +#endif + } + } + return signbit_fallback(arg); } } // namespace detail @@ -32,14 +51,7 @@ template /// https://en.cppreference.com/w/cpp/numeric/math/signbit [[nodiscard]] constexpr auto signbit(float arg) noexcept -> bool { - if (is_constant_evaluated()) { - return detail::signbit_fallback(arg); - } -#if __has_builtin(__builtin_signbit) and not defined(TETL_COMPILER_CLANG) - return __builtin_signbit(arg); -#else - return detail::signbit_fallback(arg); -#endif + return etl::detail::signbit(arg); } /// Determines if the given floating point number arg is negative. @@ -51,14 +63,7 @@ template /// https://en.cppreference.com/w/cpp/numeric/math/signbit [[nodiscard]] constexpr auto signbit(double arg) noexcept -> bool { - if (is_constant_evaluated()) { - return detail::signbit_fallback(arg); - } -#if __has_builtin(__builtin_signbit) and not defined(TETL_COMPILER_CLANG) - return __builtin_signbit(arg); -#else - return detail::signbit_fallback(arg); -#endif + return etl::detail::signbit(arg); } /// Determines if the given floating point number arg is negative. @@ -70,14 +75,19 @@ template /// https://en.cppreference.com/w/cpp/numeric/math/signbit [[nodiscard]] constexpr auto signbit(long double arg) noexcept -> bool { - if (is_constant_evaluated()) { - return detail::signbit_fallback(arg); - } -#if __has_builtin(__builtin_signbit) and not defined(TETL_COMPILER_CLANG) - return __builtin_signbit(arg); -#else - return detail::signbit_fallback(arg); -#endif + return etl::detail::signbit(arg); +} + +/// Determines if the given floating point number arg is negative. +/// +/// This function detects the sign bit of zeroes, infinities, and NaNs. +/// Along with etl::copysign, etl::signbit is one of the only two portable ways +/// to examine the sign of a NaN. +/// +/// https://en.cppreference.com/w/cpp/numeric/math/signbit +[[nodiscard]] constexpr auto signbit(integral auto arg) noexcept -> bool +{ + return etl::detail::signbit(static_cast(arg)); } /// @} diff --git a/include/etl/_cmath/sqrt.hpp b/include/etl/_cmath/sqrt.hpp index 943a1f88b..fb9632cd3 100644 --- a/include/etl/_cmath/sqrt.hpp +++ b/include/etl/_cmath/sqrt.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { From 7aea1c283d34a4ebeee84e6a0bff9ebd39ed691e Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 9 Sep 2025 08:56:40 +0200 Subject: [PATCH 11/34] [cmath] Add tests for signbit --- include/etl/_cmath/signbit.hpp | 38 +++++++++++++++++++-------- tests/cmath/CMakeLists.txt | 1 + tests/cmath/signbit.t.cpp | 48 ++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 tests/cmath/signbit.t.cpp diff --git a/include/etl/_cmath/signbit.hpp b/include/etl/_cmath/signbit.hpp index 363cf667e..fcc7e1255 100644 --- a/include/etl/_cmath/signbit.hpp +++ b/include/etl/_cmath/signbit.hpp @@ -6,36 +6,52 @@ #include +#include +#include #include +#include #include namespace etl { namespace detail { -template -[[nodiscard]] constexpr auto signbit_fallback(T arg) noexcept -> bool +template +[[nodiscard]] constexpr auto signbit_fallback(Float arg) noexcept -> bool { - return arg == T(-0.0) or arg < T(0); + if constexpr (sizeof(Float) == 4) { + auto const bits = etl::bit_cast(arg); + return bits < 0; + } else if constexpr (sizeof(Float) == 8) { + auto const bits = etl::bit_cast(arg); + return bits < 0; + } else { + return arg == Float(-0.0) or arg < Float(0); + } } -template -[[nodiscard]] constexpr auto signbit(T arg) noexcept -> bool -{ - if (not is_constant_evaluated()) { - if constexpr (is_same_v) { +inline constexpr struct signbit { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> bool + { + if constexpr (is_same_v) { #if __has_builtin(__builtin_signbitf) return __builtin_signbitf(arg); #endif } - if constexpr (is_same_v) { + if constexpr (is_same_v) { #if __has_builtin(__builtin_signbit) return __builtin_signbit(arg); #endif } + if constexpr (is_same_v) { +#if __has_builtin(__builtin_signbitl) + return __builtin_signbitl(arg); +#endif + } + return signbit_fallback(arg); } - return signbit_fallback(arg); -} +} signbit; } // namespace detail diff --git a/tests/cmath/CMakeLists.txt b/tests/cmath/CMakeLists.txt index 3acffadea..72ed62a08 100644 --- a/tests/cmath/CMakeLists.txt +++ b/tests/cmath/CMakeLists.txt @@ -30,6 +30,7 @@ tetl_add_test(${PROJECT_NAME} log2) tetl_add_test(${PROJECT_NAME} log10) tetl_add_test(${PROJECT_NAME} nextafter) tetl_add_test(${PROJECT_NAME} round) +tetl_add_test(${PROJECT_NAME} signbit) tetl_add_test(${PROJECT_NAME} sin) tetl_add_test(${PROJECT_NAME} tan) tetl_add_test(${PROJECT_NAME} tanh) diff --git a/tests/cmath/signbit.t.cpp b/tests/cmath/signbit.t.cpp new file mode 100644 index 000000000..4a38bc107 --- /dev/null +++ b/tests/cmath/signbit.t.cpp @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: BSL-1.0 +// SPDX-FileCopyrightText: Copyright (C) 2025 Tobias Hienzsch + +#include "testing/testing.hpp" + +#if defined(TETL_ENABLE_CXX_MODULES) +import etl; +#else + #include + #include + #include +#endif + +template +static constexpr auto test(auto signbit) -> bool +{ + using limits = etl::numeric_limits; + + CHECK(signbit(static_cast(-0.0F))); + CHECK(signbit(static_cast(-1.0F))); + CHECK(signbit(-limits::infinity())); + CHECK(signbit(-limits::quiet_NaN())); + + CHECK_FALSE(signbit(static_cast(+0.0F))); + CHECK_FALSE(signbit(static_cast(+1.0F))); + CHECK_FALSE(signbit(+limits::infinity())); + CHECK_FALSE(signbit(+limits::quiet_NaN())); + + return true; +} + +template +static constexpr auto test_type() -> bool +{ + CHECK(test([](auto x) { return etl::signbit(x); })); + if constexpr (not etl::same_as) { + CHECK(test([](auto x) { return etl::detail::signbit_fallback(x); })); + } + return true; +} + +auto main() -> int +{ + STATIC_CHECK(test_type()); + STATIC_CHECK(test_type()); + STATIC_CHECK(test_type()); + return 0; +} From 30ea6e008523cdccc0b2fe522ce9cf88cb50d5a1 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 9 Sep 2025 09:15:30 +0200 Subject: [PATCH 12/34] [cmath] Fix constexpr signbit on clang versions 17 to 19 --- include/etl/_cmath/signbit.hpp | 21 ++++++++++++--------- tests/cmath/signbit.t.cpp | 6 ++---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/include/etl/_cmath/signbit.hpp b/include/etl/_cmath/signbit.hpp index fcc7e1255..d893a2bb7 100644 --- a/include/etl/_cmath/signbit.hpp +++ b/include/etl/_cmath/signbit.hpp @@ -6,6 +6,7 @@ #include +#include #include #include #include @@ -26,7 +27,7 @@ template auto const bits = etl::bit_cast(arg); return bits < 0; } else { - return arg == Float(-0.0) or arg < Float(0); + return etl::detail::gcem::signbit(arg); } } @@ -34,20 +35,22 @@ inline constexpr struct signbit { template [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> bool { - if constexpr (is_same_v) { + if (not is_constant_evaluated()) { + if constexpr (is_same_v) { #if __has_builtin(__builtin_signbitf) - return __builtin_signbitf(arg); + return __builtin_signbitf(arg); #endif - } - if constexpr (is_same_v) { + } + if constexpr (is_same_v) { #if __has_builtin(__builtin_signbit) - return __builtin_signbit(arg); + return __builtin_signbit(arg); #endif - } - if constexpr (is_same_v) { + } + if constexpr (is_same_v) { #if __has_builtin(__builtin_signbitl) - return __builtin_signbitl(arg); + return __builtin_signbitl(arg); #endif + } } return signbit_fallback(arg); } diff --git a/tests/cmath/signbit.t.cpp b/tests/cmath/signbit.t.cpp index 4a38bc107..6c4a026b2 100644 --- a/tests/cmath/signbit.t.cpp +++ b/tests/cmath/signbit.t.cpp @@ -33,9 +33,7 @@ template static constexpr auto test_type() -> bool { CHECK(test([](auto x) { return etl::signbit(x); })); - if constexpr (not etl::same_as) { - CHECK(test([](auto x) { return etl::detail::signbit_fallback(x); })); - } + CHECK(test([](auto x) { return etl::detail::signbit_fallback(x); })); return true; } @@ -43,6 +41,6 @@ auto main() -> int { STATIC_CHECK(test_type()); STATIC_CHECK(test_type()); - STATIC_CHECK(test_type()); + CHECK(test_type()); return 0; } From 8e89b2f81673b1bdf219766d1b1cd31af1beea62 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 9 Sep 2025 23:11:34 +0200 Subject: [PATCH 13/34] Cleanup formatting --- include/etl/_concepts/copyable.hpp | 15 ++++------ include/etl/_expected/unexpected.hpp | 4 +-- include/etl/_format/argument.hpp | 8 ++--- include/etl/_format/basic_format_arg.hpp | 30 +++++++++---------- include/etl/_iterator/iterator_traits.hpp | 16 +++++----- .../etl/_mdspan/integral_constant_like.hpp | 22 ++++++-------- include/etl/_mdspan/layout_stride.hpp | 4 +-- include/etl/_string/basic_inplace_string.hpp | 5 ++-- 8 files changed, 45 insertions(+), 59 deletions(-) diff --git a/include/etl/_concepts/copyable.hpp b/include/etl/_concepts/copyable.hpp index 0739963e6..41583e6f0 100644 --- a/include/etl/_concepts/copyable.hpp +++ b/include/etl/_concepts/copyable.hpp @@ -12,16 +12,11 @@ namespace etl { /// \ingroup concepts template -concept copyable = // - copy_constructible - and // - movable - and // - assignable_from - and // - assignable_from - and // - assignable_from; // +concept copyable = copy_constructible + and movable + and assignable_from + and assignable_from + and assignable_from; } // namespace etl diff --git a/include/etl/_expected/unexpected.hpp b/include/etl/_expected/unexpected.hpp index 5cd5e0a57..beb73cd0f 100644 --- a/include/etl/_expected/unexpected.hpp +++ b/include/etl/_expected/unexpected.hpp @@ -22,8 +22,8 @@ template struct unexpected { template requires( - not etl::is_same_v, unexpected> // - and not etl::is_same_v, etl::in_place_t> // + not etl::is_same_v, unexpected> + and not etl::is_same_v, etl::in_place_t> and etl::is_constructible_v ) constexpr explicit unexpected(Err&& e) noexcept(etl::is_nothrow_constructible_v) diff --git a/include/etl/_format/argument.hpp b/include/etl/_format/argument.hpp index 3a25006f1..5e0fcb87f 100644 --- a/include/etl/_format/argument.hpp +++ b/include/etl/_format/argument.hpp @@ -45,9 +45,7 @@ auto format_escaped_sequences(etl::string_view str, FormatContext& ctx) -> void // Find open sequence {{ auto const* const openFirst = etl::find(first, end(str), token_begin); auto const* const openSec = etl::next(openFirst); - auto const escapeStart = openFirst != end(str) // - && openSec != end(str) // - && *openSec == token_begin; + auto const escapeStart = openFirst != end(str) && openSec != end(str) && *openSec == token_begin; if (escapeStart) { // Copy upto {{ @@ -56,9 +54,7 @@ auto format_escaped_sequences(etl::string_view str, FormatContext& ctx) -> void // Find sequence }} auto const* closeFirst = etl::find(etl::next(openSec), end(str), token_end); auto const* closeSec = etl::next(closeFirst); - auto escapeClose = closeFirst != end(str) // - && closeSec != end(str) // - && *closeSec == token_end; + auto escapeClose = closeFirst != end(str) && closeSec != end(str) && *closeSec == token_end; // Copy everything between {{ ... }}, but only one curly each. if (escapeClose) { diff --git a/include/etl/_format/basic_format_arg.hpp b/include/etl/_format/basic_format_arg.hpp index 4bfba6907..2b1f41769 100644 --- a/include/etl/_format/basic_format_arg.hpp +++ b/include/etl/_format/basic_format_arg.hpp @@ -69,21 +69,21 @@ struct basic_format_arg { template explicit basic_format_arg(T* p) noexcept; - variant< // variant< // monostate, // - bool, // - char_type, // - int, // - unsigned int, // - long long int, // - unsigned long long int, // - float, // - double, // - long double, // - char_type const*, // - basic_string_view, // - void const*, // - handle // - > + variant< + bool, + char_type, + int, + unsigned int, + long long int, + unsigned long long int, + float, + double, + long double, + char_type const*, + basic_string_view, + void const*, + handle + > value{monostate{}}; }; diff --git a/include/etl/_iterator/iterator_traits.hpp b/include/etl/_iterator/iterator_traits.hpp index ae8be0637..405a1e890 100644 --- a/include/etl/_iterator/iterator_traits.hpp +++ b/include/etl/_iterator/iterator_traits.hpp @@ -18,14 +18,14 @@ struct iterator_traits_impl { }; template struct iterator_traits_impl< Iter, - etl::void_t< // - typename Iter::iterator_category, // - typename Iter::value_type, // - typename Iter::difference_type, // - typename Iter::pointer, // - typename Iter::reference // - > // - > { + etl::void_t< + typename Iter::iterator_category, + typename Iter::value_type, + typename Iter::difference_type, + typename Iter::pointer, + typename Iter::reference + > +> { using iterator_category = typename Iter::iterator_category; using value_type = typename Iter::value_type; using difference_type = typename Iter::difference_type; diff --git a/include/etl/_mdspan/integral_constant_like.hpp b/include/etl/_mdspan/integral_constant_like.hpp index fe566f184..6882211e2 100644 --- a/include/etl/_mdspan/integral_constant_like.hpp +++ b/include/etl/_mdspan/integral_constant_like.hpp @@ -19,21 +19,17 @@ template concept pair_like = true; template -concept index_pair_like = // - pair_like // - and etl::convertible_to, IndexType> // - and etl::convertible_to, IndexType> // - ; +concept index_pair_like = pair_like + and etl::convertible_to, IndexType> + and etl::convertible_to, IndexType>; template -concept integral_constant_like = // - etl::is_integral_v // - and not etl::is_same_v> // - and etl::convertible_to // - /* and etl::equality_comparable_with */ // - and etl::bool_constant::value // - and etl::bool_constant(T()) == T::value>::value // - ; +concept integral_constant_like = etl::is_integral_v + and not etl::is_same_v> + and etl::convertible_to + /* and etl::equality_comparable_with */ + and etl::bool_constant::value + and etl::bool_constant(T()) == T::value>::value; template [[nodiscard]] constexpr auto de_ice(T val) -> T diff --git a/include/etl/_mdspan/layout_stride.hpp b/include/etl/_mdspan/layout_stride.hpp index 222968cde..4779759ce 100644 --- a/include/etl/_mdspan/layout_stride.hpp +++ b/include/etl/_mdspan/layout_stride.hpp @@ -75,8 +75,8 @@ struct layout_stride::mapping { template requires( - (sizeof...(Indices) == rank) // - and (is_convertible_v and ...) // + (sizeof...(Indices) == rank) + and (is_convertible_v and ...) and (is_nothrow_constructible_v and ...) ) [[nodiscard]] constexpr auto operator()(Indices... is) const noexcept -> index_type diff --git a/include/etl/_string/basic_inplace_string.hpp b/include/etl/_string/basic_inplace_string.hpp index 6ac3d52b7..273cf7c8e 100644 --- a/include/etl/_string/basic_inplace_string.hpp +++ b/include/etl/_string/basic_inplace_string.hpp @@ -41,9 +41,8 @@ namespace etl { template > struct basic_inplace_string { template - static constexpr bool string_view_like = // - is_convertible_v> // - and not is_convertible_v; + static constexpr bool string_view_like + = is_convertible_v> and not is_convertible_v; using internal_size_t = etl::smallest_size_t; From 455c6183a913a03ec5b0ad805c51943821e5ed08 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 9 Sep 2025 23:14:37 +0200 Subject: [PATCH 14/34] [format] Remove broken implementation & header --- examples/all_headers.cpp | 1 - include/etl/_format/argument.hpp | 78 --------- include/etl/_format/basic_format_arg.hpp | 100 ----------- include/etl/_format/basic_format_args.hpp | 42 ----- include/etl/_format/basic_format_context.hpp | 67 -------- .../_format/basic_format_parse_context.hpp | 70 -------- include/etl/_format/basic_format_string.hpp | 39 ----- include/etl/_format/fmt_buffer.hpp | 38 ---- include/etl/_format/format_arg_store.hpp | 19 -- include/etl/_format/format_to.hpp | 127 -------------- include/etl/_format/formatter.hpp | 162 ------------------ include/etl/_format/make_format_args.hpp | 27 --- include/etl/_format/vformat_to.hpp | 26 --- include/etl/format.hpp | 23 --- tests/CMakeLists.txt | 1 - tests/format/CMakeLists.txt | 5 - tests/format/formatter.t.cpp | 114 ------------ 17 files changed, 939 deletions(-) delete mode 100644 include/etl/_format/argument.hpp delete mode 100644 include/etl/_format/basic_format_arg.hpp delete mode 100644 include/etl/_format/basic_format_args.hpp delete mode 100644 include/etl/_format/basic_format_context.hpp delete mode 100644 include/etl/_format/basic_format_parse_context.hpp delete mode 100644 include/etl/_format/basic_format_string.hpp delete mode 100644 include/etl/_format/fmt_buffer.hpp delete mode 100644 include/etl/_format/format_arg_store.hpp delete mode 100644 include/etl/_format/format_to.hpp delete mode 100644 include/etl/_format/formatter.hpp delete mode 100644 include/etl/_format/make_format_args.hpp delete mode 100644 include/etl/_format/vformat_to.hpp delete mode 100644 include/etl/format.hpp delete mode 100644 tests/format/CMakeLists.txt delete mode 100644 tests/format/formatter.t.cpp diff --git a/examples/all_headers.cpp b/examples/all_headers.cpp index c47996e09..af7aa71a9 100644 --- a/examples/all_headers.cpp +++ b/examples/all_headers.cpp @@ -33,7 +33,6 @@ import etl; #include #include #include - #include #include #include #include diff --git a/include/etl/_format/argument.hpp b/include/etl/_format/argument.hpp deleted file mode 100644 index 5e0fcb87f..000000000 --- a/include/etl/_format/argument.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_FORMAT_ARGUMENT_HPP -#define TETL_FORMAT_ARGUMENT_HPP - -#include -#include -#include -#include - -namespace etl::detail { -// Escape tokens -inline constexpr auto token_begin = '{'; -inline constexpr auto token_end = '}'; - -template -auto format_argument(ValueT const& val, FormatContext& fc) -> decltype(fc.out()) -{ - auto f = formatter{}; - return f.format(val, fc); -} - -inline auto split_at_next_argument(etl::string_view str) -> etl::pair -{ - using size_type = etl::string_view::size_type; - - auto const* res = etl::find(begin(str), end(str), token_begin); - if (res != end(str) && *etl::next(res) == token_end) { - auto index = static_cast(etl::distance(begin(str), res)); - auto first = str.substr(0, index); - auto second = str.substr(index + 2); - return etl::make_pair(first, second); - } - - return etl::make_pair(str, etl::string_view{}); -} - -template -auto format_escaped_sequences(etl::string_view str, FormatContext& ctx) -> void -{ - // Loop as long as escaped sequences are found. - auto const* first = begin(str); - while (true) { - // Find open sequence {{ - auto const* const openFirst = etl::find(first, end(str), token_begin); - auto const* const openSec = etl::next(openFirst); - auto const escapeStart = openFirst != end(str) && openSec != end(str) && *openSec == token_begin; - - if (escapeStart) { - // Copy upto {{ - detail::format_argument(etl::string_view(first, openFirst), ctx); - - // Find sequence }} - auto const* closeFirst = etl::find(etl::next(openSec), end(str), token_end); - auto const* closeSec = etl::next(closeFirst); - auto escapeClose = closeFirst != end(str) && closeSec != end(str) && *closeSec == token_end; - - // Copy everything between {{ ... }}, but only one curly each. - if (escapeClose) { - detail::format_argument(etl::string_view(openSec, closeFirst + 1), ctx); - first = closeFirst + 2; - } else { - // No closing "}}" found - TETL_PRECONDITION(false); - return; - } - } else { - // No more escaped sequence found, copy rest. - detail::format_argument(etl::string_view(first, end(str)), ctx); - return; - } - } -} - -} // namespace etl::detail - -#endif // TETL_FORMAT_ARGUMENT_HPP diff --git a/include/etl/_format/basic_format_arg.hpp b/include/etl/_format/basic_format_arg.hpp deleted file mode 100644 index 2b1f41769..000000000 --- a/include/etl/_format/basic_format_arg.hpp +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_FORMAT_BASIC_FORMAT_ARG_HPP -#define TETL_FORMAT_BASIC_FORMAT_ARG_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -namespace etl { - -template -struct basic_format_arg; - -namespace detail { -template -[[nodiscard]] constexpr auto make_arg(T&& value) -> basic_format_arg; -} // namespace detail - -template -struct basic_format_arg { -private: - using char_type = typename Context::char_type; - - template - friend constexpr auto detail::make_arg(T&& value) -> basic_format_arg; - -public: - struct handle { - auto format(basic_format_parse_context&, Context& ctx) const -> void; - - private: - friend struct basic_format_arg; - - template - explicit handle(T&& val) noexcept; - - void const* _ptr; - void (*_format)(basic_format_parse_context&, Context&, void const*); - }; - - basic_format_arg() noexcept = default; - - explicit operator bool() const noexcept - { - return holds_alternative(value); - } - - template - explicit basic_format_arg(T&& v) noexcept; - explicit basic_format_arg(float n) noexcept; - explicit basic_format_arg(double n) noexcept; - explicit basic_format_arg(long double n) noexcept; - explicit basic_format_arg(char_type const* s); - - template - explicit basic_format_arg(basic_string_view s) noexcept; - - template - explicit basic_format_arg(basic_inplace_string const& s) noexcept; - - explicit basic_format_arg(nullptr_t) noexcept; - - template - explicit basic_format_arg(T* p) noexcept; - - variant< - bool, - char_type, - int, - unsigned int, - long long int, - unsigned long long int, - float, - double, - long double, - char_type const*, - basic_string_view, - void const*, - handle - > - value{monostate{}}; -}; - -namespace detail { -template -[[nodiscard]] constexpr auto make_arg(T&& value) -> basic_format_arg -{ - return {etl::forward(value)}; -} -} // namespace detail - -} // namespace etl - -#endif // TETL_FORMAT_BASIC_FORMAT_ARG_HPP diff --git a/include/etl/_format/basic_format_args.hpp b/include/etl/_format/basic_format_args.hpp deleted file mode 100644 index a7c3bb085..000000000 --- a/include/etl/_format/basic_format_args.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_FORMAT_BASIC_FORMAT_ARGS_HPP -#define TETL_FORMAT_BASIC_FORMAT_ARGS_HPP - -#include -#include -#include -#include -#include - -namespace etl { - -template -struct basic_format_args { - constexpr basic_format_args() noexcept = default; - - template - constexpr basic_format_args(detail::format_arg_store const& store) noexcept - : _args{store.args} - { - } - - [[nodiscard]] constexpr auto get(size_t i) const noexcept -> basic_format_arg - { - if (i >= _args.size()) { - return basic_format_arg{}; - } - return _args[i]; - } - -private: - span const> _args; -}; - -using format_args = basic_format_args; -using wformat_args = basic_format_args; - -} // namespace etl - -#endif // TETL_FORMAT_BASIC_FORMAT_ARGS_HPP diff --git a/include/etl/_format/basic_format_context.hpp b/include/etl/_format/basic_format_context.hpp deleted file mode 100644 index 3e838a189..000000000 --- a/include/etl/_format/basic_format_context.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_FORMAT_BASIC_FORMAT_CONTEXT_HPP -#define TETL_FORMAT_BASIC_FORMAT_CONTEXT_HPP - -#include -#include - -namespace etl { -template -struct formatter; - -/// \brief Provides access to formatting state consisting of the formatting -/// arguments and the output iterator. -/// -/// The behavior is undefined if OutputIt does not model output_iterator. -/// -/// https://en.cppreference.com/w/cpp/utility/format/basic_format_context -template -struct basic_format_context { - using iterator = OutputIt; - using char_type = CharT; - - explicit constexpr basic_format_context(OutputIt pos) noexcept - : _pos{pos} - { - } - - template - using formatter_type = formatter; - - /// \brief Returns the iterator to the output buffer. - [[nodiscard]] constexpr auto out() noexcept -> iterator - { - return _pos; - } - - /// \brief Sets the output iterator to it. After a call to advance_to, - /// subsequent calls to out() will return a copy of it. - constexpr auto advance_to(iterator it) noexcept -> void - { - _pos = it; - } - -private: - OutputIt _pos; -}; - -/// \brief Provides access to formatting state consisting of the formatting -/// arguments and the output iterator. -/// -/// \details The first template argument is an output iterator that appends to -/// etl::inplace_string, such as etl::back_insert_iterator. -/// Implementations are encouraged to use an iterator to type-erased buffer type -/// that supports appending to any contiguous and resizable container. -/// -/// The behavior is undefined if OutputIt does not model output_iterator. -/// -/// https://en.cppreference.com/w/cpp/utility/format/basic_format_context -using format_context = basic_format_context>, char>; -using wformat_context = basic_format_context>, wchar_t>; - -} // namespace etl - -#endif // TETL_FORMAT_BASIC_FORMAT_CONTEXT_HPP diff --git a/include/etl/_format/basic_format_parse_context.hpp b/include/etl/_format/basic_format_parse_context.hpp deleted file mode 100644 index 77846738a..000000000 --- a/include/etl/_format/basic_format_parse_context.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_FORMAT_BASIC_FORMAT_PARSE_CONTEXT_HPP -#define TETL_FORMAT_BASIC_FORMAT_PARSE_CONTEXT_HPP - -#include -#include -#include - -namespace etl { - -template -struct basic_format_parse_context { - using char_type = CharT; - using const_iterator = typename basic_string_view::const_iterator; - using iterator = const_iterator; - - constexpr explicit basic_format_parse_context(basic_string_view fmt, size_t numArgs = 0) noexcept - : _begin{fmt.begin()} - , _end{fmt.end()} - , _numArgs{numArgs} - { - } - - basic_format_parse_context(basic_format_parse_context const& other) = delete; - auto operator=(basic_format_parse_context const& other) -> basic_format_parse_context& = delete; - - [[nodiscard]] constexpr auto begin() const noexcept -> const_iterator - { - return _begin; - } - - [[nodiscard]] constexpr auto end() const noexcept -> const_iterator - { - return _end; - } - - constexpr auto advance_to(const_iterator it) -> void - { - _begin = it; - } - - [[nodiscard]] constexpr auto next_arg_id() -> size_t - { - return static_cast(_nextArgId++); - } - - constexpr auto check_arg_id(size_t /*id*/) -> void - { - _nextArgId = -1; - } - -private: - // next_arg_id_ > 0 means automatic - // next_arg_id_ == 0 means unknown - // next_arg_id_ < 0 means manual - - iterator _begin; - iterator _end; - size_t _numArgs; - ptrdiff_t _nextArgId{}; -}; - -using format_parse_context = basic_format_parse_context; -using wformat_parse_context = basic_format_parse_context; - -} // namespace etl - -#endif // TETL_FORMAT_BASIC_FORMAT_PARSE_CONTEXT_HPP diff --git a/include/etl/_format/basic_format_string.hpp b/include/etl/_format/basic_format_string.hpp deleted file mode 100644 index 2e310c7e0..000000000 --- a/include/etl/_format/basic_format_string.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_FORMAT_BASIC_FORMAT_STRING_HPP -#define TETL_FORMAT_BASIC_FORMAT_STRING_HPP - -#include -#include -#include - -namespace etl { - -template -struct basic_format_string { - template - requires convertible_to> - consteval basic_format_string(T const& s) - : _str(s) - { - } - - [[nodiscard]] constexpr auto get() const noexcept -> basic_string_view - { - return _str; - } - -private: - basic_string_view _str; -}; - -template -using format_string = basic_format_string...>; - -template -using wformat_string = basic_format_string...>; - -} // namespace etl - -#endif // TETL_FORMAT_BASIC_FORMAT_STRING_HPP diff --git a/include/etl/_format/fmt_buffer.hpp b/include/etl/_format/fmt_buffer.hpp deleted file mode 100644 index 62bd0a36f..000000000 --- a/include/etl/_format/fmt_buffer.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_FORMAT_FMT_BUFFER_HPP -#define TETL_FORMAT_FMT_BUFFER_HPP - -#include -#include -#include - -namespace etl::detail { - -template -struct fmt_buffer { - using value_type = CharType; - - template - fmt_buffer(It out) noexcept - : _it{addressof(out)} - , _pushBack{[](void* ptr, CharType ch) { (*static_cast(ptr)) = ch; }} - { - } - - auto push_back(CharType ch) -> void - { - (_pushBack)(_it, ch); - } - -private: - using push_back_func_t = void (*)(void*, CharType); - - void* _it; - push_back_func_t _pushBack; -}; - -} // namespace etl::detail - -#endif // TETL_FORMAT_FMT_BUFFER_HPP diff --git a/include/etl/_format/format_arg_store.hpp b/include/etl/_format/format_arg_store.hpp deleted file mode 100644 index f4d805016..000000000 --- a/include/etl/_format/format_arg_store.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_FORMAT_FORMAT_ARG_STORE_HPP -#define TETL_FORMAT_FORMAT_ARG_STORE_HPP - -#include -#include - -namespace etl::detail { - -template -struct format_arg_store { - array, sizeof...(Args)> args; -}; - -} // namespace etl::detail - -#endif // TETL_FORMAT_FORMAT_ARG_STORE_HPP diff --git a/include/etl/_format/format_to.hpp b/include/etl/_format/format_to.hpp deleted file mode 100644 index a8ce97cf3..000000000 --- a/include/etl/_format/format_to.hpp +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2020 Tobias Hienzsch - -#ifndef TETL_FORMAT_FORMAT_TO_HPP -#define TETL_FORMAT_FORMAT_TO_HPP - -#include -#include -#include -#include - -namespace etl { -template -using diff_t = typename etl::iterator_traits>::difference_type; - -/// \brief Format args according to the format string fmt, and write the result -/// to the output iterator out. -/// -/// https://en.cppreference.com/w/cpp/utility/format/format_to -template -auto format_to(OutputIt out, etl::string_view fmt, Args const&... args) -> OutputIt -{ - auto ctx = format_context{out}; - - // Format leading text before the first argument. - auto const slices = detail::split_at_next_argument(fmt); - detail::format_escaped_sequences(slices.first, ctx); - - // Save rest of format string. Supress warning if format_to was called - // without arguments. - auto rest = slices.second; - etl::ignore_unused(rest); - - ([&] { - // Format argument - detail::format_argument(args, ctx); - - // Split format text at next argument - auto const restSlices = detail::split_at_next_argument(rest); - detail::format_escaped_sequences(restSlices.first, ctx); - - // Save rest of format string for the next arguments - rest = restSlices.second; - }(), ...); - - // Anything left over after the last argument. - if (auto const trailing = detail::split_at_next_argument(rest); !trailing.first.empty()) { - detail::format_escaped_sequences(trailing.first, ctx); - TETL_ASSERT(trailing.second.empty()); - } - - return ctx.out(); -} - -/// \brief etl::format_to_n_result has no base classes, or members other than -/// out, size and implicitly declared special member functions. -/// -/// https://en.cppreference.com/w/cpp/utility/format/format_to_n -template -struct format_to_n_result { - Out out; - diff_t size; -}; - -/// \brief Format args according to the format string fmt, and write the result -/// to the output iterator out. At most n characters are written. -/// -/// https://en.cppreference.com/w/cpp/utility/format/format_to_n -template -auto format_to_n(OutputIter out, diff_t n, etl::string_view fmt, Args const&... args) - -> format_to_n_result -{ - etl::ignore_unused(n); - - auto indices = etl::static_vector{}; - auto result = format_to_n_result{out, {}}; - - auto writeChar = [&result](auto ch) { - *result.out++ = ch; - result.size++; - }; - - auto varStart = etl::size_t{}; - for (decltype(fmt)::size_type i{}; i < fmt.size(); ++i) { - auto ch = fmt[i]; - if (ch == '{') { - if ((fmt.size() > i + 1) && (fmt[i + 1] == '{')) { - ++i; - writeChar('{'); - continue; - } - - varStart = i; - continue; - } - - if (ch == '}') { - if ((fmt.size() > i + 1) && (fmt[i + 1] == '}')) { - ++i; - writeChar('}'); - continue; - } - - indices.push_back(varStart); - writeChar('0'); - continue; - } - - writeChar(ch); - } - - if (indices.size() > 0) { - [[maybe_unused]] auto replaceCharAt = [n](auto output, auto pos, char val) { - etl::ignore_unused(n); - // TETL_ASSERT((long)pos < n); - output[pos] = val; - }; - - [[maybe_unused]] typename decltype(indices)::size_type i{}; - (replaceCharAt(out, indices[i++], args), ...); - } - - return result; -} -} // namespace etl - -#endif // TETL_FORMAT_FORMAT_TO_HPP diff --git a/include/etl/_format/formatter.hpp b/include/etl/_format/formatter.hpp deleted file mode 100644 index 8eb4ca3ec..000000000 --- a/include/etl/_format/formatter.hpp +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_FORMAT_FORMATTER_HPP -#define TETL_FORMAT_FORMATTER_HPP - -#include -#include -#include -#include -#include -#include - -namespace etl { -/// \brief The enabled specializations of formatter define formatting rules for -/// a given type. Enabled specializations meet the Formatter requirements. -/// -/// https://en.cppreference.com/w/cpp/utility/format/formatter -template -struct formatter { - formatter() = delete; - formatter(formatter const& other) = delete; - auto operator=(formatter const& other) -> formatter = delete; -}; - -/// \brief Standard specializations for basic type char. -template <> -struct formatter { - template - constexpr auto format(char val, FormatContext& fc) -> decltype(fc.out()) - { - auto pos = fc.out(); - *pos = val; - return pos++; - } -}; - -template <> -struct formatter { - template - constexpr auto format(char const* val, FormatContext& fc) -> decltype(fc.out()) - { - return etl::copy(val, val + etl::strlen(val), fc.out()); - } -}; - -template -struct formatter { - template - constexpr auto format(char const* val, FormatContext& fc) -> decltype(fc.out()) - { - return etl::copy(val, val + N, fc.out()); - } -}; - -template <> -struct formatter { - template - constexpr auto format(etl::string_view str, FormatContext& fc) -> decltype(fc.out()) - { - return etl::copy(begin(str), end(str), fc.out()); - } -}; - -template -struct formatter, char> { - template - constexpr auto format(etl::inplace_string const& str, FormatContext& fc) -> decltype(fc.out()) - { - return formatter().format(str, fc); - } -}; - -namespace detail { -template -constexpr auto integer_format(Integer v, FormatContext& fc) -> decltype(fc.out()) -{ - char buf[32]{}; - auto res = strings::from_integer(v, begin(buf), sizeof(buf), 10); - if (res.error == strings::from_integer_error::none) { - auto str = string_view{begin(buf)}; - return formatter().format(str, fc); - } - return formatter().format("", fc); -} -} // namespace detail - -template <> -struct formatter { - template - constexpr auto format(short v, FormatContext& fc) -> decltype(fc.out()) - { - return detail::integer_format(v, fc); - } -}; - -template <> -struct formatter { - template - constexpr auto format(int v, FormatContext& fc) -> decltype(fc.out()) - { - return detail::integer_format(v, fc); - } -}; - -template <> -struct formatter { - template - constexpr auto format(long v, FormatContext& fc) -> decltype(fc.out()) - { - return detail::integer_format(v, fc); - } -}; - -template <> -struct formatter { - template - constexpr auto format(long long v, FormatContext& fc) -> decltype(fc.out()) - { - return detail::integer_format(v, fc); - } -}; - -template <> -struct formatter { - template - constexpr auto format(unsigned short v, FormatContext& fc) -> decltype(fc.out()) - { - return detail::integer_format(v, fc); - } -}; - -template <> -struct formatter { - template - constexpr auto format(int v, FormatContext& fc) -> decltype(fc.out()) - { - return detail::integer_format(v, fc); - } -}; - -template <> -struct formatter { - template - constexpr auto format(unsigned long v, FormatContext& fc) -> decltype(fc.out()) - { - return detail::integer_format(v, fc); - } -}; - -template <> -struct formatter { - template - constexpr auto format(unsigned long long v, FormatContext& fc) -> decltype(fc.out()) - { - return detail::integer_format(v, fc); - } -}; - -} // namespace etl - -#endif // TETL_FORMAT_FORMATTER_HPP diff --git a/include/etl/_format/make_format_args.hpp b/include/etl/_format/make_format_args.hpp deleted file mode 100644 index 68cdd50a9..000000000 --- a/include/etl/_format/make_format_args.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_FORMAT_MAKE_FORMAT_ARGS_HPP -#define TETL_FORMAT_MAKE_FORMAT_ARGS_HPP - -#include -#include -#include - -namespace etl { - -template -auto make_format_args(Args&&... args) -> detail::format_arg_store -{ - return {etl::forward(args)...}; -} - -template -auto make_wformat_args(Args&&... args) -> detail::format_arg_store -{ - return {etl::forward(args)...}; -} - -} // namespace etl - -#endif // TETL_FORMAT_MAKE_FORMAT_ARGS_HPP diff --git a/include/etl/_format/vformat_to.hpp b/include/etl/_format/vformat_to.hpp deleted file mode 100644 index 1caf58774..000000000 --- a/include/etl/_format/vformat_to.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_FORMAT_VFORMAT_TO_HPP -#define TETL_FORMAT_VFORMAT_TO_HPP - -#include -#include -#include -#include -#include - -namespace etl { - -template -auto vformat_to(OutputIt out, string_view fmt, format_args args) -> OutputIt -{ - auto buffer = etl::detail::fmt_buffer{out}; - auto it = etl::back_inserter(buffer); - etl::ignore_unused(fmt, args, it); - return out; -} - -} // namespace etl - -#endif // TETL_FORMAT_VFORMAT_TO_HPP diff --git a/include/etl/format.hpp b/include/etl/format.hpp deleted file mode 100644 index f1c495186..000000000 --- a/include/etl/format.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2020 Tobias Hienzsch - -#ifndef TETL_FORMAT_HPP -#define TETL_FORMAT_HPP - -/// \defgroup format format -/// Formatting library including etl::format -/// \ingroup strings-library - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif // TETL_FORMAT_HPP diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 79d4afa8f..c656904a8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -62,7 +62,6 @@ add_subdirectory("exception") add_subdirectory("execution") add_subdirectory("expected") add_subdirectory("flat_set") -add_subdirectory("format") add_subdirectory("functional") add_subdirectory("inplace_vector") add_subdirectory("iterator") diff --git a/tests/format/CMakeLists.txt b/tests/format/CMakeLists.txt deleted file mode 100644 index ef298cce7..000000000 --- a/tests/format/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: BSL-1.0 -# SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch -project(format) - -tetl_add_test(${PROJECT_NAME} formatter) diff --git a/tests/format/formatter.t.cpp b/tests/format/formatter.t.cpp deleted file mode 100644 index 4da6609bf..000000000 --- a/tests/format/formatter.t.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#include "testing/testing.hpp" - -#if defined(TETL_ENABLE_CXX_MODULES) -import etl; -#else - #include - #include - #include - #include -#endif - -using namespace etl::string_view_literals; - -template -static constexpr auto test() -> bool -{ - // { - // using string_t = T; - - // auto str = string_t(); - // auto ctx = etl::format_context { etl::back_inserter(str) }; - // auto formatter = etl::formatter {}; - - // formatter.format('a', ctx); - // CHECK(str[0] == 'a'); - - // formatter.format('x', ctx); - // CHECK(str[1] == 'x'); - - // formatter.format('1', ctx); - // CHECK(str[2] == '1'); - // } - // { - // using string_t = T; - - // auto str = string_t(); - // auto ctx = etl::format_context { etl::back_inserter(str) }; - - // auto f1 = etl::formatter {}; - // f1.format("abc", ctx); - // CHECK(etl::string_view(str.data()) == etl::string_view("abc")); - - // str.clear(); - // auto f2 = etl::formatter {}; - // f2.format("foobar", ctx); - // CHECK(etl::string_view(str.data()) == etl::string_view("foobar")); - // } - // { - // using string_t = T; - - // auto str = string_t(); - // auto ctx = etl::format_context { etl::back_inserter(str) }; - // auto formatter = etl::formatter {}; - - // auto const* cStr1 = "test"; - // formatter.format(cStr1, ctx); - // CHECK(etl::string_view(str.data()) == etl::string_view(cStr1)); - - // str.clear(); - // auto const* cStr2 = "abcdef"; - // formatter.format(cStr2, ctx); - // CHECK(etl::string_view(str.data()) == etl::string_view(cStr2)); - // } - // { - // using string_t = T; - - // auto str = string_t(); - // auto ctx = etl::format_context { etl::back_inserter(str) }; - // auto formatter = etl::formatter {}; - - // etl::string_view str1 = "test"; - // formatter.format(str1, ctx); - // CHECK(etl::string_view(str.data()) == etl::string_view(str1)); - - // str.clear(); - // etl::string_view str2 = "abcdef"; - // formatter.format(str2, ctx); - // CHECK(etl::string_view(str.data()) == etl::string_view(str2)); - // } - // { - // using string_t = T; - - // auto str = string_t(); - // auto ctx = etl::format_context { etl::back_inserter(str) }; - // auto formatter = etl::formatter {}; - - // string_t str1 = "test"; - // formatter.format(str1, ctx); - // CHECK(etl::string_view(str.data()) == etl::string_view(str1)); - - // str.clear(); - // string_t str2 = "abcdef"; - // formatter.format(str2, ctx); - // CHECK(etl::string_view(str.data()) == etl::string_view(str2)); - // } - return true; -} - -static constexpr auto test_all() -> bool -{ - CHECK(test>()); - CHECK(test>()); - return true; -} - -auto main() -> int -{ - STATIC_CHECK(test_all()); - - return 0; -} From e4e905933b2831d3b361629247ad9276e2fce8fe Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 9 Sep 2025 23:17:14 +0200 Subject: [PATCH 15/34] Enable all contract checks in CMake desktop presets --- CMakePresets.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakePresets.json b/CMakePresets.json index b4273525b..34af0dd0d 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -21,7 +21,11 @@ { "name": "desktop", "description": "Configure with hosted system toolchain", - "inherits": ["_root-config"] + "inherits": ["_root-config"], + "cacheVariables": { + "TETL_BUILD_CONTRACT_CHECKS": true, + "TETL_BUILD_CONTRACT_CHECKS_SAFE": true + } }, { "name": "avr-gcc", From f97a42888d2bc1828de6ea986973021f4eac0998 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 9 Sep 2025 23:18:48 +0200 Subject: [PATCH 16/34] Remove experimental/net --- include/etl/experimental/net/buffer.hpp | 52 ------------ include/etl/experimental/net/buffer_const.hpp | 71 ---------------- .../etl/experimental/net/buffer_mutable.hpp | 71 ---------------- include/etl/experimental/net/byte_order.hpp | 75 ---------------- src/etl.cpp | 6 -- src/inc/experimental/net/buffer.inc | 11 --- src/inc/experimental/net/byte_order.inc | 9 -- tests/CMakeLists.txt | 1 - tests/experimental/net/CMakeLists.txt | 6 -- tests/experimental/net/buffer.t.cpp | 85 ------------------- tests/experimental/net/byte_order.t.cpp | 40 --------- 11 files changed, 427 deletions(-) delete mode 100644 include/etl/experimental/net/buffer.hpp delete mode 100644 include/etl/experimental/net/buffer_const.hpp delete mode 100644 include/etl/experimental/net/buffer_mutable.hpp delete mode 100644 include/etl/experimental/net/byte_order.hpp delete mode 100644 src/inc/experimental/net/buffer.inc delete mode 100644 src/inc/experimental/net/byte_order.inc delete mode 100644 tests/experimental/net/CMakeLists.txt delete mode 100644 tests/experimental/net/buffer.t.cpp delete mode 100644 tests/experimental/net/byte_order.t.cpp diff --git a/include/etl/experimental/net/buffer.hpp b/include/etl/experimental/net/buffer.hpp deleted file mode 100644 index 8e17e3690..000000000 --- a/include/etl/experimental/net/buffer.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2019 Tobias Hienzsch - -#ifndef TETL_NET_BUFFER_HPP -#define TETL_NET_BUFFER_HPP - -#include - -#include -#include - -#include -#include - -namespace etl::experimental::net { -inline auto make_buffer(void* data, size_t size) noexcept -> mutable_buffer -{ - return mutable_buffer{data, size}; -} - -inline auto make_buffer(void const* data, size_t size) noexcept -> const_buffer -{ - return const_buffer{data, size}; -} - -template -inline auto make_buffer(etl::array& array) noexcept -> mutable_buffer -{ - return mutable_buffer{array.data(), array.size()}; -} - -template -inline auto make_buffer(etl::array const& array) noexcept -> const_buffer -{ - return const_buffer{array.data(), array.size()}; -} - -template -inline auto make_buffer(etl::static_vector& vec) noexcept -> mutable_buffer -{ - return mutable_buffer{vec.data(), vec.size()}; -} - -template -inline auto make_buffer(etl::static_vector const& vec) noexcept -> const_buffer -{ - return const_buffer{vec.data(), vec.size()}; -} - -} // namespace etl::experimental::net - -#endif // TETL_NET_BUFFER_HPP diff --git a/include/etl/experimental/net/buffer_const.hpp b/include/etl/experimental/net/buffer_const.hpp deleted file mode 100644 index ac8ef72aa..000000000 --- a/include/etl/experimental/net/buffer_const.hpp +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2019 Tobias Hienzsch - -#ifndef TETL_NET_BUFFER_CONST_HPP -#define TETL_NET_BUFFER_CONST_HPP - -#include - -#include -#include - -namespace etl::experimental::net { -struct const_buffer { - /// \brief Construct an empty buffer. - const_buffer() noexcept = default; - - /// \brief Construct a buffer to represent a given memory range. - const_buffer(void const* data, etl::size_t size) - : _data{data} - , _size{size} - { - } - - /// \brief Get a pointer to the beginning of the memory range. - [[nodiscard]] auto data() const noexcept -> void const* - { - return _data; - } - - /// \brief Get the size of the memory range. - [[nodiscard]] auto size() const noexcept -> etl::size_t - { - return _size; - } - - /// \brief Move the start of the buffer by the specified number of bytes. - auto operator+=(etl::size_t n) noexcept -> const_buffer& - { - auto const offset = n < _size ? n : _size; - _data = static_cast(_data) + offset; - _size -= offset; - return *this; - } - -private: - void const* _data = nullptr; - etl::size_t _size = 0; -}; - -/// \brief Create a new modifiable buffer that is offset from the start of -/// another. -/// \relates const_buffer -inline auto operator+(const_buffer const& b, etl::size_t const n) noexcept -> const_buffer -{ - auto offset = n < b.size() ? n : b.size(); - auto const* data = static_cast(b.data()) + offset; - auto size = b.size() - offset; - return const_buffer{data, size}; -} - -/// \brief Create a new modifiable buffer that is offset from the start of -/// another. -/// \relates const_buffer -inline auto operator+(etl::size_t const n, const_buffer const& b) noexcept -> const_buffer -{ - return b + n; -} - -} // namespace etl::experimental::net - -#endif // TETL_NET_BUFFER_CONST_HPP diff --git a/include/etl/experimental/net/buffer_mutable.hpp b/include/etl/experimental/net/buffer_mutable.hpp deleted file mode 100644 index 67a51cf51..000000000 --- a/include/etl/experimental/net/buffer_mutable.hpp +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2019 Tobias Hienzsch - -#ifndef TETL_NET_BUFFER_MUTABLE_HPP -#define TETL_NET_BUFFER_MUTABLE_HPP - -#include - -#include -#include - -namespace etl::experimental::net { -struct mutable_buffer { - /// \brief Construct an empty buffer. - mutable_buffer() noexcept = default; - - /// \brief Construct a buffer to represent a given memory range. - mutable_buffer(void* data, etl::size_t size) - : _data{data} - , _size{size} - { - } - - /// \brief Get a pointer to the beginning of the memory range. - [[nodiscard]] auto data() const noexcept -> void* - { - return _data; - } - - /// \brief Get the size of the memory range. - [[nodiscard]] auto size() const noexcept -> etl::size_t - { - return _size; - } - - /// \brief Move the start of the buffer by the specified number of bytes. - auto operator+=(etl::size_t n) noexcept -> mutable_buffer& - { - auto const offset = n < _size ? n : _size; - _data = static_cast(_data) + offset; - _size -= offset; - return *this; - } - -private: - void* _data = nullptr; - etl::size_t _size = 0; -}; - -/// \brief Create a new modifiable buffer that is offset from the start of -/// another. -/// \relates mutable_buffer -inline auto operator+(mutable_buffer const& b, etl::size_t const n) noexcept -> mutable_buffer -{ - auto offset = n < b.size() ? n : b.size(); - auto* data = static_cast(b.data()) + offset; - auto size = b.size() - offset; - return mutable_buffer{data, size}; -} - -/// \brief Create a new modifiable buffer that is offset from the start of -/// another. -/// \relates mutable_buffer -inline auto operator+(etl::size_t const n, mutable_buffer const& b) noexcept -> mutable_buffer -{ - return b + n; -} - -} // namespace etl::experimental::net - -#endif // TETL_NET_BUFFER_MUTABLE_HPP diff --git a/include/etl/experimental/net/byte_order.hpp b/include/etl/experimental/net/byte_order.hpp deleted file mode 100644 index 420f1f7a8..000000000 --- a/include/etl/experimental/net/byte_order.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2019 Tobias Hienzsch - -#ifndef TETL_NET_BYTE_ORDER_HPP -#define TETL_NET_BYTE_ORDER_HPP - -#include - -#include - -namespace etl::experimental::net { -template -constexpr auto ntoh(T) -> T = delete; - -constexpr auto ntoh(char v) noexcept -> char -{ - return v; -} - -constexpr auto ntoh(uint8_t v) noexcept -> uint8_t -{ - return v; -} - -constexpr auto ntoh(int8_t v) noexcept -> int8_t -{ - return v; -} - -constexpr auto ntoh(uint16_t v) noexcept -> uint16_t -{ - return uint16_t(v << uint16_t(8)) | uint16_t(v >> uint16_t(8)); -} - -constexpr auto ntoh(uint32_t v) noexcept -> uint32_t -{ - auto const a = v << 24; - auto const b = (v & 0x0000FF00) << 8; - auto const c = (v & 0x00FF0000) >> 8; - auto const d = v >> 24; - - return a | b | c | d; -} - -template -constexpr auto hton(T) -> T = delete; - -constexpr auto hton(char v) noexcept -> char -{ - return v; -} - -constexpr auto hton(int8_t v) noexcept -> int8_t -{ - return v; -} - -constexpr auto hton(uint8_t v) noexcept -> uint8_t -{ - return v; -} - -constexpr auto hton(uint16_t v) noexcept -> uint16_t -{ - return ntoh(v); -} - -constexpr auto hton(uint32_t v) noexcept -> uint32_t -{ - return ntoh(v); -} - -} // namespace etl::experimental::net - -#endif // TETL_NET_BYTE_ORDER_HPP diff --git a/src/etl.cpp b/src/etl.cpp index 13e8d1315..4baee19cc 100644 --- a/src/etl.cpp +++ b/src/etl.cpp @@ -63,9 +63,6 @@ module; #include #include -#include -#include - export module etl; #include "inc/algorithm.inc" @@ -128,6 +125,3 @@ export module etl; #include "inc/experimental/hardware/stm32/gpio.inc" #include "inc/experimental/hardware/stm32/interrupt.inc" - -#include "inc/experimental/net/buffer.inc" -#include "inc/experimental/net/byte_order.inc" diff --git a/src/inc/experimental/net/buffer.inc b/src/inc/experimental/net/buffer.inc deleted file mode 100644 index d6f80a5a9..000000000 --- a/src/inc/experimental/net/buffer.inc +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2025 Tobias Hienzsch - -export namespace etl::experimental::net { - -using etl::experimental::net::const_buffer; -using etl::experimental::net::make_buffer; -using etl::experimental::net::mutable_buffer; -using etl::experimental::net::operator+; - -} // namespace etl::experimental::net diff --git a/src/inc/experimental/net/byte_order.inc b/src/inc/experimental/net/byte_order.inc deleted file mode 100644 index 312049ebf..000000000 --- a/src/inc/experimental/net/byte_order.inc +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2025 Tobias Hienzsch - -export namespace etl::experimental::net { - -using etl::experimental::net::hton; -using etl::experimental::net::ntoh; - -} // namespace etl::experimental::net diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c656904a8..8c3417523 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -95,5 +95,4 @@ add_subdirectory("vector") add_subdirectory("version") add_subdirectory("experimental/freertos") -add_subdirectory("experimental/net") add_subdirectory("experimental/stm32") diff --git a/tests/experimental/net/CMakeLists.txt b/tests/experimental/net/CMakeLists.txt deleted file mode 100644 index e1399b946..000000000 --- a/tests/experimental/net/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: BSL-1.0 -# SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch -project(experimental_net) - -tetl_add_test(${PROJECT_NAME} buffer) -tetl_add_test(${PROJECT_NAME} byte_order) diff --git a/tests/experimental/net/buffer.t.cpp b/tests/experimental/net/buffer.t.cpp deleted file mode 100644 index 2ea68e4cd..000000000 --- a/tests/experimental/net/buffer.t.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#include "testing/testing.hpp" - -#if defined(TETL_ENABLE_CXX_MODULES) -import etl; -#else - #include // for array - #include // for make_buffer - #include // for const_buffer, ope... - #include // for mutable_buffer -#endif - -static auto test_all() -> bool -{ - { - auto const buffer = etl::experimental::net::mutable_buffer{}; - CHECK(buffer.data() == nullptr); - CHECK(buffer.size() == 0); - } - { - auto mem = etl::array{}; - auto buf = etl::experimental::net::make_buffer(mem.data(), mem.size()); - CHECK(mem.data() == buf.data()); - CHECK(mem.size() == buf.size()); - } - { - auto mem = etl::array{}; - auto buf = etl::experimental::net::make_buffer(mem.data(), mem.size()); - buf += 4; - CHECK(mem.data() != buf.data()); - } - { - auto mem = etl::array{}; - auto buf = etl::experimental::net::make_buffer(mem.data(), mem.size()); - - { - auto newBuf = buf + 4; - CHECK(newBuf.size() == buf.size() - 4); - } - - { - auto newBuf = 8 + buf; - CHECK(newBuf.size() == buf.size() - 8); - } - } - { - auto const buf = etl::experimental::net::const_buffer{}; - CHECK(buf.data() == nullptr); - CHECK(buf.size() == 0); - } - { - auto const mem = etl::array{}; - auto buf = etl::experimental::net::make_buffer(mem.data(), mem.size()); - CHECK(mem.data() == buf.data()); - CHECK(mem.size() == buf.size()); - } - { - auto const mem = etl::array{}; - auto buf = etl::experimental::net::make_buffer(mem.data(), mem.size()); - buf += 4; - CHECK(mem.data() != buf.data()); - CHECK(mem.size() - 4 == buf.size()); - } - - { - auto const mem = etl::array{}; - auto buf = etl::experimental::net::make_buffer(mem.data(), mem.size()); - - auto newBuf1 = buf + 4; - CHECK(newBuf1.size() == buf.size() - 4); - - auto newBuf2 = 8 + buf; - CHECK(newBuf2.size() == buf.size() - 8); - } - - return true; -} - -auto main() -> int -{ - CHECK(test_all()); - return 0; -} diff --git a/tests/experimental/net/byte_order.t.cpp b/tests/experimental/net/byte_order.t.cpp deleted file mode 100644 index 6ad387afe..000000000 --- a/tests/experimental/net/byte_order.t.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#include "testing/testing.hpp" - -#if defined(TETL_ENABLE_CXX_MODULES) -import etl; -#else - #include // for int8_t, uint16_t, uin... - #include // for hton, ntoh, net -#endif - -static constexpr auto test_all() -> bool -{ - using namespace etl::experimental::net; - - CHECK(ntoh(hton(etl::int8_t{0})) == 0); - CHECK(ntoh(hton(etl::int8_t{1})) == 1); - CHECK(ntoh(hton(etl::int8_t{42})) == 42); - - CHECK(ntoh(hton(etl::uint8_t{0})) == 0); - CHECK(ntoh(hton(etl::uint8_t{1})) == 1); - CHECK(ntoh(hton(etl::uint8_t{42})) == 42); - - CHECK(ntoh(hton(etl::uint16_t{0})) == 0); - CHECK(ntoh(hton(etl::uint16_t{1})) == 1); - CHECK(ntoh(hton(etl::uint16_t{42})) == 42); - - CHECK(ntoh(hton(etl::uint32_t{0})) == 0); - CHECK(ntoh(hton(etl::uint32_t{1})) == 1); - CHECK(ntoh(hton(etl::uint32_t{42})) == 42); - - return true; -} - -auto main() -> int -{ - STATIC_CHECK(test_all()); - return 0; -} From ec673937471d3867a2b52d94771e0ba29fdea25f Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Thu, 11 Sep 2025 13:04:13 +0200 Subject: [PATCH 17/34] [type_traits] Add doxygen group tags --- include/etl/_string/basic_inplace_string.hpp | 8 ++++---- include/etl/_string_view/basic_string_view.hpp | 8 ++++---- include/etl/_type_traits/add_const.hpp | 2 ++ include/etl/_type_traits/add_cv.hpp | 2 ++ .../etl/_type_traits/add_lvalue_reference.hpp | 2 ++ include/etl/_type_traits/add_pointer.hpp | 2 ++ .../etl/_type_traits/add_rvalue_reference.hpp | 2 ++ include/etl/_type_traits/add_volatile.hpp | 2 ++ include/etl/_type_traits/aligned_storage.hpp | 4 ++++ include/etl/_type_traits/aligned_union.hpp | 18 ++++++++++++------ include/etl/_type_traits/alignment_of.hpp | 2 ++ include/etl/_type_traits/always_false.hpp | 1 + .../_type_traits/basic_common_reference.hpp | 2 ++ include/etl/_type_traits/bool_constant.hpp | 6 +++++- include/etl/_type_traits/conditional.hpp | 3 +++ include/etl/_type_traits/conjunction.hpp | 3 +++ include/etl/_type_traits/copy_cv.hpp | 7 +++++-- include/etl/_type_traits/decay.hpp | 3 +++ include/etl/_type_traits/declval.hpp | 1 + include/etl/_type_traits/disjunction.hpp | 2 ++ include/etl/_type_traits/enable_if.hpp | 2 ++ include/etl/_type_traits/extent.hpp | 2 ++ .../has_unique_object_representations.hpp | 3 +++ include/etl/_type_traits/index_constant.hpp | 2 ++ include/etl/_type_traits/integral_constant.hpp | 7 +++++++ include/etl/_type_traits/is_abstract.hpp | 2 ++ include/etl/_type_traits/is_aggregate.hpp | 2 ++ include/etl/_type_traits/is_arithmetic.hpp | 2 ++ include/etl/_type_traits/is_array.hpp | 4 ++++ include/etl/_type_traits/is_assignable.hpp | 2 ++ include/etl/_type_traits/is_base_of.hpp | 4 ++++ include/etl/_type_traits/is_bounded_array.hpp | 3 +++ .../etl/_type_traits/is_builtin_integer.hpp | 2 ++ .../_type_traits/is_builtin_signed_integer.hpp | 2 ++ .../is_builtin_unsigned_integer.hpp | 4 ++++ include/etl/_type_traits/is_class.hpp | 2 ++ 36 files changed, 108 insertions(+), 17 deletions(-) diff --git a/include/etl/_string/basic_inplace_string.hpp b/include/etl/_string/basic_inplace_string.hpp index 273cf7c8e..a4453a7bc 100644 --- a/include/etl/_string/basic_inplace_string.hpp +++ b/include/etl/_string/basic_inplace_string.hpp @@ -1199,7 +1199,7 @@ struct basic_inplace_string { /// \brief Finds the first character not equal to any of the characters in /// the given character sequence. /// - /// \return Position of the first character not equal to any of the + /// \returns Position of the first character not equal to any of the /// characters in the given string, or npos if no such character is found. [[nodiscard]] constexpr auto find_first_not_of(basic_inplace_string const& str, size_type pos = 0) const noexcept -> size_type @@ -1210,7 +1210,7 @@ struct basic_inplace_string { /// \brief Finds the first character not equal to any of the characters in /// the given character sequence. /// - /// \return Position of the first character not equal to any of the + /// \returns Position of the first character not equal to any of the /// characters in the given string, or npos if no such character is found. [[nodiscard]] constexpr auto find_first_not_of(Char ch, size_type pos = 0) const noexcept -> size_type { @@ -1220,7 +1220,7 @@ struct basic_inplace_string { /// \brief Finds the first character not equal to any of the characters in /// the given character sequence. /// - /// \return Position of the first character not equal to any of the + /// \returns Position of the first character not equal to any of the /// characters in the given string, or npos if no such character is found. [[nodiscard]] constexpr auto find_first_not_of(Char const* s, size_type pos) const -> size_type { @@ -1230,7 +1230,7 @@ struct basic_inplace_string { /// \brief Finds the first character not equal to any of the characters in /// the given character sequence. /// - /// \return Position of the first character not equal to any of the + /// \returns Position of the first character not equal to any of the /// characters in the given string, or npos if no such character is found. [[nodiscard]] constexpr auto find_first_not_of(Char const* s, size_type pos, size_type count) const -> size_type { diff --git a/include/etl/_string_view/basic_string_view.hpp b/include/etl/_string_view/basic_string_view.hpp index fcc7ceb8e..bd047573d 100644 --- a/include/etl/_string_view/basic_string_view.hpp +++ b/include/etl/_string_view/basic_string_view.hpp @@ -552,7 +552,7 @@ struct basic_string_view { /// \brief Finds the first character not equal to any of the characters in /// the given character sequence. /// - /// \return Position of the first character not equal to any of the + /// \returns Position of the first character not equal to any of the /// characters in the given string, or npos if no such character is found. [[nodiscard]] constexpr auto find_first_not_of(basic_string_view sv, size_type pos = 0) const noexcept -> size_type { @@ -571,7 +571,7 @@ struct basic_string_view { /// \brief Finds the first character not equal to any of the characters in /// the given character sequence. /// - /// \return Position of the first character not equal to any of the + /// \returns Position of the first character not equal to any of the /// characters in the given string, or npos if no such character is found. [[nodiscard]] constexpr auto find_first_not_of(Char c, size_type pos = 0) const noexcept -> size_type { @@ -589,7 +589,7 @@ struct basic_string_view { /// \brief Finds the first character not equal to any of the characters in /// the given character sequence. /// - /// \return Position of the first character not equal to any of the + /// \returns Position of the first character not equal to any of the /// characters in the given string, or npos if no such character is found. [[nodiscard]] constexpr auto find_first_not_of(Char const* s, size_type pos, size_type count) const -> size_type { @@ -599,7 +599,7 @@ struct basic_string_view { /// \brief Finds the first character not equal to any of the characters in /// the given character sequence. /// - /// \return Position of the first character not equal to any of the + /// \returns Position of the first character not equal to any of the /// characters in the given string, or npos if no such character is found. [[nodiscard]] constexpr auto find_first_not_of(Char const* s, size_type pos = 0) const -> size_type { diff --git a/include/etl/_type_traits/add_const.hpp b/include/etl/_type_traits/add_const.hpp index fd649d49b..abcbc7631 100644 --- a/include/etl/_type_traits/add_const.hpp +++ b/include/etl/_type_traits/add_const.hpp @@ -9,12 +9,14 @@ namespace etl { /// \brief Provides the member typedef type which is the same as T, except it /// has a cv-qualifier added (unless T is a function, a reference, or already /// has this cv-qualifier). Adds const. +/// \ingroup type_traits template struct add_const { using type = T const; }; /// \relates add_const +/// \ingroup type_traits template using add_const_t = typename add_const::type; diff --git a/include/etl/_type_traits/add_cv.hpp b/include/etl/_type_traits/add_cv.hpp index a9183a80c..c7fa233d0 100644 --- a/include/etl/_type_traits/add_cv.hpp +++ b/include/etl/_type_traits/add_cv.hpp @@ -11,12 +11,14 @@ namespace etl { /// has this cv-qualifier). Adds both const and volatile. /// /// \headerfile etl/type_traits.hpp +/// \ingroup type_traits template struct add_cv { using type = T const volatile; }; /// \relates add_cv +/// \ingroup type_traits template using add_cv_t = typename add_cv::type; diff --git a/include/etl/_type_traits/add_lvalue_reference.hpp b/include/etl/_type_traits/add_lvalue_reference.hpp index 6eaaaea62..02b5b12ae 100644 --- a/include/etl/_type_traits/add_lvalue_reference.hpp +++ b/include/etl/_type_traits/add_lvalue_reference.hpp @@ -20,10 +20,12 @@ auto try_add_lvalue_reference(...) -> type_identity; /// \brief Creates a lvalue reference type of T. /// \headerfile etl/type_traits.hpp +/// \ingroup type_traits template struct add_lvalue_reference : decltype(detail::try_add_lvalue_reference(0)) { }; /// \relates add_lvalue_reference +/// \ingroup type_traits template using add_lvalue_reference_t = typename add_lvalue_reference::type; diff --git a/include/etl/_type_traits/add_pointer.hpp b/include/etl/_type_traits/add_pointer.hpp index c046e76aa..c24fc97f3 100644 --- a/include/etl/_type_traits/add_pointer.hpp +++ b/include/etl/_type_traits/add_pointer.hpp @@ -28,10 +28,12 @@ auto try_add_pointer(...) -> type_identity; /// specializations for add_pointer is undefined. /// /// \headerfile etl/type_traits.hpp +/// \ingroup type_traits template struct add_pointer : decltype(detail::try_add_pointer(0)) { }; /// \relates add_pointer +/// \ingroup type_traits template using add_pointer_t = typename add_pointer::type; diff --git a/include/etl/_type_traits/add_rvalue_reference.hpp b/include/etl/_type_traits/add_rvalue_reference.hpp index 2eac0d7ee..68dd1869b 100644 --- a/include/etl/_type_traits/add_rvalue_reference.hpp +++ b/include/etl/_type_traits/add_rvalue_reference.hpp @@ -20,10 +20,12 @@ auto try_add_rvalue_reference(...) -> type_identity; /// \brief Creates a rvalue reference type of T. /// \headerfile etl/type_traits.hpp +/// \ingroup type_traits template struct add_rvalue_reference : decltype(detail::try_add_rvalue_reference(0)) { }; /// \relates add_rvalue_reference +/// \ingroup type_traits template using add_rvalue_reference_t = typename add_rvalue_reference::type; diff --git a/include/etl/_type_traits/add_volatile.hpp b/include/etl/_type_traits/add_volatile.hpp index 4a0551609..0ef5c44e2 100644 --- a/include/etl/_type_traits/add_volatile.hpp +++ b/include/etl/_type_traits/add_volatile.hpp @@ -11,12 +11,14 @@ namespace etl { /// has this cv-qualifier). Adds volatile. /// /// \headerfile etl/type_traits.hpp +/// \ingroup type_traits template struct add_volatile { using type = T volatile; }; /// \relates add_volatile +/// \ingroup type_traits template using add_volatile_t = typename add_volatile::type; diff --git a/include/etl/_type_traits/aligned_storage.hpp b/include/etl/_type_traits/aligned_storage.hpp index 93017aedd..08a041bb8 100644 --- a/include/etl/_type_traits/aligned_storage.hpp +++ b/include/etl/_type_traits/aligned_storage.hpp @@ -47,6 +47,8 @@ union aligned_storage_impl { /// alignment requirement for any object whose size is at most Len. If the /// default value is not used, Align must be the value of alignof(T) for some /// type T, or the behavior is undefined. +/// +/// \ingroup type_traits template )> struct aligned_storage { struct type { @@ -54,6 +56,8 @@ struct aligned_storage { }; }; +/// \relates aligned_storage +/// \ingroup type_traits template )> using aligned_storage_t = typename aligned_storage::type; diff --git a/include/etl/_type_traits/aligned_union.hpp b/include/etl/_type_traits/aligned_union.hpp index 5f8dce3f4..bd0b958b1 100644 --- a/include/etl/_type_traits/aligned_union.hpp +++ b/include/etl/_type_traits/aligned_union.hpp @@ -24,14 +24,18 @@ template /// \brief Provides the nested type type, which is a trivial standard-layout /// type of a size and alignment suitable for use as uninitialized storage for -/// an object of any of the types listed in Types. The size of the storage is at -/// least Len. aligned_union also determines the strictest (largest) alignment -/// requirement among all Types and makes it available as the constant -/// alignment_value. If sizeof...(Types) == 0 or if any of the types in Types is -/// not a complete object type, the behavior is undefined. It is -/// implementation-defined whether any extended alignment is supported. The +/// an object of any of the types listed in Types. +/// +/// The size of the storage is at least Len. aligned_union also determines the +/// strictest (largest) alignment requirement among all Types and makes it +/// available as the constant alignment_value. If sizeof...(Types) == 0 or if +/// any of the types in Types is not a complete object type, the behavior is undefined. +/// +/// It is implementation-defined whether any extended alignment is supported. The /// behavior of a program that adds specializations for aligned_union is /// undefined. +/// +/// \ingroup type_traits template struct aligned_union { static constexpr size_t alignment_value = detail::vmax(alignof(Types)...); @@ -41,6 +45,8 @@ struct aligned_union { }; }; +/// \relates aligned_union +/// \ingroup type_traits template using aligned_union_t = typename aligned_union::type; diff --git a/include/etl/_type_traits/alignment_of.hpp b/include/etl/_type_traits/alignment_of.hpp index 328c501fa..45bbe80e1 100644 --- a/include/etl/_type_traits/alignment_of.hpp +++ b/include/etl/_type_traits/alignment_of.hpp @@ -10,9 +10,11 @@ namespace etl { /// \brief alignment_of +/// \ingroup type_traits template struct alignment_of : integral_constant { }; +/// \ingroup type_traits template inline constexpr size_t alignment_of_v = alignment_of::value; diff --git a/include/etl/_type_traits/always_false.hpp b/include/etl/_type_traits/always_false.hpp index 6513d26ec..6174eb208 100644 --- a/include/etl/_type_traits/always_false.hpp +++ b/include/etl/_type_traits/always_false.hpp @@ -6,6 +6,7 @@ namespace etl { +/// \ingroup type_traits template constexpr bool always_false = false; diff --git a/include/etl/_type_traits/basic_common_reference.hpp b/include/etl/_type_traits/basic_common_reference.hpp index 4de4d2718..313432d5a 100644 --- a/include/etl/_type_traits/basic_common_reference.hpp +++ b/include/etl/_type_traits/basic_common_reference.hpp @@ -9,6 +9,8 @@ namespace etl { /// \brief The class template basic_common_reference is a customization point /// that allows users to influence the result of common_reference for user-defined /// types (typically proxy references). The primary template is empty. +/// +/// \ingroup type_traits template typename TQ, template typename UQ> struct basic_common_reference { }; diff --git a/include/etl/_type_traits/bool_constant.hpp b/include/etl/_type_traits/bool_constant.hpp index 4289b543d..4ed51df21 100644 --- a/include/etl/_type_traits/bool_constant.hpp +++ b/include/etl/_type_traits/bool_constant.hpp @@ -8,10 +8,14 @@ namespace etl { +/// \ingroup type_traits template using bool_constant = integral_constant; -using true_type = bool_constant; +/// \ingroup type_traits +using true_type = bool_constant; + +/// \ingroup type_traits using false_type = bool_constant; } // namespace etl diff --git a/include/etl/_type_traits/conditional.hpp b/include/etl/_type_traits/conditional.hpp index 76d876475..78f419a09 100644 --- a/include/etl/_type_traits/conditional.hpp +++ b/include/etl/_type_traits/conditional.hpp @@ -8,6 +8,7 @@ namespace etl { /// \brief Provides member typedef type, which is defined as T if B is true at /// compile time, or as F if B is false. +/// \ingroup type_traits template struct conditional { using type = T; @@ -18,6 +19,8 @@ struct conditional { using type = F; }; +/// \ingroup type_traits +/// \relates conditional template using conditional_t = typename conditional::type; diff --git a/include/etl/_type_traits/conjunction.hpp b/include/etl/_type_traits/conjunction.hpp index 2da109159..3267dcaa4 100644 --- a/include/etl/_type_traits/conjunction.hpp +++ b/include/etl/_type_traits/conjunction.hpp @@ -11,9 +11,12 @@ namespace etl { /// \brief Forms the logical conjunction of the type traits B..., effectively /// performing a logical AND on the sequence of traits. +/// \ingroup type_traits template struct conjunction : bool_constant<(B::value && ...)> { }; +/// \ingroup type_traits +/// \relates conjunction template inline constexpr bool conjunction_v = conjunction::value; diff --git a/include/etl/_type_traits/copy_cv.hpp b/include/etl/_type_traits/copy_cv.hpp index 843caa0a0..5adc82448 100644 --- a/include/etl/_type_traits/copy_cv.hpp +++ b/include/etl/_type_traits/copy_cv.hpp @@ -10,6 +10,7 @@ namespace etl { +/// \ingroup type_traits template struct copy_cv { using type = T0; @@ -30,8 +31,10 @@ struct copy_cv { using type = add_cv_t; }; -template -using copy_cv_t = typename copy_cv::type; +/// \ingroup type_traits +/// \relates copy_cv +template +using copy_cv_t = typename copy_cv::type; } // namespace etl diff --git a/include/etl/_type_traits/decay.hpp b/include/etl/_type_traits/decay.hpp index f398f5198..7033e412d 100644 --- a/include/etl/_type_traits/decay.hpp +++ b/include/etl/_type_traits/decay.hpp @@ -17,6 +17,8 @@ namespace etl { /// Applies lvalue-to-rvalue, array-to-pointer, and function-to-pointer implicit /// conversions to the type T, removes cv-qualifiers, and defines the resulting /// type as the member typedef type. +/// +/// \ingroup type_traits template struct decay { private: @@ -30,6 +32,7 @@ struct decay { >; }; +/// \ingroup type_traits template using decay_t = typename etl::decay::type; diff --git a/include/etl/_type_traits/declval.hpp b/include/etl/_type_traits/declval.hpp index fc4aaf5c9..358a55734 100644 --- a/include/etl/_type_traits/declval.hpp +++ b/include/etl/_type_traits/declval.hpp @@ -8,6 +8,7 @@ namespace etl { +/// \ingroup type_traits template auto declval() noexcept -> add_rvalue_reference_t; diff --git a/include/etl/_type_traits/disjunction.hpp b/include/etl/_type_traits/disjunction.hpp index 4accefd06..53e5ba0fa 100644 --- a/include/etl/_type_traits/disjunction.hpp +++ b/include/etl/_type_traits/disjunction.hpp @@ -11,9 +11,11 @@ namespace etl { /// Forms the logical disjunction of the type traits B..., effectively /// performing a logical OR on the sequence of traits. +/// \ingroup type_traits template struct disjunction : bool_constant<(B::value or ...)> { }; +/// \ingroup type_traits template inline constexpr bool disjunction_v = disjunction::value; diff --git a/include/etl/_type_traits/enable_if.hpp b/include/etl/_type_traits/enable_if.hpp index 80714a846..4f426e8ad 100644 --- a/include/etl/_type_traits/enable_if.hpp +++ b/include/etl/_type_traits/enable_if.hpp @@ -8,6 +8,7 @@ namespace etl { /// Define a member typedef only if a boolean constant is true. /// /// \include type_traits.cpp +/// \ingroup type_traits template struct enable_if { }; @@ -16,6 +17,7 @@ struct enable_if { using type = Type; }; +/// \ingroup type_traits template using enable_if_t = typename enable_if::type; diff --git a/include/etl/_type_traits/extent.hpp b/include/etl/_type_traits/extent.hpp index fe5e8623d..58c602fe6 100644 --- a/include/etl/_type_traits/extent.hpp +++ b/include/etl/_type_traits/extent.hpp @@ -13,6 +13,7 @@ namespace etl { /// the number of elements along the Nth dimension of the array, if N is in [0, /// rank_v). For any other type, or if T is an array of unknown bound along /// its first dimension and N is 0, value is 0. +/// \ingroup type_traits template struct extent : integral_constant { }; @@ -28,6 +29,7 @@ struct extent : integral_constant { }; template struct extent : extent { }; +/// \ingroup type_traits template inline constexpr auto extent_v = static_cast(extent::value); diff --git a/include/etl/_type_traits/has_unique_object_representations.hpp b/include/etl/_type_traits/has_unique_object_representations.hpp index b1b67b99f..410c2254c 100644 --- a/include/etl/_type_traits/has_unique_object_representations.hpp +++ b/include/etl/_type_traits/has_unique_object_representations.hpp @@ -27,10 +27,13 @@ namespace etl { /// or array of unknown bound. The behavior of a program that adds /// specializations for has_unique_object_representations or /// has_unique_object_representations_v is undefined. +/// +/// \ingroup type_traits template struct has_unique_object_representations : bool_constant<__has_unique_object_representations(remove_cv_t>)> { }; +/// \ingroup type_traits template inline constexpr bool has_unique_object_representations_v = has_unique_object_representations::value; diff --git a/include/etl/_type_traits/index_constant.hpp b/include/etl/_type_traits/index_constant.hpp index 182139088..04d07a8f2 100644 --- a/include/etl/_type_traits/index_constant.hpp +++ b/include/etl/_type_traits/index_constant.hpp @@ -9,9 +9,11 @@ namespace etl { +/// \ingroup type_traits template using index_constant = integral_constant; +/// \ingroup type_traits template inline constexpr auto index_v = index_constant{}; diff --git a/include/etl/_type_traits/integral_constant.hpp b/include/etl/_type_traits/integral_constant.hpp index 5eab5e50c..2f7d1d39b 100644 --- a/include/etl/_type_traits/integral_constant.hpp +++ b/include/etl/_type_traits/integral_constant.hpp @@ -6,6 +6,7 @@ namespace etl { +/// \ingroup type_traits template struct integral_constant { static constexpr Type value = Val; @@ -23,6 +24,8 @@ struct integral_constant { } }; +/// \relates integral_constant +/// \ingroup type_traits template [[nodiscard]] constexpr auto operator+(integral_constant /*l*/, integral_constant /*r*/) -> integral_constant @@ -30,6 +33,8 @@ template return {}; } +/// \relates integral_constant +/// \ingroup type_traits template [[nodiscard]] constexpr auto operator==(integral_constant /*l*/, integral_constant /*r*/) -> integral_constant @@ -37,6 +42,8 @@ template return {}; } +/// \relates integral_constant +/// \ingroup type_traits template [[nodiscard]] constexpr auto operator!=(integral_constant /*l*/, integral_constant /*r*/) -> integral_constant diff --git a/include/etl/_type_traits/is_abstract.hpp b/include/etl/_type_traits/is_abstract.hpp index 38cc39834..5eb4c1f84 100644 --- a/include/etl/_type_traits/is_abstract.hpp +++ b/include/etl/_type_traits/is_abstract.hpp @@ -10,9 +10,11 @@ namespace etl { +/// \ingroup type_traits template struct is_abstract : bool_constant<__is_abstract(T)> { }; +/// \ingroup type_traits template inline constexpr bool is_abstract_v = __is_abstract(T); diff --git a/include/etl/_type_traits/is_aggregate.hpp b/include/etl/_type_traits/is_aggregate.hpp index 9a6637ad4..766e8ca68 100644 --- a/include/etl/_type_traits/is_aggregate.hpp +++ b/include/etl/_type_traits/is_aggregate.hpp @@ -11,9 +11,11 @@ namespace etl { +/// \ingroup type_traits template struct is_aggregate : bool_constant<__is_aggregate(remove_cv_t)> { }; +/// \ingroup type_traits template inline constexpr bool is_aggregate_v = __is_aggregate(remove_cv_t); diff --git a/include/etl/_type_traits/is_arithmetic.hpp b/include/etl/_type_traits/is_arithmetic.hpp index 8592e32a9..a0bfe51b6 100644 --- a/include/etl/_type_traits/is_arithmetic.hpp +++ b/include/etl/_type_traits/is_arithmetic.hpp @@ -15,9 +15,11 @@ namespace etl { /// constant value equal true. For any other type, value is false. The behavior /// of a program that adds specializations for is_arithmetic or is_arithmetic_v /// (since C++17) is undefined. +/// \ingroup type_traits template struct is_arithmetic : bool_constant or is_floating_point_v> { }; +/// \ingroup type_traits template inline constexpr bool is_arithmetic_v = is_integral_v or is_floating_point_v; diff --git a/include/etl/_type_traits/is_array.hpp b/include/etl/_type_traits/is_array.hpp index 158b0505d..7c0e0343b 100644 --- a/include/etl/_type_traits/is_array.hpp +++ b/include/etl/_type_traits/is_array.hpp @@ -12,8 +12,11 @@ namespace etl { /// \brief Checks whether T is an array type. Provides the member constant value /// which is equal to true, if T is an array type. Otherwise, value is equal to /// false. +/// /// \details The behavior of a program that adds specializations for is_array or /// is_array_v is undefined. +/// +/// \ingroup type_traits template struct is_array : false_type { }; @@ -23,6 +26,7 @@ struct is_array : true_type { }; template struct is_array : true_type { }; +/// \ingroup type_traits template inline constexpr bool is_array_v = is_array::value; diff --git a/include/etl/_type_traits/is_assignable.hpp b/include/etl/_type_traits/is_assignable.hpp index 394ac5ee2..1b73cdac8 100644 --- a/include/etl/_type_traits/is_assignable.hpp +++ b/include/etl/_type_traits/is_assignable.hpp @@ -14,9 +14,11 @@ namespace etl { /// well-formed in unevaluated context, provides the member constant value equal /// true. Otherwise, value is false. Access checks are performed as if from a /// context unrelated to either type. +/// \ingroup type_traits template struct is_assignable : bool_constant<__is_assignable(T, U)> { }; +/// \ingroup type_traits template inline constexpr bool is_assignable_v = __is_assignable(T, U); diff --git a/include/etl/_type_traits/is_base_of.hpp b/include/etl/_type_traits/is_base_of.hpp index b98ecc65c..9c4e99789 100644 --- a/include/etl/_type_traits/is_base_of.hpp +++ b/include/etl/_type_traits/is_base_of.hpp @@ -30,12 +30,16 @@ auto test_pre_is_base_of(int) -> decltype(test_pre_ptr_convertible(static_cas /// type; otherwise the behavior is undefined. /// /// https://en.cppreference.com/w/cpp/types/is_base_of +/// +/// \ingroup type_traits template struct is_base_of : bool_constant< is_class_v and is_class_vand decltype(detail::test_pre_is_base_of(0))::value > { }; +/// \relates is_base_of +/// \ingroup type_traits template inline constexpr bool is_base_of_v = is_base_of::value; diff --git a/include/etl/_type_traits/is_bounded_array.hpp b/include/etl/_type_traits/is_bounded_array.hpp index f14932321..0631938bb 100644 --- a/include/etl/_type_traits/is_bounded_array.hpp +++ b/include/etl/_type_traits/is_bounded_array.hpp @@ -12,12 +12,15 @@ namespace etl { /// \brief Checks whether T is an array type of known bound. Provides the member /// constant value which is equal to true, if T is an array type of known bound. /// Otherwise, value is equal to false. +/// +/// \ingroup type_traits template struct is_bounded_array : false_type { }; template struct is_bounded_array : true_type { }; +/// \ingroup type_traits template inline constexpr bool is_bounded_array_v = is_bounded_array::value; diff --git a/include/etl/_type_traits/is_builtin_integer.hpp b/include/etl/_type_traits/is_builtin_integer.hpp index 5add4a621..560aa923e 100644 --- a/include/etl/_type_traits/is_builtin_integer.hpp +++ b/include/etl/_type_traits/is_builtin_integer.hpp @@ -10,10 +10,12 @@ namespace etl { +/// \ingroup type_traits template struct is_builtin_integer : bool_constant or is_builtin_signed_integer_v> { }; /// \relates is_builtin_integer +/// \ingroup type_traits template inline constexpr auto is_builtin_integer_v = is_builtin_integer::value; diff --git a/include/etl/_type_traits/is_builtin_signed_integer.hpp b/include/etl/_type_traits/is_builtin_signed_integer.hpp index 9ba6d1fb2..e66af3995 100644 --- a/include/etl/_type_traits/is_builtin_signed_integer.hpp +++ b/include/etl/_type_traits/is_builtin_signed_integer.hpp @@ -10,11 +10,13 @@ namespace etl { +/// \ingroup type_traits template struct is_builtin_signed_integer : bool_constant, mpl::list>> { }; /// \relates is_builtin_signed_integer +/// \ingroup type_traits template inline constexpr auto is_builtin_signed_integer_v = is_builtin_signed_integer::value; diff --git a/include/etl/_type_traits/is_builtin_unsigned_integer.hpp b/include/etl/_type_traits/is_builtin_unsigned_integer.hpp index d5a17b679..5de453d7e 100644 --- a/include/etl/_type_traits/is_builtin_unsigned_integer.hpp +++ b/include/etl/_type_traits/is_builtin_unsigned_integer.hpp @@ -11,6 +11,7 @@ namespace etl { /// True if T is `unsigned char` or `unsigned short` or `unsigned int` or `unsigned long` or `unsigned long long` +/// \ingroup type_traits template struct is_builtin_unsigned_integer : bool_constant> { }; /// \relates is_builtin_unsigned_integer +/// \ingroup type_traits template inline constexpr auto is_builtin_unsigned_integer_v = is_builtin_unsigned_integer::value; +/// @} + } // namespace etl #endif // TETL_TYPE_TRAITS_IS_BUILTIN_UNSIGNED_INTEGER_HPP diff --git a/include/etl/_type_traits/is_class.hpp b/include/etl/_type_traits/is_class.hpp index 706b3e4a2..03cdadaed 100644 --- a/include/etl/_type_traits/is_class.hpp +++ b/include/etl/_type_traits/is_class.hpp @@ -10,9 +10,11 @@ namespace etl { +/// \ingroup type_traits template struct is_class : bool_constant<__is_class(T)> { }; +/// \ingroup type_traits template inline constexpr bool is_class_v = __is_class(T); From ddba2d032ae1eabd591d76f2ea0dadc99dfbb160 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Thu, 11 Sep 2025 22:41:31 +0200 Subject: [PATCH 18/34] [cmath] Use builtin abs & fabs for floating-point --- include/etl/_cmath/fabs.hpp | 47 +++++++++++++++++ include/etl/_complex/log.hpp | 2 +- include/etl/_cstdlib/labs.hpp | 2 +- include/etl/_cstdlib/llabs.hpp | 2 +- include/etl/_math/abs.hpp | 95 ++++++++++++++++------------------ include/etl/cmath.hpp | 1 + 6 files changed, 97 insertions(+), 52 deletions(-) create mode 100644 include/etl/_cmath/fabs.hpp diff --git a/include/etl/_cmath/fabs.hpp b/include/etl/_cmath/fabs.hpp new file mode 100644 index 000000000..d2157f0a7 --- /dev/null +++ b/include/etl/_cmath/fabs.hpp @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: BSL-1.0 +// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch + +#ifndef TETL_CMATH_FABS_HPP +#define TETL_CMATH_FABS_HPP + +#include + +namespace etl { + +/// \ingroup cmath +/// @{ + +/// Returns the larger of two floating point arguments, treating NaNs as +/// missing data (between a NaN and a numeric value, the numeric value is chosen) +/// +/// https://en.cppreference.com/w/cpp/numeric/math/fabs +[[nodiscard]] constexpr auto fabs(float arg) noexcept -> float +{ + return etl::detail::fabs(arg); +} + +[[nodiscard]] constexpr auto fabsf(float arg) noexcept -> float +{ + return etl::detail::fabs(arg); +} + +[[nodiscard]] constexpr auto fabs(double arg) noexcept -> double +{ + return etl::detail::fabs(arg); +} + +[[nodiscard]] constexpr auto fabs(long double arg) noexcept -> long double +{ + return etl::detail::fabs(arg); +} + +[[nodiscard]] constexpr auto fabsl(long double arg) noexcept -> long double +{ + return etl::detail::fabs(arg); +} + +/// @} + +} // namespace etl + +#endif // TETL_CMATH_FABS_HPP diff --git a/include/etl/_complex/log.hpp b/include/etl/_complex/log.hpp index 27c143f88..65502628b 100644 --- a/include/etl/_complex/log.hpp +++ b/include/etl/_complex/log.hpp @@ -5,9 +5,9 @@ #define TETL_COMPLEX_LOG_HPP #include +#include #include #include -#include namespace etl { diff --git a/include/etl/_cstdlib/labs.hpp b/include/etl/_cstdlib/labs.hpp index 8e19dbc75..28ec1355a 100644 --- a/include/etl/_cstdlib/labs.hpp +++ b/include/etl/_cstdlib/labs.hpp @@ -14,7 +14,7 @@ namespace etl { /// by integral promotion, the program is ill-formed. [[nodiscard]] constexpr auto labs(long n) noexcept -> long { - return detail::abs_impl(n); + return etl::detail::abs(n); } } // namespace etl diff --git a/include/etl/_cstdlib/llabs.hpp b/include/etl/_cstdlib/llabs.hpp index f076fcf83..5621deb1a 100644 --- a/include/etl/_cstdlib/llabs.hpp +++ b/include/etl/_cstdlib/llabs.hpp @@ -14,7 +14,7 @@ namespace etl { /// by integral promotion, the program is ill-formed. [[nodiscard]] constexpr auto llabs(long long n) noexcept -> long long { - return detail::abs_impl(n); + return etl::detail::abs(n); } } // namespace etl diff --git a/include/etl/_math/abs.hpp b/include/etl/_math/abs.hpp index 99ce723e1..2e91c2c1d 100644 --- a/include/etl/_math/abs.hpp +++ b/include/etl/_math/abs.hpp @@ -4,22 +4,44 @@ #ifndef TETL_MATH_ABS_HPP #define TETL_MATH_ABS_HPP +#include + +#include +#include + namespace etl { namespace detail { -template -[[nodiscard]] constexpr auto abs_impl(T n) noexcept -> T -{ - // constexpr auto isInt = is_same_v; - // constexpr auto isLong = is_same_v; - // constexpr auto isLongLong = is_same_v; - // static_assert(isInt || isLong || isLongLong); - - if (n >= T(0)) { - return n; +inline constexpr struct abs { + template + [[nodiscard]] constexpr auto operator()(T arg) const noexcept -> T + { + if (arg >= T(0)) { + return arg; + } + return arg * T(-1); } - return n * T(-1); -} +} abs; + +inline constexpr struct fabs { + template + [[nodiscard]] constexpr auto operator()(Float arg) const noexcept -> Float + { + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_fabsf) + if constexpr (etl::same_as) { + return __builtin_fabsf(arg); + } +#endif +#if __has_builtin(__builtin_fabs) + if constexpr (etl::same_as) { + return __builtin_fabs(arg); + } +#endif + } + return etl::detail::abs(arg); + } +} fabs; } // namespace detail @@ -27,59 +49,34 @@ template /// undefined if the result cannot be represented by the return type. If abs /// is called with an unsigned integral argument that cannot be converted to int /// by integral promotion, the program is ill-formed. -[[nodiscard]] constexpr auto abs(int n) noexcept -> int -{ - return detail::abs_impl(n); -} - -[[nodiscard]] constexpr auto abs(long n) noexcept -> long -{ - return detail::abs_impl(n); -} - -[[nodiscard]] constexpr auto abs(long long n) noexcept -> long long -{ - return detail::abs_impl(n); -} - -[[nodiscard]] constexpr auto abs(float n) noexcept -> float -{ - return detail::abs_impl(n); -} - -[[nodiscard]] constexpr auto abs(double n) noexcept -> double -{ - return detail::abs_impl(n); -} - -[[nodiscard]] constexpr auto abs(long double n) noexcept -> long double +[[nodiscard]] constexpr auto abs(int arg) noexcept -> int { - return detail::abs_impl(n); + return etl::detail::abs(arg); } -[[nodiscard]] constexpr auto fabs(float n) noexcept -> float +[[nodiscard]] constexpr auto abs(long arg) noexcept -> long { - return detail::abs_impl(n); + return etl::detail::abs(arg); } -[[nodiscard]] constexpr auto fabsf(float n) noexcept -> float +[[nodiscard]] constexpr auto abs(long long arg) noexcept -> long long { - return detail::abs_impl(n); + return etl::detail::abs(arg); } -[[nodiscard]] constexpr auto fabs(double n) noexcept -> double +[[nodiscard]] constexpr auto abs(float arg) noexcept -> float { - return detail::abs_impl(n); + return etl::detail::abs(arg); } -[[nodiscard]] constexpr auto fabs(long double n) noexcept -> long double +[[nodiscard]] constexpr auto abs(double arg) noexcept -> double { - return detail::abs_impl(n); + return etl::detail::abs(arg); } -[[nodiscard]] constexpr auto fabsl(long double n) noexcept -> long double +[[nodiscard]] constexpr auto abs(long double arg) noexcept -> long double { - return detail::abs_impl(n); + return etl::detail::abs(arg); } } // namespace etl diff --git a/include/etl/cmath.hpp b/include/etl/cmath.hpp index ba9f11168..1fa13ae8b 100644 --- a/include/etl/cmath.hpp +++ b/include/etl/cmath.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include From 2187a3732d2b9714af524b8f8e588e389585fab9 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Thu, 11 Sep 2025 22:50:22 +0200 Subject: [PATCH 19/34] [complex] Merge private headers --- include/etl/_complex/abs.hpp | 21 ---- include/etl/_complex/arg.hpp | 37 ------ include/etl/_complex/complex.hpp | 182 ++++++++++++++++++++++++++++- include/etl/_complex/conj.hpp | 36 ------ include/etl/_complex/cos.hpp | 26 ----- include/etl/_complex/cosh.hpp | 26 ----- include/etl/_complex/imag.hpp | 36 ------ include/etl/_complex/log.hpp | 23 ---- include/etl/_complex/log10.hpp | 21 ---- include/etl/_complex/norm.hpp | 38 ------ include/etl/_complex/polar.hpp | 22 ---- include/etl/_complex/real.hpp | 36 ------ include/etl/_complex/sin.hpp | 26 ----- include/etl/_complex/sinh.hpp | 29 ----- include/etl/_complex/tan.hpp | 22 ---- include/etl/_complex/tanh.hpp | 22 ---- include/etl/_linalg/exposition.hpp | 4 - include/etl/complex.hpp | 15 --- 18 files changed, 181 insertions(+), 441 deletions(-) delete mode 100644 include/etl/_complex/abs.hpp delete mode 100644 include/etl/_complex/arg.hpp delete mode 100644 include/etl/_complex/conj.hpp delete mode 100644 include/etl/_complex/cos.hpp delete mode 100644 include/etl/_complex/cosh.hpp delete mode 100644 include/etl/_complex/imag.hpp delete mode 100644 include/etl/_complex/log.hpp delete mode 100644 include/etl/_complex/log10.hpp delete mode 100644 include/etl/_complex/norm.hpp delete mode 100644 include/etl/_complex/polar.hpp delete mode 100644 include/etl/_complex/real.hpp delete mode 100644 include/etl/_complex/sin.hpp delete mode 100644 include/etl/_complex/sinh.hpp delete mode 100644 include/etl/_complex/tan.hpp delete mode 100644 include/etl/_complex/tanh.hpp diff --git a/include/etl/_complex/abs.hpp b/include/etl/_complex/abs.hpp deleted file mode 100644 index 252c6d2f2..000000000 --- a/include/etl/_complex/abs.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_COMPLEX_ABS_HPP -#define TETL_COMPLEX_ABS_HPP - -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto abs(complex const& z) -> T -{ - return hypot(z.real(), z.imag()); -} - -} // namespace etl - -#endif // TETL_COMPLEX_ABS_HPP diff --git a/include/etl/_complex/arg.hpp b/include/etl/_complex/arg.hpp deleted file mode 100644 index 71b578cc0..000000000 --- a/include/etl/_complex/arg.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_COMPLEX_ARG_HPP -#define TETL_COMPLEX_ARG_HPP - -#include -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto arg(complex const& z) noexcept -> T -{ - return etl::atan2(z.imag(), z.real()); -} - -/// \ingroup complex -template -[[nodiscard]] constexpr auto arg(Float f) noexcept -> complex -{ - return etl::arg(etl::complex(f)); -} - -/// \ingroup complex -template -[[nodiscard]] constexpr auto arg(Integer i) noexcept -> complex -{ - return etl::arg(etl::complex(i)); -} - -} // namespace etl - -#endif // TETL_COMPLEX_ARG_HPP diff --git a/include/etl/_complex/complex.hpp b/include/etl/_complex/complex.hpp index 700853800..ec5ea3b57 100644 --- a/include/etl/_complex/complex.hpp +++ b/include/etl/_complex/complex.hpp @@ -4,6 +4,15 @@ #ifndef TETL_COMPLEX_COMPLEX_HPP #define TETL_COMPLEX_COMPLEX_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -13,9 +22,12 @@ namespace etl { +/// \ingroup algorithm +/// @{ + /// \brief A complex number /// \headerfile etl/complex.hpp -/// \ingroup complex + template struct complex { using value_type = T; @@ -374,6 +386,174 @@ constexpr auto operator""_if(unsigned long long d) -> complex } // namespace complex_literals } // namespace literals +template +[[nodiscard]] constexpr auto abs(complex const& z) -> T +{ + return hypot(z.real(), z.imag()); +} + +template +[[nodiscard]] constexpr auto arg(complex const& z) noexcept -> T +{ + return etl::atan2(z.imag(), z.real()); +} + +template +[[nodiscard]] constexpr auto arg(Float f) noexcept -> complex +{ + return etl::arg(etl::complex(f)); +} + +template +[[nodiscard]] constexpr auto arg(Integer i) noexcept -> complex +{ + return etl::arg(etl::complex(i)); +} + +template +[[nodiscard]] constexpr auto conj(complex const& z) noexcept -> complex +{ + return complex(z.real(), -z.imag()); +} + +template +[[nodiscard]] constexpr auto conj(Float f) noexcept -> complex +{ + return complex(f); +} + +template +[[nodiscard]] constexpr auto conj(Integer i) noexcept -> complex +{ + return complex(static_cast(i)); +} + +template +[[nodiscard]] constexpr auto cos(complex const& z) -> complex +{ + auto const x = z.real(); + auto const y = z.imag(); + return {cos(x) * cosh(y), -sin(x) * sinh(y)}; +} + +template +[[nodiscard]] constexpr auto cosh(complex const& z) -> complex +{ + auto const x = z.real(); + auto const y = z.imag(); + return {cosh(x) * cos(y), sinh(x) * sin(y)}; +} + +template +[[nodiscard]] constexpr auto imag(complex const& z) noexcept(noexcept(z.imag())) -> T +{ + return z.imag(); +} + +template +[[nodiscard]] constexpr auto imag(Float /*f*/) noexcept -> Float +{ + return Float{}; +} + +template +[[nodiscard]] constexpr auto imag(Integer /*i*/) noexcept -> double +{ + return 0.0; +} + +template +[[nodiscard]] constexpr auto log(complex const& z) noexcept -> complex +{ + return {etl::log(etl::abs(z)), etl::arg(z)}; +} + +template +[[nodiscard]] constexpr auto log10(complex const& z) noexcept -> complex +{ + return etl::log(z) / etl::log(T(10)); +} + +template +[[nodiscard]] constexpr auto norm(complex const& z) noexcept -> T +{ + auto const x = z.real(); + auto const y = z.imag(); + return x * x + y * y; +} + +template +[[nodiscard]] constexpr auto norm(Float f) noexcept -> complex +{ + return etl::norm(etl::complex(f)); +} + +template +[[nodiscard]] constexpr auto norm(Integer i) noexcept -> complex +{ + return etl::norm(etl::complex(i)); +} + +template +[[nodiscard]] constexpr auto polar(T const& r, T const& theta = T()) noexcept -> etl::complex +{ + return etl::complex{r * etl::cos(theta), r * etl::sin(theta)}; +} + +template +[[nodiscard]] constexpr auto real(complex const& z) noexcept(noexcept(z.real())) -> T +{ + return z.real(); +} + +template +[[nodiscard]] constexpr auto real(Float f) noexcept -> Float +{ + return f; +} + +template +[[nodiscard]] constexpr auto real(Integer i) noexcept -> double +{ + return static_cast(i); +} + +template +[[nodiscard]] constexpr auto sin(complex const& z) -> complex +{ + auto const x = z.real(); + auto const y = z.imag(); + return { + etl::sin(x) * etl::cosh(y), + etl::cos(x) * etl::sinh(y), + }; +} + +template +[[nodiscard]] constexpr auto sinh(complex const& z) -> complex +{ + auto const x = z.real(); + auto const y = z.imag(); + return { + etl::sinh(x) * etl::cos(y), + etl::cosh(x) * etl::sin(y), + }; +} + +template +[[nodiscard]] constexpr auto tan(complex const& z) -> complex +{ + return etl::sin(z) / etl::cos(z); +} + +template +[[nodiscard]] constexpr auto tanh(complex const& z) -> complex +{ + return etl::sinh(z) / etl::cosh(z); +} + +/// @} + } // namespace etl #endif // TETL_COMPLEX_COMPLEX_HPP diff --git a/include/etl/_complex/conj.hpp b/include/etl/_complex/conj.hpp deleted file mode 100644 index 7d30c1e18..000000000 --- a/include/etl/_complex/conj.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_COMPLEX_CONJ_HPP -#define TETL_COMPLEX_CONJ_HPP - -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto conj(complex const& z) noexcept -> complex -{ - return complex(z.real(), -z.imag()); -} - -/// \ingroup complex -template -[[nodiscard]] constexpr auto conj(Float f) noexcept -> complex -{ - return complex(f); -} - -/// \ingroup complex -template -[[nodiscard]] constexpr auto conj(Integer i) noexcept -> complex -{ - return complex(static_cast(i)); -} - -} // namespace etl - -#endif // TETL_COMPLEX_CONJ_HPP diff --git a/include/etl/_complex/cos.hpp b/include/etl/_complex/cos.hpp deleted file mode 100644 index ee4fcbdf0..000000000 --- a/include/etl/_complex/cos.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_COMPLEX_COS_HPP -#define TETL_COMPLEX_COS_HPP - -#include -#include -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto cos(complex const& z) -> complex -{ - auto const x = z.real(); - auto const y = z.imag(); - return {cos(x) * cosh(y), -sin(x) * sinh(y)}; -} - -} // namespace etl - -#endif // TETL_COMPLEX_COS_HPP diff --git a/include/etl/_complex/cosh.hpp b/include/etl/_complex/cosh.hpp deleted file mode 100644 index b0e328380..000000000 --- a/include/etl/_complex/cosh.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_COMPLEX_COSH_HPP -#define TETL_COMPLEX_COSH_HPP - -#include -#include -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto cosh(complex const& z) -> complex -{ - auto const x = z.real(); - auto const y = z.imag(); - return {cosh(x) * cos(y), sinh(x) * sin(y)}; -} - -} // namespace etl - -#endif // TETL_COMPLEX_COSH_HPP diff --git a/include/etl/_complex/imag.hpp b/include/etl/_complex/imag.hpp deleted file mode 100644 index edf48333e..000000000 --- a/include/etl/_complex/imag.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2019 Tobias Hienzsch - -#ifndef TETL_COMPLEX_IMAG_HPP -#define TETL_COMPLEX_IMAG_HPP - -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto imag(complex const& z) noexcept(noexcept(z.imag())) -> T -{ - return z.imag(); -} - -/// \ingroup complex -template -[[nodiscard]] constexpr auto imag(Float /*f*/) noexcept -> Float -{ - return Float{}; -} - -/// \ingroup complex -template -[[nodiscard]] constexpr auto imag(Integer /*i*/) noexcept -> double -{ - return 0.0; -} - -} // namespace etl - -#endif // TETL_COMPLEX_IMAG_HPP diff --git a/include/etl/_complex/log.hpp b/include/etl/_complex/log.hpp deleted file mode 100644 index 65502628b..000000000 --- a/include/etl/_complex/log.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_COMPLEX_LOG_HPP -#define TETL_COMPLEX_LOG_HPP - -#include -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto log(complex const& z) noexcept -> complex -{ - return {etl::log(etl::abs(z)), etl::arg(z)}; -} - -} // namespace etl - -#endif // TETL_COMPLEX_LOG_HPP diff --git a/include/etl/_complex/log10.hpp b/include/etl/_complex/log10.hpp deleted file mode 100644 index ca7af7177..000000000 --- a/include/etl/_complex/log10.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_COMPLEX_LOG10_HPP -#define TETL_COMPLEX_LOG10_HPP - -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto log10(complex const& z) noexcept -> complex -{ - return etl::log(z) / etl::log(T(10)); -} - -} // namespace etl - -#endif // TETL_COMPLEX_LOG10_HPP diff --git a/include/etl/_complex/norm.hpp b/include/etl/_complex/norm.hpp deleted file mode 100644 index d3ea37170..000000000 --- a/include/etl/_complex/norm.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_COMPLEX_NORM_HPP -#define TETL_COMPLEX_NORM_HPP - -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto norm(complex const& z) noexcept -> T -{ - auto const x = z.real(); - auto const y = z.imag(); - return x * x + y * y; -} - -/// \ingroup complex -template -[[nodiscard]] constexpr auto norm(Float f) noexcept -> complex -{ - return etl::norm(etl::complex(f)); -} - -/// \ingroup complex -template -[[nodiscard]] constexpr auto norm(Integer i) noexcept -> complex -{ - return etl::norm(etl::complex(i)); -} - -} // namespace etl - -#endif // TETL_COMPLEX_NORM_HPP diff --git a/include/etl/_complex/polar.hpp b/include/etl/_complex/polar.hpp deleted file mode 100644 index 489f155ff..000000000 --- a/include/etl/_complex/polar.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch - -#ifndef TETL_COMPLEX_POLAR_HPP -#define TETL_COMPLEX_POLAR_HPP - -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto polar(T const& r, T const& theta = T()) noexcept -> etl::complex -{ - return etl::complex{r * etl::cos(theta), r * etl::sin(theta)}; -} - -} // namespace etl - -#endif // TETL_COMPLEX_POLAR_HPP diff --git a/include/etl/_complex/real.hpp b/include/etl/_complex/real.hpp deleted file mode 100644 index 0814216b2..000000000 --- a/include/etl/_complex/real.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2019 Tobias Hienzsch - -#ifndef TETL_COMPLEX_REAL_HPP -#define TETL_COMPLEX_REAL_HPP - -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto real(complex const& z) noexcept(noexcept(z.real())) -> T -{ - return z.real(); -} - -/// \ingroup complex -template -[[nodiscard]] constexpr auto real(Float f) noexcept -> Float -{ - return f; -} - -/// \ingroup complex -template -[[nodiscard]] constexpr auto real(Integer i) noexcept -> double -{ - return static_cast(i); -} - -} // namespace etl - -#endif // TETL_COMPLEX_REAL_HPP diff --git a/include/etl/_complex/sin.hpp b/include/etl/_complex/sin.hpp deleted file mode 100644 index e54f58be3..000000000 --- a/include/etl/_complex/sin.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_COMPLEX_SIN_HPP -#define TETL_COMPLEX_SIN_HPP - -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto sin(complex const& z) -> complex -{ - auto const x = z.real(); - auto const y = z.imag(); - return { - etl::sin(x) * etl::cosh(y), - etl::cos(x) * etl::sinh(y), - }; -} - -} // namespace etl - -#endif // TETL_COMPLEX_SIN_HPP diff --git a/include/etl/_complex/sinh.hpp b/include/etl/_complex/sinh.hpp deleted file mode 100644 index 256a35aba..000000000 --- a/include/etl/_complex/sinh.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_COMPLEX_SINH_HPP -#define TETL_COMPLEX_SINH_HPP - -#include -#include -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto sinh(complex const& z) -> complex -{ - auto const x = z.real(); - auto const y = z.imag(); - return { - etl::sinh(x) * etl::cos(y), - etl::cosh(x) * etl::sin(y), - }; -} - -} // namespace etl - -#endif // TETL_COMPLEX_SINH_HPP diff --git a/include/etl/_complex/tan.hpp b/include/etl/_complex/tan.hpp deleted file mode 100644 index 477a2e875..000000000 --- a/include/etl/_complex/tan.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_COMPLEX_TAN_HPP -#define TETL_COMPLEX_TAN_HPP - -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto tan(complex const& z) -> complex -{ - return etl::sin(z) / etl::cos(z); -} - -} // namespace etl - -#endif // TETL_COMPLEX_TAN_HPP diff --git a/include/etl/_complex/tanh.hpp b/include/etl/_complex/tanh.hpp deleted file mode 100644 index 14754c0ae..000000000 --- a/include/etl/_complex/tanh.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: BSL-1.0 -// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch - -#ifndef TETL_COMPLEX_TANH_HPP -#define TETL_COMPLEX_TANH_HPP - -#include -#include -#include - -namespace etl { - -/// \ingroup complex -template -[[nodiscard]] constexpr auto tanh(complex const& z) -> complex -{ - return etl::sinh(z) / etl::cosh(z); -} - -} // namespace etl - -#endif // TETL_COMPLEX_TANH_HPP diff --git a/include/etl/_linalg/exposition.hpp b/include/etl/_linalg/exposition.hpp index 709a8b1b7..5bd0f04fb 100644 --- a/include/etl/_linalg/exposition.hpp +++ b/include/etl/_linalg/exposition.hpp @@ -4,11 +4,7 @@ #ifndef TETL_LINALG_EXPOSITION_HPP #define TETL_LINALG_EXPOSITION_HPP -#include #include -#include -#include -#include #include #include #include diff --git a/include/etl/complex.hpp b/include/etl/complex.hpp index 3861c18cf..c497ee127 100644 --- a/include/etl/complex.hpp +++ b/include/etl/complex.hpp @@ -13,21 +13,6 @@ #include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #endif // TETL_COMPLEX_HPP From b5956a8fedd952b51ef3d3ca37e0dc99a98e881c Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Sun, 14 Sep 2025 20:03:34 +0200 Subject: [PATCH 20/34] [complex] Fix doxygen tag --- include/etl/_complex/complex.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/etl/_complex/complex.hpp b/include/etl/_complex/complex.hpp index ec5ea3b57..5c9130fda 100644 --- a/include/etl/_complex/complex.hpp +++ b/include/etl/_complex/complex.hpp @@ -22,7 +22,7 @@ namespace etl { -/// \ingroup algorithm +/// \ingroup complex /// @{ /// \brief A complex number From d2103cbdbc9ba06bff118f4f8323fd55b009c570 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Sun, 14 Sep 2025 20:16:23 +0200 Subject: [PATCH 21/34] [cmath] Improve ipow --- include/etl/_math/ipow.hpp | 20 ++++++++++++++----- tests/cmath/ipow.t.cpp | 39 +++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/include/etl/_math/ipow.hpp b/include/etl/_math/ipow.hpp index 318cd0b74..93b911378 100644 --- a/include/etl/_math/ipow.hpp +++ b/include/etl/_math/ipow.hpp @@ -4,11 +4,12 @@ #ifndef TETL_MATH_IPOW_HPP #define TETL_MATH_IPOW_HPP -#include +#include +#include namespace etl { -template +template [[nodiscard]] constexpr auto ipow(Int base, Int exponent) noexcept -> Int { auto result = Int(1); @@ -18,13 +19,22 @@ template return result; } -template +template [[nodiscard]] constexpr auto ipow(decltype(Base) exponent) noexcept -> decltype(Base) { - using Int = decltype(Base); + using Int = decltype(Base); + using UInt = etl::make_unsigned_t; if constexpr (Base == Int(2)) { - return static_cast(Int(1) << exponent); + return static_cast(UInt(1) << UInt(exponent)); + } else if constexpr (Base == Int(4)) { + return static_cast(UInt(1) << UInt(exponent * Int(2))); + } else if constexpr (Base == Int(8)) { + return static_cast(UInt(1) << UInt(exponent * Int(3))); + } else if constexpr (Base == Int(16)) { + return static_cast(UInt(1) << UInt(exponent * Int(4))); + } else if constexpr (Base == Int(32)) { + return static_cast(UInt(1) << UInt(exponent * Int(5))); } else { return ipow(Base, exponent); } diff --git a/tests/cmath/ipow.t.cpp b/tests/cmath/ipow.t.cpp index e06bd0ac9..468eb2ede 100644 --- a/tests/cmath/ipow.t.cpp +++ b/tests/cmath/ipow.t.cpp @@ -11,26 +11,39 @@ import etl; #include #endif -template +template static constexpr auto test() -> bool { static_assert(etl::same_as(), etl::declval())), Int>); - CHECK(etl::ipow(1, 0) == 1); - CHECK(etl::ipow(1, 1) == 1); - CHECK(etl::ipow(1, 2) == 1); + CHECK(etl::ipow(Int(1), Int(0)) == Int(1)); + CHECK(etl::ipow(Int(1), Int(1)) == Int(1)); + CHECK(etl::ipow(Int(1), Int(2)) == Int(1)); - CHECK(etl::ipow(2, 0) == 1); - CHECK(etl::ipow(2, 1) == 2); - CHECK(etl::ipow(2, 2) == 4); + CHECK(etl::ipow(Int(2), Int(0)) == Int(1)); + CHECK(etl::ipow(Int(2), Int(1)) == Int(2)); + CHECK(etl::ipow(Int(2), Int(2)) == Int(4)); - CHECK(etl::ipow<1>(0) == 1); - CHECK(etl::ipow<1>(1) == 1); - CHECK(etl::ipow<1>(2) == 1); + CHECK(etl::ipow(Int(0)) == Int(1)); + CHECK(etl::ipow(Int(1)) == Int(1)); + CHECK(etl::ipow(Int(2)) == Int(1)); - CHECK(etl::ipow<2>(0) == 1); - CHECK(etl::ipow<2>(1) == 2); - CHECK(etl::ipow<2>(2) == 4); + CHECK(etl::ipow(Int(0)) == Int(1)); + CHECK(etl::ipow(Int(1)) == Int(2)); + CHECK(etl::ipow(Int(2)) == Int(4)); + + CHECK(etl::ipow(Int(1)) == Int(8)); + CHECK(etl::ipow(Int(1)) == Int(16)); + CHECK(etl::ipow(Int(1)) == Int(32)); + CHECK(etl::ipow(Int(1)) == Int(64)); + + CHECK(etl::ipow(Int(2)) == Int(64)); + + if constexpr (sizeof(Int) > 1) { + CHECK(etl::ipow(Int(2)) == Int(256)); + CHECK(etl::ipow(Int(2)) == Int(1024)); + CHECK(etl::ipow(Int(2)) == Int(4096)); + } return true; } From adb3b7fcece1622826f33e61902af1c6bb2e6971 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Sun, 14 Sep 2025 20:17:09 +0200 Subject: [PATCH 22/34] Upgrade pre-commit hooks --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 514ba1a49..4595e2699 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,6 +31,6 @@ repos: types_or: [c++, c] - repo: https://github.com/fsfe/reuse-tool - rev: v5.0.2 + rev: v5.1.1 hooks: - id: reuse From 6f983dd71daa00a6b985a8ae59a0e6a2cb6a65d2 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 15:23:08 +0200 Subject: [PATCH 23/34] [cmath] Improve type deduction in ipow --- include/etl/_math/ipow.hpp | 17 ++++++++--------- tests/cmath/ipow.t.cpp | 28 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/include/etl/_math/ipow.hpp b/include/etl/_math/ipow.hpp index 93b911378..8ab037ff3 100644 --- a/include/etl/_math/ipow.hpp +++ b/include/etl/_math/ipow.hpp @@ -19,24 +19,23 @@ template return result; } -template -[[nodiscard]] constexpr auto ipow(decltype(Base) exponent) noexcept -> decltype(Base) +template +[[nodiscard]] constexpr auto ipow(Int exponent) noexcept -> Int { - using Int = decltype(Base); using UInt = etl::make_unsigned_t; - if constexpr (Base == Int(2)) { + if constexpr (Base == 2ULL) { return static_cast(UInt(1) << UInt(exponent)); - } else if constexpr (Base == Int(4)) { + } else if constexpr (Base == 4ULL) { return static_cast(UInt(1) << UInt(exponent * Int(2))); - } else if constexpr (Base == Int(8)) { + } else if constexpr (Base == 8ULL) { return static_cast(UInt(1) << UInt(exponent * Int(3))); - } else if constexpr (Base == Int(16)) { + } else if constexpr (Base == 16ULL) { return static_cast(UInt(1) << UInt(exponent * Int(4))); - } else if constexpr (Base == Int(32)) { + } else if constexpr (Base == 32ULL) { return static_cast(UInt(1) << UInt(exponent * Int(5))); } else { - return ipow(Base, exponent); + return etl::ipow(static_cast(Base), exponent); } } diff --git a/tests/cmath/ipow.t.cpp b/tests/cmath/ipow.t.cpp index 468eb2ede..9ae164be6 100644 --- a/tests/cmath/ipow.t.cpp +++ b/tests/cmath/ipow.t.cpp @@ -24,25 +24,25 @@ static constexpr auto test() -> bool CHECK(etl::ipow(Int(2), Int(1)) == Int(2)); CHECK(etl::ipow(Int(2), Int(2)) == Int(4)); - CHECK(etl::ipow(Int(0)) == Int(1)); - CHECK(etl::ipow(Int(1)) == Int(1)); - CHECK(etl::ipow(Int(2)) == Int(1)); + CHECK(etl::ipow<1>(Int(0)) == Int(1)); + CHECK(etl::ipow<1>(Int(1)) == Int(1)); + CHECK(etl::ipow<1>(Int(2)) == Int(1)); - CHECK(etl::ipow(Int(0)) == Int(1)); - CHECK(etl::ipow(Int(1)) == Int(2)); - CHECK(etl::ipow(Int(2)) == Int(4)); + CHECK(etl::ipow<2>(Int(0)) == Int(1)); + CHECK(etl::ipow<2>(Int(1)) == Int(2)); + CHECK(etl::ipow<2>(Int(2)) == Int(4)); - CHECK(etl::ipow(Int(1)) == Int(8)); - CHECK(etl::ipow(Int(1)) == Int(16)); - CHECK(etl::ipow(Int(1)) == Int(32)); - CHECK(etl::ipow(Int(1)) == Int(64)); + CHECK(etl::ipow<8>(Int(1)) == Int(8)); + CHECK(etl::ipow<16>(Int(1)) == Int(16)); + CHECK(etl::ipow<32>(Int(1)) == Int(32)); + CHECK(etl::ipow<64>(Int(1)) == Int(64)); - CHECK(etl::ipow(Int(2)) == Int(64)); + CHECK(etl::ipow<8>(Int(2)) == Int(64)); if constexpr (sizeof(Int) > 1) { - CHECK(etl::ipow(Int(2)) == Int(256)); - CHECK(etl::ipow(Int(2)) == Int(1024)); - CHECK(etl::ipow(Int(2)) == Int(4096)); + CHECK(etl::ipow<16>(Int(2)) == Int(256)); + CHECK(etl::ipow<32>(Int(2)) == Int(1024)); + CHECK(etl::ipow<64>(Int(2)) == Int(4096)); } return true; From a8eacbb9d76ae2b6858406c6ac2fa690aa3523d2 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 15:23:31 +0200 Subject: [PATCH 24/34] [cstring] Use __builtin_memcpy also on gcc --- include/etl/_cstring/memcpy.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/etl/_cstring/memcpy.hpp b/include/etl/_cstring/memcpy.hpp index 6e33c81a7..992bbe2a8 100644 --- a/include/etl/_cstring/memcpy.hpp +++ b/include/etl/_cstring/memcpy.hpp @@ -4,6 +4,8 @@ #ifndef TETL_CSTRING_MEMCPY_HPP #define TETL_CSTRING_MEMCPY_HPP +#include + #include #include @@ -15,7 +17,7 @@ namespace etl { /// \ingroup cstring inline auto memcpy(void* dest, void const* src, etl::size_t n) -> void* { -#if defined(__clang__) +#if __has_builtin(__builtin_memcpy) return __builtin_memcpy(dest, src, n); #else return etl::detail::memcpy(dest, src, n); From 6445b73113e412f0ec9cca340374ecbecd268d44 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 15:23:56 +0200 Subject: [PATCH 25/34] [bitset] Replace operator[] with unchecked_at in basic_bitset --- include/etl/_bitset/basic_bitset.hpp | 6 +++--- include/etl/_bitset/bitset.hpp | 4 ++-- tests/bitset/basic_bitset.t.cpp | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/etl/_bitset/basic_bitset.hpp b/include/etl/_bitset/basic_bitset.hpp index 9ba045d01..60be9a28e 100644 --- a/include/etl/_bitset/basic_bitset.hpp +++ b/include/etl/_bitset/basic_bitset.hpp @@ -87,14 +87,14 @@ struct basic_bitset { } /// Returns the number of bits that the bitset holds. - [[nodiscard]] constexpr auto size() const noexcept -> etl::size_t + [[nodiscard]] static constexpr auto size() noexcept -> etl::size_t { return Bits; } /// Returns true if the bit at position \p pos is set. /// \pre `pos < size()` - [[nodiscard]] constexpr auto operator[](etl::size_t pos) const -> bool + [[nodiscard]] constexpr auto unchecked_at(etl::size_t pos) const -> bool { TETL_PRECONDITION(pos < size()); return unchecked_test(pos); @@ -102,7 +102,7 @@ struct basic_bitset { /// Returns a reference to the bit at position \p pos /// \pre `pos < size()` - [[nodiscard]] constexpr auto operator[](etl::size_t pos) -> reference + [[nodiscard]] constexpr auto unchecked_at(etl::size_t pos) -> reference { TETL_PRECONDITION(pos < size()); return reference{_words[word_index(pos)], offset_in_word(pos)}; diff --git a/include/etl/_bitset/bitset.hpp b/include/etl/_bitset/bitset.hpp index fbd1b11ea..326d7d5eb 100644 --- a/include/etl/_bitset/bitset.hpp +++ b/include/etl/_bitset/bitset.hpp @@ -160,7 +160,7 @@ struct bitset { [[nodiscard]] constexpr auto operator[](size_t const pos) -> reference { TETL_PRECONDITION(pos < size()); - return _bits[pos]; + return _bits.unchecked_at(pos); } /// Returns the value of the bit at the position pos. Perfoms no @@ -170,7 +170,7 @@ struct bitset { [[nodiscard]] constexpr auto operator[](size_t const pos) const -> bool { TETL_PRECONDITION(pos < size()); - return _bits[pos]; + return _bits.unchecked_at(pos); } /// Returns the value of the bit at the position pos. Perfoms no diff --git a/tests/bitset/basic_bitset.t.cpp b/tests/bitset/basic_bitset.t.cpp index 03db00e45..231dc5166 100644 --- a/tests/bitset/basic_bitset.t.cpp +++ b/tests/bitset/basic_bitset.t.cpp @@ -26,15 +26,15 @@ static constexpr auto test() -> bool CHECK_FALSE(set.any()); set.unchecked_flip(0); - CHECK(etl::as_const(set)[0]); - CHECK(set[0]); + CHECK(etl::as_const(set).unchecked_at(0)); + CHECK(set.unchecked_at(0)); CHECK(set.count() == 1); CHECK(set.any()); CHECK_FALSE(set.none()); set.unchecked_set(0, false); CHECK(set.count() == 0); - CHECK_FALSE(set[0]); + CHECK_FALSE(set.unchecked_at(0)); } { @@ -49,23 +49,23 @@ static constexpr auto test() -> bool auto set = bitset(0b1111).unchecked_reset(0).unchecked_flip(1); CHECK(set.count() == 2); - auto ref = set[0]; + auto ref = set.unchecked_at(0); ref = true; CHECK(ref); CHECK_FALSE(~ref); ref = false; CHECK(~ref); - CHECK_FALSE(etl::as_const(set)[0]); + CHECK_FALSE(etl::as_const(set).unchecked_at(0)); CHECK_FALSE(ref); ref.flip(); CHECK(ref); - CHECK(etl::as_const(set)[0]); + CHECK(etl::as_const(set).unchecked_at(0)); - ref = set[2]; + ref = set.unchecked_at(2); CHECK(ref); - CHECK(etl::as_const(set)[2]); + CHECK(etl::as_const(set).unchecked_at(2)); CHECK((bitset(0b111) & bitset(0b101)) == bitset(0b101)); CHECK((bitset(0b111) | bitset(0b101)) == bitset(0b111)); From 1bb90674df18cbeffbdbc4bd84407b81b158e9c4 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 15:28:33 +0200 Subject: [PATCH 26/34] Rename fuzz targets --- fuzzing/Makefile | 20 +++++++++---------- ...{fuzz_algorithm.cpp => algorithm.fuzz.cpp} | 0 .../src/{fuzz_bitset.cpp => bitset.fuzz.cpp} | 0 ...uzz_from_chars.cpp => from_chars.fuzz.cpp} | 0 ...z_string_view.cpp => string_view.fuzz.cpp} | 0 .../{fuzz_to_chars.cpp => to_chars.fuzz.cpp} | 0 6 files changed, 10 insertions(+), 10 deletions(-) rename fuzzing/src/{fuzz_algorithm.cpp => algorithm.fuzz.cpp} (100%) rename fuzzing/src/{fuzz_bitset.cpp => bitset.fuzz.cpp} (100%) rename fuzzing/src/{fuzz_from_chars.cpp => from_chars.fuzz.cpp} (100%) rename fuzzing/src/{fuzz_string_view.cpp => string_view.fuzz.cpp} (100%) rename fuzzing/src/{fuzz_to_chars.cpp => to_chars.fuzz.cpp} (100%) diff --git a/fuzzing/Makefile b/fuzzing/Makefile index aa5f54b84..57432e3c8 100644 --- a/fuzzing/Makefile +++ b/fuzzing/Makefile @@ -12,20 +12,20 @@ bin: .PHONY: build build: bin - $(CXX) $(CXXFLAGS) -I ../include -o bin/fuzz_algorithm src/fuzz_algorithm.cpp - $(CXX) $(CXXFLAGS) -I ../include -o bin/fuzz_bitset src/fuzz_bitset.cpp - $(CXX) $(CXXFLAGS) -I ../include -o bin/fuzz_from_chars src/fuzz_from_chars.cpp - $(CXX) $(CXXFLAGS) -I ../include -o bin/fuzz_string_view src/fuzz_string_view.cpp - $(CXX) $(CXXFLAGS) -I ../include -o bin/fuzz_to_chars src/fuzz_to_chars.cpp + $(CXX) $(CXXFLAGS) -I ../include -o bin/algorithm.fuzz src/algorithm.fuzz.cpp + $(CXX) $(CXXFLAGS) -I ../include -o bin/bitset.fuzz src/bitset.fuzz.cpp + $(CXX) $(CXXFLAGS) -I ../include -o bin/from_chars.fuzz src/from_chars.fuzz.cpp + $(CXX) $(CXXFLAGS) -I ../include -o bin/string_view.fuzz src/string_view.fuzz.cpp + $(CXX) $(CXXFLAGS) -I ../include -o bin/to_chars.fuzz src/to_chars.fuzz.cpp .PHONY: fuzz fuzz: build $(LCOV) -c -i -d . --base-directory . -o bin/base_cov.info --ignore-errors inconsistent - LLVM_PROFILE_FILE="bin/%p-%m.profraw" ./bin/fuzz_algorithm -max_total_time=$(MAXTIME) - LLVM_PROFILE_FILE="bin/%p-%m.profraw" ./bin/fuzz_bitset -max_total_time=$(MAXTIME) - LLVM_PROFILE_FILE="bin/%p-%m.profraw" ./bin/fuzz_from_chars -max_total_time=$(MAXTIME) - LLVM_PROFILE_FILE="bin/%p-%m.profraw" ./bin/fuzz_string_view -max_total_time=$(MAXTIME) - LLVM_PROFILE_FILE="bin/%p-%m.profraw" ./bin/fuzz_to_chars -max_total_time=$(MAXTIME) + LLVM_PROFILE_FILE="bin/%p-%m.profraw" ./bin/algorithm.fuzz -max_total_time=$(MAXTIME) + LLVM_PROFILE_FILE="bin/%p-%m.profraw" ./bin/bitset.fuzz -max_total_time=$(MAXTIME) + LLVM_PROFILE_FILE="bin/%p-%m.profraw" ./bin/from_chars.fuzz -max_total_time=$(MAXTIME) + LLVM_PROFILE_FILE="bin/%p-%m.profraw" ./bin/string_view.fuzz -max_total_time=$(MAXTIME) + LLVM_PROFILE_FILE="bin/%p-%m.profraw" ./bin/to_chars.fuzz -max_total_time=$(MAXTIME) $(LCOV) -c -d . --base-directory . -o bin/fuzz_cov.info --ignore-errors inconsistent $(LCOV) -a bin/base_cov.info -a bin/fuzz_cov.info -o bin/cov.info --ignore-errors inconsistent $(LCOV) --remove bin/cov.info "*clang*" -o bin/cov.info --ignore-errors inconsistent diff --git a/fuzzing/src/fuzz_algorithm.cpp b/fuzzing/src/algorithm.fuzz.cpp similarity index 100% rename from fuzzing/src/fuzz_algorithm.cpp rename to fuzzing/src/algorithm.fuzz.cpp diff --git a/fuzzing/src/fuzz_bitset.cpp b/fuzzing/src/bitset.fuzz.cpp similarity index 100% rename from fuzzing/src/fuzz_bitset.cpp rename to fuzzing/src/bitset.fuzz.cpp diff --git a/fuzzing/src/fuzz_from_chars.cpp b/fuzzing/src/from_chars.fuzz.cpp similarity index 100% rename from fuzzing/src/fuzz_from_chars.cpp rename to fuzzing/src/from_chars.fuzz.cpp diff --git a/fuzzing/src/fuzz_string_view.cpp b/fuzzing/src/string_view.fuzz.cpp similarity index 100% rename from fuzzing/src/fuzz_string_view.cpp rename to fuzzing/src/string_view.fuzz.cpp diff --git a/fuzzing/src/fuzz_to_chars.cpp b/fuzzing/src/to_chars.fuzz.cpp similarity index 100% rename from fuzzing/src/fuzz_to_chars.cpp rename to fuzzing/src/to_chars.fuzz.cpp From 6ba4e3ca65ad78beee41f717787f6841b5b1b28c Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 15:42:04 +0200 Subject: [PATCH 27/34] [cstring] Use more builtins with gcc --- include/etl/_cstring/memchr.hpp | 6 ++++-- include/etl/_cstring/memcmp.hpp | 4 +++- include/etl/_cstring/memmove.hpp | 4 +++- include/etl/_cstring/strchr.hpp | 21 +++++++++++++-------- include/etl/_cstring/strcmp.hpp | 4 +++- include/etl/_cstring/strlen.hpp | 12 ++++++++---- include/etl/_cstring/strncmp.hpp | 4 +++- include/etl/_cwchar/wmemcpy.hpp | 4 +++- include/etl/_cwchar/wmemmove.hpp | 4 +++- 9 files changed, 43 insertions(+), 20 deletions(-) diff --git a/include/etl/_cstring/memchr.hpp b/include/etl/_cstring/memchr.hpp index 42fd2bccc..11b634aee 100644 --- a/include/etl/_cstring/memchr.hpp +++ b/include/etl/_cstring/memchr.hpp @@ -4,6 +4,8 @@ #ifndef TETL_CSTRING_MEMCHR_HPP #define TETL_CSTRING_MEMCHR_HPP +#include + #include #include @@ -28,7 +30,7 @@ namespace etl { /// \ingroup cstring [[nodiscard]] inline auto memchr(void* ptr, int ch, etl::size_t n) -> void* { -#if defined(__clang__) +#if __has_builtin(__builtin_memchr) return __builtin_memchr(ptr, ch, n); #else auto* p = static_cast(ptr); @@ -38,7 +40,7 @@ namespace etl { [[nodiscard]] inline auto memchr(void const* ptr, int ch, etl::size_t n) -> void const* { -#if defined(__clang__) +#if __has_builtin(__builtin_memchr) return __builtin_memchr(ptr, ch, n); #else auto const* const p = static_cast(ptr); diff --git a/include/etl/_cstring/memcmp.hpp b/include/etl/_cstring/memcmp.hpp index 5556c0b91..b59b4640a 100644 --- a/include/etl/_cstring/memcmp.hpp +++ b/include/etl/_cstring/memcmp.hpp @@ -4,6 +4,8 @@ #ifndef TETL_CSTRING_MEMCMP_HPP #define TETL_CSTRING_MEMCMP_HPP +#include + #include #include @@ -18,7 +20,7 @@ namespace etl { /// \ingroup cstring [[nodiscard]] inline auto memcmp(void const* lhs, void const* rhs, etl::size_t count) noexcept -> int { -#if defined(__clang__) +#if __has_builtin(__builtin_memcmp) return __builtin_memcmp(lhs, rhs, count); #else auto const* l = static_cast(lhs); diff --git a/include/etl/_cstring/memmove.hpp b/include/etl/_cstring/memmove.hpp index ded476cee..1c321df7c 100644 --- a/include/etl/_cstring/memmove.hpp +++ b/include/etl/_cstring/memmove.hpp @@ -4,6 +4,8 @@ #ifndef TETL_CSTRING_MEMMOVE_HPP #define TETL_CSTRING_MEMMOVE_HPP +#include + #include #include #include @@ -17,7 +19,7 @@ inline auto memmove(void* dest, void const* src, etl::size_t count) -> void* { TETL_PRECONDITION(dest != nullptr); TETL_PRECONDITION(src != nullptr); -#if defined(__clang__) +#if __has_builtin(__builtin_memmove) return __builtin_memmove(dest, src, count); #else return etl::detail::memmove(dest, src, count); diff --git a/include/etl/_cstring/strchr.hpp b/include/etl/_cstring/strchr.hpp index 422253919..23f6ab63c 100644 --- a/include/etl/_cstring/strchr.hpp +++ b/include/etl/_cstring/strchr.hpp @@ -4,9 +4,12 @@ #ifndef TETL_CSTRING_STRCHR_HPP #define TETL_CSTRING_STRCHR_HPP +#include + #include #include #include +#include namespace etl { @@ -25,21 +28,23 @@ namespace etl { [[nodiscard]] constexpr auto strchr(char const* str, int ch) -> char const* { TETL_PRECONDITION(str != nullptr); -#if defined(__clang__) - return __builtin_strchr(str, ch); -#else - return etl::detail::strchr(str, ch); + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_strchr) + return __builtin_strchr(str, ch); #endif + } + return etl::detail::strchr(str, ch); } [[nodiscard]] constexpr auto strchr(char* str, int ch) -> char* { TETL_PRECONDITION(str != nullptr); -#if defined(__clang__) - return __builtin_strchr(str, ch); -#else - return etl::detail::strchr(str, ch); + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_strchr) + return __builtin_strchr(str, ch); #endif + } + return etl::detail::strchr(str, ch); } /// @} diff --git a/include/etl/_cstring/strcmp.hpp b/include/etl/_cstring/strcmp.hpp index f5202bb34..9f1f9cd9d 100644 --- a/include/etl/_cstring/strcmp.hpp +++ b/include/etl/_cstring/strcmp.hpp @@ -4,6 +4,8 @@ #ifndef TETL_CSTRING_STRCMP_HPP #define TETL_CSTRING_STRCMP_HPP +#include + #include #include @@ -18,7 +20,7 @@ namespace etl { /// \ingroup cstring [[nodiscard]] constexpr auto strcmp(char const* lhs, char const* rhs) -> int { -#if defined(__clang__) +#if __has_builtin(__builtin_strcmp) return __builtin_strcmp(lhs, rhs); #else return etl::detail::strcmp(lhs, rhs); diff --git a/include/etl/_cstring/strlen.hpp b/include/etl/_cstring/strlen.hpp index a4dcaefd5..8aeb5cff1 100644 --- a/include/etl/_cstring/strlen.hpp +++ b/include/etl/_cstring/strlen.hpp @@ -4,8 +4,11 @@ #ifndef TETL_CSTRING_STRLEN_HPP #define TETL_CSTRING_STRLEN_HPP +#include + #include #include +#include namespace etl { @@ -13,11 +16,12 @@ namespace etl { /// \ingroup cstring [[nodiscard]] constexpr auto strlen(char const* str) -> etl::size_t { -#if defined(__clang__) - return __builtin_strlen(str); -#else - return etl::detail::strlen(str); + if (not is_constant_evaluated()) { +#if __has_builtin(__builtin_strlen) + return __builtin_strlen(str); #endif + } + return etl::detail::strlen(str); } } // namespace etl diff --git a/include/etl/_cstring/strncmp.hpp b/include/etl/_cstring/strncmp.hpp index bc67c473d..6656e7809 100644 --- a/include/etl/_cstring/strncmp.hpp +++ b/include/etl/_cstring/strncmp.hpp @@ -4,6 +4,8 @@ #ifndef TETL_CSTRING_STRNCMP_HPP #define TETL_CSTRING_STRNCMP_HPP +#include + #include #include @@ -20,7 +22,7 @@ namespace etl { /// \ingroup cstring [[nodiscard]] constexpr auto strncmp(char const* lhs, char const* rhs, etl::size_t count) -> int { -#if defined(__clang__) +#if __has_builtin(__builtin_strncmp) return __builtin_strncmp(lhs, rhs, count); #else return etl::detail::strncmp(lhs, rhs, count); diff --git a/include/etl/_cwchar/wmemcpy.hpp b/include/etl/_cwchar/wmemcpy.hpp index a473b668e..b771cfe6c 100644 --- a/include/etl/_cwchar/wmemcpy.hpp +++ b/include/etl/_cwchar/wmemcpy.hpp @@ -4,6 +4,8 @@ #ifndef TETL_CWCHAR_WMEMCPY_HPP #define TETL_CWCHAR_WMEMCPY_HPP +#include + #include #include @@ -17,7 +19,7 @@ namespace etl { /// https://en.cppreference.com/w/cpp/string/wide/wmemcpy constexpr auto wmemcpy(wchar_t* dest, wchar_t const* src, etl::size_t count) noexcept -> wchar_t* { -#if defined(__clang__) +#if __has_builtin(__builtin_wmemcpy) return __builtin_wmemcpy(dest, src, count); #else if (count == 0) { diff --git a/include/etl/_cwchar/wmemmove.hpp b/include/etl/_cwchar/wmemmove.hpp index 86d69fbb4..1f4c01fc8 100644 --- a/include/etl/_cwchar/wmemmove.hpp +++ b/include/etl/_cwchar/wmemmove.hpp @@ -4,6 +4,8 @@ #ifndef TETL_CWCHAR_WMEMMOVE_HPP #define TETL_CWCHAR_WMEMMOVE_HPP +#include + #include #include @@ -23,7 +25,7 @@ namespace etl { /// https://en.cppreference.com/w/cpp/string/wide/wmemmove constexpr auto wmemmove(wchar_t* dest, wchar_t const* src, etl::size_t count) noexcept -> wchar_t* { -#if defined(__clang__) +#if __has_builtin(__builtin_wmemmove) return __builtin_wmemmove(dest, src, count); #else return etl::detail::memmove(dest, src, count); From da2ede4bc445df850a60caac9052125cd43d809e Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 16:31:30 +0200 Subject: [PATCH 28/34] Replace most logical &&, ||, ! with and, or, not --- examples/string.cpp | 4 +-- examples/utility.cpp | 4 +-- fuzzing/src/algorithm.fuzz.cpp | 6 ++-- include/etl/_bit/countl_zero.hpp | 2 +- include/etl/_cctype/isalnum.hpp | 2 +- include/etl/_cctype/isblank.hpp | 2 +- include/etl/_cctype/isgraph.hpp | 2 +- include/etl/_cctype/isprint.hpp | 2 +- include/etl/_cctype/ispunct.hpp | 2 +- include/etl/_cctype/isspace.hpp | 2 +- include/etl/_chrono/duration.hpp | 6 ++-- include/etl/_cmath/copysign.hpp | 2 +- include/etl/_cmath/lerp.hpp | 2 +- include/etl/_cmath/lrint.hpp | 4 +-- include/etl/_cmath/rint.hpp | 2 +- include/etl/_concepts/emulation.hpp | 2 +- include/etl/_concepts/move_constructible.hpp | 2 +- include/etl/_cwctype/iswalpha.hpp | 6 ++-- include/etl/_cwctype/iswblank.hpp | 2 +- include/etl/_cwctype/iswcntrl.hpp | 2 +- include/etl/_cwctype/iswdigit.hpp | 2 +- include/etl/_cwctype/iswgraph.hpp | 2 +- include/etl/_cwctype/iswlower.hpp | 2 +- include/etl/_cwctype/iswprint.hpp | 2 +- include/etl/_cwctype/iswpunct.hpp | 2 +- include/etl/_cwctype/iswspace.hpp | 2 +- include/etl/_cwctype/iswupper.hpp | 2 +- include/etl/_cwctype/iswxdigit.hpp | 8 ++--- include/etl/_flat_set/flat_set.hpp | 6 ++-- include/etl/_functional/bind_front.hpp | 2 +- include/etl/_functional/inplace_function.hpp | 6 ++-- include/etl/_functional/invoke.hpp | 2 +- include/etl/_functional/logical_and.hpp | 8 ++--- include/etl/_functional/logical_not.hpp | 8 ++--- include/etl/_functional/logical_or.hpp | 8 ++--- include/etl/_functional/not_fn.hpp | 6 ++-- include/etl/_iterator/ranges_iter_move.hpp | 2 +- include/etl/_linalg/exposition.hpp | 6 ++-- include/etl/_mdspan/layout_left.hpp | 6 ++-- include/etl/_mdspan/layout_right.hpp | 6 ++-- include/etl/_mdspan/mdspan.hpp | 10 +++--- include/etl/_memory/align.hpp | 2 +- include/etl/_memory/default_delete.hpp | 9 +++-- include/etl/_mutex/unique_lock.hpp | 8 ++--- include/etl/_optional/optional.hpp | 6 ++-- include/etl/_random/generate_canonical.hpp | 2 +- include/etl/_ratio/ratio_equal.hpp | 2 +- include/etl/_set/static_set.hpp | 6 ++-- include/etl/_span/span.hpp | 2 +- include/etl/_string/str_replace.hpp | 2 +- .../etl/_string_view/basic_string_view.hpp | 16 ++++----- include/etl/_strings/cstr.hpp | 6 ++-- include/etl/_strings/to_floating_point.hpp | 4 +-- include/etl/_tuple/tuple.hpp | 18 +++++----- include/etl/_type_traits/conjunction.hpp | 2 +- include/etl/_type_traits/invoke_result.hpp | 2 +- include/etl/_type_traits/is_convertible.hpp | 4 +-- .../_type_traits/is_nothrow_constructible.hpp | 2 +- .../_type_traits/is_nothrow_convertible.hpp | 2 +- .../is_nothrow_swappable_with.hpp | 2 +- .../etl/_type_traits/is_swappable_with.hpp | 4 +-- include/etl/_utility/pair.hpp | 6 ++-- include/etl/_utility/swap.hpp | 2 +- include/etl/_vector/static_vector.hpp | 34 +++++++++---------- tests/functional/hash.t.cpp | 2 +- tests/mutex/test_mutex.hpp | 2 +- 66 files changed, 151 insertions(+), 152 deletions(-) diff --git a/examples/string.cpp b/examples/string.cpp index eee038eac..eeace669a 100644 --- a/examples/string.cpp +++ b/examples/string.cpp @@ -33,13 +33,13 @@ auto main() -> int assert(str == "Hell"); str.push_back('o'); - assert(!str.empty()); + assert(not str.empty()); assert(str.size() == 5); assert(str == "Hello"); auto other = etl::string_view{" World"}; str.append(other, 0); - assert(!str.empty()); + assert(not str.empty()); assert(str.size() == 11); assert(str == "Hello World"); diff --git a/examples/utility.cpp b/examples/utility.cpp index 3ad735d25..1991d1906 100644 --- a/examples/utility.cpp +++ b/examples/utility.cpp @@ -25,12 +25,12 @@ auto main() -> int // AS CONST auto c = 1; - static_assert(!etl::is_const_v); + static_assert(not etl::is_const_v); static_assert(etl::is_const_v>); // CMP static_assert(etl::cmp_equal(42, 42)); - static_assert(!etl::cmp_equal(42UL, 100UL)); + static_assert(not etl::cmp_equal(42UL, 100UL)); static_assert(etl::cmp_not_equal(42UL, 100UL)); // PAIR construct diff --git a/fuzzing/src/algorithm.fuzz.cpp b/fuzzing/src/algorithm.fuzz.cpp index d42122d66..7e6b9debb 100644 --- a/fuzzing/src/algorithm.fuzz.cpp +++ b/fuzzing/src/algorithm.fuzz.cpp @@ -28,7 +28,7 @@ template } etl::sort(begin(vec), end(vec)); - if (!etl::is_sorted(begin(vec), end(vec))) { + if (not etl::is_sorted(begin(vec), end(vec))) { return 1; } @@ -49,7 +49,7 @@ template } etl::sort(begin(vec), end(vec)); - if (!etl::is_sorted(begin(vec), end(vec))) { + if (not etl::is_sorted(begin(vec), end(vec))) { return 1; } @@ -87,7 +87,7 @@ template auto e = etl::mismatch(begin(src), end(src), begin(objs), end(objs)); auto s = std::mismatch(begin(src), end(src), begin(objs), end(objs)); - if ((e.first != s.first) || (e.second != s.second)) { + if ((e.first != s.first) or (e.second != s.second)) { return 1; } diff --git a/include/etl/_bit/countl_zero.hpp b/include/etl/_bit/countl_zero.hpp index b68882c2e..d6b3442db 100644 --- a/include/etl/_bit/countl_zero.hpp +++ b/include/etl/_bit/countl_zero.hpp @@ -29,7 +29,7 @@ template } auto res = 0; - while (!(x & (UInt(1) << (static_cast(totalBits) - UInt(1))))) { + while (not(x & (UInt(1) << (static_cast(totalBits) - UInt(1))))) { x = static_cast(x << UInt(1)); ++res; } diff --git a/include/etl/_cctype/isalnum.hpp b/include/etl/_cctype/isalnum.hpp index 532a3f2e9..1420e432b 100644 --- a/include/etl/_cctype/isalnum.hpp +++ b/include/etl/_cctype/isalnum.hpp @@ -22,7 +22,7 @@ namespace etl { auto const isLower = ch >= 'a' and ch <= 'z'; auto const isUpper = ch >= 'A' and ch <= 'Z'; - return static_cast(isDigit || isLower || isUpper); + return static_cast(isDigit or isLower or isUpper); } } // namespace etl diff --git a/include/etl/_cctype/isblank.hpp b/include/etl/_cctype/isblank.hpp index a59a62c79..5caf5f455 100644 --- a/include/etl/_cctype/isblank.hpp +++ b/include/etl/_cctype/isblank.hpp @@ -20,7 +20,7 @@ namespace etl { /// \ingroup cctype [[nodiscard]] constexpr auto isblank(int ch) noexcept -> int { - return static_cast(ch == ' ' || ch == '\t'); + return static_cast(ch == ' ' or ch == '\t'); } } // namespace etl diff --git a/include/etl/_cctype/isgraph.hpp b/include/etl/_cctype/isgraph.hpp index e146cfab5..750e1d96a 100644 --- a/include/etl/_cctype/isgraph.hpp +++ b/include/etl/_cctype/isgraph.hpp @@ -29,7 +29,7 @@ namespace etl { auto const isLower = etl::islower(ch) != 0; auto const isPunct = etl::ispunct(ch) != 0; - return static_cast(isDigit || isLower || isUpper || isPunct); + return static_cast(isDigit or isLower or isUpper or isPunct); } } // namespace etl diff --git a/include/etl/_cctype/isprint.hpp b/include/etl/_cctype/isprint.hpp index 3bbe2f034..cd214f711 100644 --- a/include/etl/_cctype/isprint.hpp +++ b/include/etl/_cctype/isprint.hpp @@ -20,7 +20,7 @@ namespace etl { /// \ingroup cctype [[nodiscard]] constexpr auto isprint(int ch) noexcept -> int { - return static_cast(etl::isgraph(ch) != 0 || ch == ' '); + return static_cast(etl::isgraph(ch) != 0 or ch == ' '); } } // namespace etl diff --git a/include/etl/_cctype/ispunct.hpp b/include/etl/_cctype/ispunct.hpp index 912f5d728..db09c451b 100644 --- a/include/etl/_cctype/ispunct.hpp +++ b/include/etl/_cctype/ispunct.hpp @@ -27,7 +27,7 @@ namespace etl { auto const sec3 = ch >= '[' and ch <= '`'; auto const sec4 = ch >= '{' and ch <= '~'; - return static_cast(sec1 || sec2 || sec3 || sec4); + return static_cast(sec1 or sec2 or sec3 or sec4); } } // namespace etl diff --git a/include/etl/_cctype/isspace.hpp b/include/etl/_cctype/isspace.hpp index 5897be641..99c17a33e 100644 --- a/include/etl/_cctype/isspace.hpp +++ b/include/etl/_cctype/isspace.hpp @@ -25,7 +25,7 @@ namespace etl { auto const carriage = ch == '\r'; auto const hTab = ch == '\t'; auto const vTab = ch == '\v'; - return static_cast(sp || form || line || carriage || hTab || vTab); + return static_cast(sp or form or line or carriage or hTab or vTab); } } // namespace etl diff --git a/include/etl/_chrono/duration.hpp b/include/etl/_chrono/duration.hpp index 4c840ed72..c61a512ab 100644 --- a/include/etl/_chrono/duration.hpp +++ b/include/etl/_chrono/duration.hpp @@ -317,7 +317,7 @@ template template [[nodiscard]] constexpr auto operator!=(duration const& lhs, duration const& rhs) -> bool { - return !(lhs == rhs); + return not(lhs == rhs); } /// Compares two durations. Compares lhs to rhs, i.e. compares the number @@ -334,7 +334,7 @@ template template [[nodiscard]] constexpr auto operator<=(duration const& lhs, duration const& rhs) -> bool { - return !(rhs < lhs); + return not(rhs < lhs); } /// Compares two durations. Compares lhs to rhs, i.e. compares the number @@ -350,7 +350,7 @@ template template [[nodiscard]] constexpr auto operator>=(duration const& lhs, duration const& rhs) -> bool { - return !(lhs < rhs); + return not(lhs < rhs); } /// Signed integer type of at least 64 bits. diff --git a/include/etl/_cmath/copysign.hpp b/include/etl/_cmath/copysign.hpp index 40955a2bd..aafe17cab 100644 --- a/include/etl/_cmath/copysign.hpp +++ b/include/etl/_cmath/copysign.hpp @@ -24,7 +24,7 @@ constexpr auto copysign_fallback(T x, T y) noexcept -> T template [[nodiscard]] constexpr auto copysign(T x, T y) noexcept -> T { - if (!is_constant_evaluated()) { + if (not is_constant_evaluated()) { if constexpr (is_same_v) { #if __has_builtin(__builtin_copysignf) return __builtin_copysignf(x, y); diff --git a/include/etl/_cmath/lerp.hpp b/include/etl/_cmath/lerp.hpp index fee0c5043..bb358acbc 100644 --- a/include/etl/_cmath/lerp.hpp +++ b/include/etl/_cmath/lerp.hpp @@ -15,7 +15,7 @@ namespace etl { template [[nodiscard]] constexpr auto lerp(Float a, Float b, Float t) noexcept -> Float { - if ((a <= 0 && b >= 0) || (a >= 0 && b <= 0)) { + if ((a <= 0 and b >= 0) or (a >= 0 and b <= 0)) { return t * b + (1 - t) * a; } diff --git a/include/etl/_cmath/lrint.hpp b/include/etl/_cmath/lrint.hpp index 1aa7e9b8f..e9794012d 100644 --- a/include/etl/_cmath/lrint.hpp +++ b/include/etl/_cmath/lrint.hpp @@ -21,7 +21,7 @@ template template [[nodiscard]] constexpr auto lrint_impl(T arg) noexcept -> long { - if (!is_constant_evaluated()) { + if (not is_constant_evaluated()) { if constexpr (is_same_v) { #if __has_builtin(__builtin_lrintf) return __builtin_lrintf(arg); @@ -44,7 +44,7 @@ template template [[nodiscard]] constexpr auto llrint_impl(T arg) noexcept -> long long { - if (!is_constant_evaluated()) { + if (not is_constant_evaluated()) { if constexpr (is_same_v) { #if __has_builtin(__builtin_llrintf) return __builtin_llrintf(arg); diff --git a/include/etl/_cmath/rint.hpp b/include/etl/_cmath/rint.hpp index d3e9946b3..05eb78bc0 100644 --- a/include/etl/_cmath/rint.hpp +++ b/include/etl/_cmath/rint.hpp @@ -25,7 +25,7 @@ template template [[nodiscard]] constexpr auto rint_impl(T arg) noexcept -> T { - if (!is_constant_evaluated()) { + if (not is_constant_evaluated()) { if constexpr (is_same_v) { #if __has_builtin(__builtin_rintf) return __builtin_rintf(arg); diff --git a/include/etl/_concepts/emulation.hpp b/include/etl/_concepts/emulation.hpp index 30943c882..9b5019155 100644 --- a/include/etl/_concepts/emulation.hpp +++ b/include/etl/_concepts/emulation.hpp @@ -44,7 +44,7 @@ struct IteratorConcept>> // clang-format off template inline constexpr bool InputIterator = IteratorConcept {}; template inline constexpr bool ForwardIterator = IteratorConcept {}; -template inline constexpr bool OutputIterator = IteratorConcept {} || ForwardIterator; +template inline constexpr bool OutputIterator = IteratorConcept {} or ForwardIterator; template inline constexpr bool BidirectionalIterator = IteratorConcept {}; template inline constexpr bool RandomAccessIterator = IteratorConcept {}; template inline constexpr bool RandomAccessRange = RandomAccessIterator>; diff --git a/include/etl/_concepts/move_constructible.hpp b/include/etl/_concepts/move_constructible.hpp index 26fb99995..b9274a2a5 100644 --- a/include/etl/_concepts/move_constructible.hpp +++ b/include/etl/_concepts/move_constructible.hpp @@ -18,7 +18,7 @@ namespace etl { /// /// \ingroup concepts template -concept move_constructible = constructible_from && convertible_to; +concept move_constructible = constructible_from and convertible_to; } // namespace etl diff --git a/include/etl/_cwctype/iswalpha.hpp b/include/etl/_cwctype/iswalpha.hpp index 24c9b83e5..3f0abbe29 100644 --- a/include/etl/_cwctype/iswalpha.hpp +++ b/include/etl/_cwctype/iswalpha.hpp @@ -20,9 +20,9 @@ namespace etl { /// \ingroup cwctype [[nodiscard]] constexpr auto iswalpha(wint_t ch) noexcept -> int { - auto isLower = ch >= L'a' && ch <= L'z'; - auto isUpper = ch >= L'A' && ch <= L'Z'; - return static_cast(isLower || isUpper); + auto isLower = ch >= L'a' and ch <= L'z'; + auto isUpper = ch >= L'A' and ch <= L'Z'; + return static_cast(isLower or isUpper); } } // namespace etl diff --git a/include/etl/_cwctype/iswblank.hpp b/include/etl/_cwctype/iswblank.hpp index 602fe8167..40b3a3d04 100644 --- a/include/etl/_cwctype/iswblank.hpp +++ b/include/etl/_cwctype/iswblank.hpp @@ -20,7 +20,7 @@ namespace etl { /// \ingroup cwctype [[nodiscard]] constexpr auto iswblank(wint_t ch) noexcept -> int { - return static_cast(ch == L' ' || ch == L'\t'); + return static_cast(ch == L' ' or ch == L'\t'); } } // namespace etl diff --git a/include/etl/_cwctype/iswcntrl.hpp b/include/etl/_cwctype/iswcntrl.hpp index cbdf30d0a..b1de3b17b 100644 --- a/include/etl/_cwctype/iswcntrl.hpp +++ b/include/etl/_cwctype/iswcntrl.hpp @@ -20,7 +20,7 @@ namespace etl { /// \ingroup cwctype [[nodiscard]] constexpr auto iswcntrl(wint_t ch) noexcept -> int { - return static_cast((ch <= wint_t(0x1F)) || ch == wint_t(0x7F)); + return static_cast((ch <= wint_t(0x1F)) or ch == wint_t(0x7F)); } } // namespace etl diff --git a/include/etl/_cwctype/iswdigit.hpp b/include/etl/_cwctype/iswdigit.hpp index 0960f15b8..04d9a3da0 100644 --- a/include/etl/_cwctype/iswdigit.hpp +++ b/include/etl/_cwctype/iswdigit.hpp @@ -18,7 +18,7 @@ namespace etl { /// \ingroup cwctype [[nodiscard]] constexpr auto iswdigit(wint_t ch) noexcept -> int { - return static_cast(ch >= L'0' && ch <= L'9'); + return static_cast(ch >= L'0' and ch <= L'9'); } } // namespace etl diff --git a/include/etl/_cwctype/iswgraph.hpp b/include/etl/_cwctype/iswgraph.hpp index c5df8eecc..b04dd5073 100644 --- a/include/etl/_cwctype/iswgraph.hpp +++ b/include/etl/_cwctype/iswgraph.hpp @@ -30,7 +30,7 @@ namespace etl { auto const isUpper = iswupper(ch) != 0; auto const isLower = iswlower(ch) != 0; auto const isPunct = iswpunct(ch) != 0; - return static_cast(isDigit || isLower || isUpper || isPunct); + return static_cast(isDigit or isLower or isUpper or isPunct); } } // namespace etl diff --git a/include/etl/_cwctype/iswlower.hpp b/include/etl/_cwctype/iswlower.hpp index 52a9fc053..dd692f345 100644 --- a/include/etl/_cwctype/iswlower.hpp +++ b/include/etl/_cwctype/iswlower.hpp @@ -20,7 +20,7 @@ namespace etl { /// \ingroup cwctype [[nodiscard]] constexpr auto iswlower(wint_t ch) noexcept -> int { - return static_cast(ch >= L'a' && ch <= L'z'); + return static_cast(ch >= L'a' and ch <= L'z'); } } // namespace etl diff --git a/include/etl/_cwctype/iswprint.hpp b/include/etl/_cwctype/iswprint.hpp index 83c80cc16..d1f7d24d1 100644 --- a/include/etl/_cwctype/iswprint.hpp +++ b/include/etl/_cwctype/iswprint.hpp @@ -22,7 +22,7 @@ namespace etl { /// \ingroup cwctype [[nodiscard]] constexpr auto iswprint(wint_t ch) noexcept -> int { - return static_cast(etl::iswgraph(ch) != 0 || ch == ' '); + return static_cast(etl::iswgraph(ch) != 0 or ch == ' '); } } // namespace etl diff --git a/include/etl/_cwctype/iswpunct.hpp b/include/etl/_cwctype/iswpunct.hpp index d8ca80958..dbf4c1c43 100644 --- a/include/etl/_cwctype/iswpunct.hpp +++ b/include/etl/_cwctype/iswpunct.hpp @@ -24,7 +24,7 @@ namespace etl { auto const sec2 = ch >= L':' and ch <= L'@'; auto const sec3 = ch >= L'[' and ch <= L'`'; auto const sec4 = ch >= L'{' and ch <= L'~'; - return static_cast(sec1 || sec2 || sec3 || sec4); + return static_cast(sec1 or sec2 or sec3 or sec4); } } // namespace etl diff --git a/include/etl/_cwctype/iswspace.hpp b/include/etl/_cwctype/iswspace.hpp index 426c9670b..27207345f 100644 --- a/include/etl/_cwctype/iswspace.hpp +++ b/include/etl/_cwctype/iswspace.hpp @@ -33,7 +33,7 @@ namespace etl { auto const carriage = ch == L'\r'; auto const hTab = ch == L'\t'; auto const vTab = ch == L'\v'; - return static_cast(sp || form || line || carriage || hTab || vTab); + return static_cast(sp or form or line or carriage or hTab or vTab); } } // namespace etl diff --git a/include/etl/_cwctype/iswupper.hpp b/include/etl/_cwctype/iswupper.hpp index 7c181c1c4..72dca45f9 100644 --- a/include/etl/_cwctype/iswupper.hpp +++ b/include/etl/_cwctype/iswupper.hpp @@ -20,7 +20,7 @@ namespace etl { /// \ingroup cwctype [[nodiscard]] constexpr auto iswupper(wint_t ch) noexcept -> int { - return static_cast(ch >= L'A' && ch <= L'Z'); + return static_cast(ch >= L'A' and ch <= L'Z'); } } // namespace etl diff --git a/include/etl/_cwctype/iswxdigit.hpp b/include/etl/_cwctype/iswxdigit.hpp index 5b9a88774..a6a7c1d08 100644 --- a/include/etl/_cwctype/iswxdigit.hpp +++ b/include/etl/_cwctype/iswxdigit.hpp @@ -18,10 +18,10 @@ namespace etl { /// \ingroup cwctype [[nodiscard]] constexpr auto iswxdigit(wint_t ch) noexcept -> int { - auto const isDigit = ch >= '0' && ch <= '9'; - auto const isHexLower = ch >= 'a' && ch <= 'f'; - auto const isHexUpper = ch >= 'A' && ch <= 'F'; - return static_cast(isDigit || isHexLower || isHexUpper); + auto const isDigit = ch >= '0' and ch <= '9'; + auto const isHexLower = ch >= 'a' and ch <= 'f'; + auto const isHexUpper = ch >= 'A' and ch <= 'F'; + return static_cast(isDigit or isHexLower or isHexUpper); } } // namespace etl diff --git a/include/etl/_flat_set/flat_set.hpp b/include/etl/_flat_set/flat_set.hpp index 3690522dd..f419d478d 100644 --- a/include/etl/_flat_set/flat_set.hpp +++ b/include/etl/_flat_set/flat_set.hpp @@ -274,7 +274,7 @@ struct flat_set { } constexpr auto - swap(flat_set& other) noexcept(etl::is_nothrow_swappable_v && etl::is_nothrow_swappable_v) + swap(flat_set& other) noexcept(etl::is_nothrow_swappable_v and etl::is_nothrow_swappable_v) -> void { using etl::swap; @@ -452,12 +452,12 @@ struct flat_set { friend constexpr auto operator<=(flat_set const& x, flat_set const& y) -> bool { - return !(y < x); + return not(y < x); } friend constexpr auto operator>=(flat_set const& x, flat_set const& y) -> bool { - return !(x < y); + return not(x < y); } friend constexpr auto swap(flat_set& x, flat_set& y) noexcept(noexcept(x.swap(y))) -> void diff --git a/include/etl/_functional/bind_front.hpp b/include/etl/_functional/bind_front.hpp index 8d69008a3..1ea96ee56 100644 --- a/include/etl/_functional/bind_front.hpp +++ b/include/etl/_functional/bind_front.hpp @@ -34,7 +34,7 @@ template class bind_front_t { public: template - requires(!(sizeof...(BA) == 0 && is_base_of_v>)) + requires(not(sizeof...(BA) == 0 and is_base_of_v>)) explicit bind_front_t(F&& f, BA&&... ba) : _func(etl::forward(f)) , _boundArgs(etl::forward(ba)...) diff --git a/include/etl/_functional/inplace_function.hpp b/include/etl/_functional/inplace_function.hpp index 772279b36..4d6042247 100644 --- a/include/etl/_functional/inplace_function.hpp +++ b/include/etl/_functional/inplace_function.hpp @@ -127,7 +127,7 @@ struct inplace_function { } template > - requires(!detail::is_inplace_function::value && is_invocable_r_v) + requires(not detail::is_inplace_function::value and is_invocable_r_v) inplace_function(T&& closure) { static_assert(is_copy_constructible_v, "inplace_function cannot be constructed from non-copyable type"); @@ -265,7 +265,7 @@ template [[nodiscard]] constexpr auto operator==(inplace_function const& f, nullptr_t /*ignore*/) noexcept -> bool { - return !static_cast(f); + return not static_cast(f); } /// \brief Compares a etl::inplace_function with a null pointer. Empty functions @@ -285,7 +285,7 @@ template [[nodiscard]] constexpr auto operator==(nullptr_t /*ignore*/, inplace_function const& f) noexcept -> bool { - return !static_cast(f); + return not static_cast(f); } /// \brief Compares a etl::inplace_function with a null pointer. Empty functions diff --git a/include/etl/_functional/invoke.hpp b/include/etl/_functional/invoke.hpp index e8748f1f3..be758c90f 100644 --- a/include/etl/_functional/invoke.hpp +++ b/include/etl/_functional/invoke.hpp @@ -28,7 +28,7 @@ constexpr auto invoke_memptr(Pointed Class::* f, T1&& t1, Args&&... args) -> dec return ((*etl::forward(t1)).*f)(etl::forward(args)...); } } else { - static_assert(is_object_v && sizeof...(args) == 0); + static_assert(is_object_v and sizeof...(args) == 0); if constexpr (is_base_of_v>) { return etl::forward(t1).*f; } else if constexpr (is_reference_wrapper_v>) { diff --git a/include/etl/_functional/logical_and.hpp b/include/etl/_functional/logical_and.hpp index be448fd04..ce732fba6 100644 --- a/include/etl/_functional/logical_and.hpp +++ b/include/etl/_functional/logical_and.hpp @@ -15,7 +15,7 @@ template struct logical_and { [[nodiscard]] constexpr auto operator()(T const& lhs, T const& rhs) const -> bool { - return lhs && rhs; + return lhs and rhs; } }; @@ -25,10 +25,10 @@ struct logical_and { template [[nodiscard]] constexpr auto - operator()(T&& lhs, U&& rhs) const noexcept(noexcept(etl::forward(lhs) && etl::forward(rhs))) - -> decltype(etl::forward(lhs) && etl::forward(rhs)) + operator()(T&& lhs, U&& rhs) const noexcept(noexcept(etl::forward(lhs) and etl::forward(rhs))) + -> decltype(etl::forward(lhs) and etl::forward(rhs)) { - return etl::forward(lhs) && etl::forward(rhs); + return etl::forward(lhs) and etl::forward(rhs); } }; diff --git a/include/etl/_functional/logical_not.hpp b/include/etl/_functional/logical_not.hpp index d65e9508f..556b37cf7 100644 --- a/include/etl/_functional/logical_not.hpp +++ b/include/etl/_functional/logical_not.hpp @@ -15,7 +15,7 @@ template struct logical_not { [[nodiscard]] constexpr auto operator()(T const& arg) const -> bool { - return !arg; + return not arg; } }; @@ -24,10 +24,10 @@ struct logical_not { using is_transparent = void; template - [[nodiscard]] constexpr auto operator()(T&& arg) const noexcept(noexcept(!etl::forward(arg))) - -> decltype(!etl::forward(arg)) + [[nodiscard]] constexpr auto operator()(T&& arg) const noexcept(noexcept(not etl::forward(arg))) + -> decltype(not etl::forward(arg)) { - return !etl::forward(arg); + return not etl::forward(arg); } }; diff --git a/include/etl/_functional/logical_or.hpp b/include/etl/_functional/logical_or.hpp index 8b5eeab7a..13ad1c488 100644 --- a/include/etl/_functional/logical_or.hpp +++ b/include/etl/_functional/logical_or.hpp @@ -15,7 +15,7 @@ template struct logical_or { [[nodiscard]] constexpr auto operator()(T const& lhs, T const& rhs) const -> bool { - return lhs || rhs; + return lhs or rhs; } }; @@ -25,10 +25,10 @@ struct logical_or { template [[nodiscard]] constexpr auto - operator()(T&& lhs, U&& rhs) const noexcept(noexcept(etl::forward(lhs) || etl::forward(rhs))) - -> decltype(etl::forward(lhs) || etl::forward(rhs)) + operator()(T&& lhs, U&& rhs) const noexcept(noexcept(etl::forward(lhs) or etl::forward(rhs))) + -> decltype(etl::forward(lhs) or etl::forward(rhs)) { - return etl::forward(lhs) || etl::forward(rhs); + return etl::forward(lhs) or etl::forward(rhs); } }; diff --git a/include/etl/_functional/not_fn.hpp b/include/etl/_functional/not_fn.hpp index ba8fad144..46ef51973 100644 --- a/include/etl/_functional/not_fn.hpp +++ b/include/etl/_functional/not_fn.hpp @@ -73,10 +73,10 @@ template struct stateless_not_fn { template constexpr auto - operator()(Args&&... args) const noexcept(noexcept(!etl::invoke(ConstFn, etl::forward(args)...))) - -> decltype(!etl::invoke(ConstFn, etl::forward(args)...)) + operator()(Args&&... args) const noexcept(noexcept(not etl::invoke(ConstFn, etl::forward(args)...))) + -> decltype(not etl::invoke(ConstFn, etl::forward(args)...)) { - return !etl::invoke(ConstFn, etl::forward(args)...); + return not etl::invoke(ConstFn, etl::forward(args)...); } }; diff --git a/include/etl/_iterator/ranges_iter_move.hpp b/include/etl/_iterator/ranges_iter_move.hpp index 7a1fd9e41..e8d6fdf8c 100644 --- a/include/etl/_iterator/ranges_iter_move.hpp +++ b/include/etl/_iterator/ranges_iter_move.hpp @@ -30,7 +30,7 @@ concept can_move = not adl_iter_move and requires(T&& t) { template concept can_deref = not adl_iter_move and !can_move and requires(T&& t) { *t; - requires(!is_lvalue_reference_v); + requires(not is_lvalue_reference_v); }; struct fn { diff --git a/include/etl/_linalg/exposition.hpp b/include/etl/_linalg/exposition.hpp index 5bd0f04fb..7b6331a57 100644 --- a/include/etl/_linalg/exposition.hpp +++ b/include/etl/_linalg/exposition.hpp @@ -146,19 +146,19 @@ concept inout_matrix = is_mdspan_v /// \ingroup linalg template -concept in_object = is_mdspan_v and (T::rank() == 1 || T::rank() == 2); +concept in_object = is_mdspan_v and (T::rank() == 1 or T::rank() == 2); /// \ingroup linalg template concept out_object = is_mdspan_v - and (T::rank() == 1 || T::rank() == 2) + and (T::rank() == 1 or T::rank() == 2) and is_same_v, typename T::element_type> and T::is_always_unique(); /// \ingroup linalg template concept inout_object = is_mdspan_v - and (T::rank() == 1 || T::rank() == 2) + and (T::rank() == 1 or T::rank() == 2) and is_same_v, typename T::element_type> and T::is_always_unique(); diff --git a/include/etl/_mdspan/layout_left.hpp b/include/etl/_mdspan/layout_left.hpp index f10f34fce..67d7ee593 100644 --- a/include/etl/_mdspan/layout_left.hpp +++ b/include/etl/_mdspan/layout_left.hpp @@ -42,7 +42,7 @@ struct layout_left::mapping { } template - requires(extents_type::rank() <= 1) && is_constructible_v + requires(extents_type::rank() <= 1) and is_constructible_v constexpr explicit(not is_convertible_v) mapping( layout_right::mapping const& other ) noexcept @@ -67,8 +67,8 @@ struct layout_left::mapping { template requires(sizeof...(Indices) == extents_type::rank()) - && (is_convertible_v && ...) - && (is_nothrow_constructible_v && ...) + and (is_convertible_v and ...) + and (is_nothrow_constructible_v and ...) [[nodiscard]] constexpr auto operator()(Indices... indices) const noexcept -> index_type { return [&](index_sequence /*seq*/) { diff --git a/include/etl/_mdspan/layout_right.hpp b/include/etl/_mdspan/layout_right.hpp index a45100c62..02e17f2e4 100644 --- a/include/etl/_mdspan/layout_right.hpp +++ b/include/etl/_mdspan/layout_right.hpp @@ -36,7 +36,7 @@ struct layout_right::mapping { template requires is_constructible_v - constexpr explicit(!is_convertible_v) mapping( + constexpr explicit(not is_convertible_v) mapping( mapping const& other ) noexcept : _extents{other.extents()} @@ -44,8 +44,8 @@ struct layout_right::mapping { } template - requires(extents_type::rank() <= 1) && is_constructible_v - constexpr explicit(!is_convertible_v) mapping( + requires(extents_type::rank() <= 1) and is_constructible_v + constexpr explicit(not is_convertible_v) mapping( layout_left::mapping const& other ) noexcept : _extents{other.extents()} diff --git a/include/etl/_mdspan/mdspan.hpp b/include/etl/_mdspan/mdspan.hpp index 83cde8607..796d51f28 100644 --- a/include/etl/_mdspan/mdspan.hpp +++ b/include/etl/_mdspan/mdspan.hpp @@ -87,7 +87,7 @@ struct mdspan { template requires((is_convertible_v and ...) and (is_nothrow_constructible_v and ...) - and ((sizeof...(OtherIndexTypes) == rank()) || (sizeof...(OtherIndexTypes) == rank_dynamic())) + and ((sizeof...(OtherIndexTypes) == rank()) or (sizeof...(OtherIndexTypes) == rank_dynamic())) and is_constructible_v and is_default_constructible_v) explicit constexpr mdspan(data_handle_type ptr, OtherIndexTypes... exts) @@ -181,8 +181,8 @@ struct mdspan { #if defined(__cpp_multidimensional_subscript) template requires( - (is_convertible_v && ...) - and (is_nothrow_constructible_v && ...) + (is_convertible_v and ...) + and (is_nothrow_constructible_v and ...) and sizeof...(OtherIndexTypes) == rank() ) [[nodiscard]] constexpr auto operator[](OtherIndexTypes... indices) const -> reference @@ -276,7 +276,7 @@ struct mdspan { }; template - requires(is_array_v && rank_v == 1) + requires(is_array_v and rank_v == 1) mdspan(CArray&) -> mdspan, extents>>; template @@ -284,7 +284,7 @@ template mdspan(Pointer&&) -> mdspan>, extents>; template - requires((is_convertible_v && ...) && sizeof...(Integrals) > 0) + requires((is_convertible_v and ...) and sizeof...(Integrals) > 0) explicit mdspan(ElementType*, Integrals...) -> mdspan>; template diff --git a/include/etl/_memory/align.hpp b/include/etl/_memory/align.hpp index 61ce1e64b..6b3eef00f 100644 --- a/include/etl/_memory/align.hpp +++ b/include/etl/_memory/align.hpp @@ -27,7 +27,7 @@ namespace etl { if (off != 0) { off = alignment - off; } - if (space < off || space - off < size) { + if (space < off or space - off < size) { return nullptr; } diff --git a/include/etl/_memory/default_delete.hpp b/include/etl/_memory/default_delete.hpp index c65b151eb..d2a52806b 100644 --- a/include/etl/_memory/default_delete.hpp +++ b/include/etl/_memory/default_delete.hpp @@ -14,6 +14,10 @@ namespace etl { template struct default_delete { + static_assert(not is_function_v); + static_assert(not is_void_v); + static_assert(sizeof(T)); + constexpr default_delete() noexcept = default; template @@ -26,11 +30,6 @@ struct default_delete { { delete ptr; } - -private: - static_assert(!is_function_v); - static_assert(!is_void_v); - static_assert(sizeof(T)); }; template diff --git a/include/etl/_mutex/unique_lock.hpp b/include/etl/_mutex/unique_lock.hpp index b62077497..598367a52 100644 --- a/include/etl/_mutex/unique_lock.hpp +++ b/include/etl/_mutex/unique_lock.hpp @@ -115,7 +115,7 @@ struct unique_lock { /// mutex and has acquired ownership of it, the mutex is unlocked. constexpr auto operator=(unique_lock&& u) noexcept -> unique_lock& { - if (_mutex != nullptr && _owns) { + if (_mutex != nullptr and _owns) { unlock(); } _mutex = exchange(u._mutex, nullptr); @@ -143,7 +143,7 @@ struct unique_lock { /// successfully, false otherwise. constexpr auto try_lock() noexcept(noexcept(_mutex->try_lock())) -> bool { - if ((_mutex != nullptr) && !_owns) { + if ((_mutex != nullptr) and not _owns) { if (auto success = _mutex->try_lock(); success) { _owns = true; return true; @@ -164,7 +164,7 @@ struct unique_lock { constexpr auto try_lock_for(chrono::duration const& dur) noexcept(noexcept(_mutex->try_lock_for(dur))) -> bool { - if ((_mutex != nullptr) && !_owns) { + if ((_mutex != nullptr) and not _owns) { if (auto success = _mutex->try_lock_for(dur); success) { _owns = true; return true; @@ -179,7 +179,7 @@ struct unique_lock { constexpr auto try_lock_until(chrono::time_point const& tp) noexcept(noexcept(_mutex->try_lock_until(tp))) -> bool { - if ((_mutex != nullptr) && !_owns) { + if ((_mutex != nullptr) and not _owns) { if (auto success = _mutex->try_lock_until(tp); success) { _owns = true; return true; diff --git a/include/etl/_optional/optional.hpp b/include/etl/_optional/optional.hpp index ac01a9298..c01cf85ed 100644 --- a/include/etl/_optional/optional.hpp +++ b/include/etl/_optional/optional.hpp @@ -93,9 +93,9 @@ struct optional { using iterator = T*; using const_iterator = T const*; - static_assert(!is_array_v, "instantiation of optional with an array type is ill-formed"); - static_assert(!is_same_v, nullopt_t>, "instantiation of optional with nullopt_t is ill-formed"); - static_assert(!is_same_v, in_place_t>, "instantiation of optional with in_place_t is ill-formed"); + static_assert(not is_array_v, "optional of an array type is ill-formed"); + static_assert(not is_same_v, nullopt_t>, "optional of nullopt_t is ill-formed"); + static_assert(not is_same_v, in_place_t>, "optional of in_place_t is ill-formed"); /// Constructs an object that does not contain a value. constexpr optional() noexcept = default; diff --git a/include/etl/_random/generate_canonical.hpp b/include/etl/_random/generate_canonical.hpp index e036e9313..915832bd0 100644 --- a/include/etl/_random/generate_canonical.hpp +++ b/include/etl/_random/generate_canonical.hpp @@ -16,7 +16,7 @@ namespace detail { [[nodiscard]] constexpr auto generate_canonical_iterations(int bits, uint64_t gMin, uint64_t gMax) -> int { - if (bits == 0 || (gMax == numeric_limits::max() && gMin == 0)) { + if (bits == 0 or (gMax == numeric_limits::max() and gMin == 0)) { return 1; } diff --git a/include/etl/_ratio/ratio_equal.hpp b/include/etl/_ratio/ratio_equal.hpp index 5f59e7e39..f5a729c6d 100644 --- a/include/etl/_ratio/ratio_equal.hpp +++ b/include/etl/_ratio/ratio_equal.hpp @@ -14,7 +14,7 @@ namespace etl { /// Otherwise, value is false. /// \ingroup ratio template -struct ratio_equal : bool_constant { }; +struct ratio_equal : bool_constant { }; /// \relates ratio_equal /// \ingroup ratio diff --git a/include/etl/_set/static_set.hpp b/include/etl/_set/static_set.hpp index 26e0a4a23..032f5fc75 100644 --- a/include/etl/_set/static_set.hpp +++ b/include/etl/_set/static_set.hpp @@ -210,10 +210,10 @@ struct static_set { constexpr auto insert(value_type&& value) -> pair requires(is_move_constructible_v) { - if (!full()) { + if (not full()) { auto cmp = key_compare{}; auto* p = etl::lower_bound(_storage.begin(), _storage.end(), value, cmp); - if (p == _storage.end() || *(p) != value) { + if (p == _storage.end() or *p != value) { _storage.push_back(etl::move(value)); auto* pos = rotate(p, _storage.end() - 1, _storage.end()); return make_pair(pos, true); @@ -514,7 +514,7 @@ template [[nodiscard]] constexpr auto operator==(static_set const& lhs, static_set const& rhs) -> bool { - return lhs.size() == rhs.size() && equal(begin(lhs), end(lhs), begin(rhs)); + return lhs.size() == rhs.size() and equal(lhs.begin(), lhs.end(), rhs.begin()); } /// \brief Compares the contents of two sets. diff --git a/include/etl/_span/span.hpp b/include/etl/_span/span.hpp index ffb18a614..130d5769d 100644 --- a/include/etl/_span/span.hpp +++ b/include/etl/_span/span.hpp @@ -101,7 +101,7 @@ struct span { /// data() == nullptr and size() == 0. /// /// \details This overload only participates in overload resolution - /// if extent == 0 || extent == etl::dynamic_extent. + /// if extent == 0 or extent == etl::dynamic_extent. constexpr span() noexcept requires(extent == 0 or extent == dynamic_extent) = default; diff --git a/include/etl/_string/str_replace.hpp b/include/etl/_string/str_replace.hpp index 06b8200bc..394ddb0f4 100644 --- a/include/etl/_string/str_replace.hpp +++ b/include/etl/_string/str_replace.hpp @@ -17,7 +17,7 @@ constexpr auto str_replace(CharT* f, CharT* l, CharT ch) -> void template constexpr auto str_replace(CharT* f, CharT* l, CharT const* sf, CharT const* sl) -> void { - for (; (f != l) && (sf != sl); ++f, ++sf) { + for (; (f != l) and (sf != sl); ++f, ++sf) { *f = *sf; } } diff --git a/include/etl/_string_view/basic_string_view.hpp b/include/etl/_string_view/basic_string_view.hpp index bd047573d..080eb9bb3 100644 --- a/include/etl/_string_view/basic_string_view.hpp +++ b/include/etl/_string_view/basic_string_view.hpp @@ -322,10 +322,10 @@ struct basic_string_view { /// Checks if the string view begins with the given prefix, where the prefix is a single character. /// - /// \details Effectively returns !empty() && Traits::eq(front(), c) + /// \details Effectively returns not empty() and Traits::eq(front(), c) [[nodiscard]] constexpr auto starts_with(Char c) const noexcept -> bool { - return !empty() && traits_type::eq(front(), c); + return not empty() and traits_type::eq(front(), c); } /// \brief Checks if the string view begins with the given prefix, where the @@ -340,20 +340,20 @@ struct basic_string_view { /// \brief Checks if the string view ends with the given suffix, where the /// prefix is a string view. /// - /// \details Effectively returns size() >= sv.size() && compare(size() - + /// \details Effectively returns size() >= sv.size() and compare(size() - /// sv.size(), npos, sv) == 0 [[nodiscard]] constexpr auto ends_with(basic_string_view sv) const noexcept -> bool { - return size() >= sv.size() && compare(size() - sv.size(), npos, sv) == 0; + return size() >= sv.size() and compare(size() - sv.size(), npos, sv) == 0; } /// \brief Checks if the string view ends with the given suffix, where the /// prefix is a single character. /// - /// \details Effectively returns !empty() && Traits::eq(back(), c) + /// \details Effectively returns not empty() and Traits::eq(back(), c) [[nodiscard]] constexpr auto ends_with(Char c) const noexcept -> bool { - return !empty() && Traits::eq(back(), c); + return not empty() and Traits::eq(back(), c); } /// \brief Checks if the string view ends with the given suffix, where the @@ -447,7 +447,7 @@ struct basic_string_view { } auto const* r = etl::find_end(data(), data() + pos, sv.begin(), sv.end(), Traits::eq); - if (sv.size() > 0 && r == data() + pos) { + if (sv.size() > 0 and r == data() + pos) { return npos; } return static_cast(r - data()); @@ -578,7 +578,7 @@ struct basic_string_view { if (pos < size()) { auto const* last = data() + size(); for (auto const* s = data() + pos; s != last; ++s) { - if (!Traits::eq(*s, c)) { + if (not Traits::eq(*s, c)) { return static_cast(s - data()); } } diff --git a/include/etl/_strings/cstr.hpp b/include/etl/_strings/cstr.hpp index 0e5d79aef..1e7cc3c6f 100644 --- a/include/etl/_strings/cstr.hpp +++ b/include/etl/_strings/cstr.hpp @@ -52,7 +52,7 @@ template { auto* ptr = dest + strlen(dest); SizeT localCounter = 0; - while (*src != CharT(0) && localCounter != count) { + while (*src != CharT(0) and localCounter != count) { *ptr++ = *src++; ++localCounter; } @@ -147,7 +147,7 @@ template auto const length = strlen(dest); auto const srcLen = strlen(src); for (SizeT i = 0; i < length; ++i) { - if (!is_legal_char(src, srcLen, dest[i])) { + if (not is_legal_char(src, srcLen, dest[i])) { break; } ++result; @@ -173,7 +173,7 @@ template [[nodiscard]] constexpr auto strstr_impl(CharT* haystack, CharT* needle) noexcept -> CharT* { while (*haystack != CharT(0)) { - if ((*haystack == *needle) && (strcmp(haystack, needle) == 0)) { + if ((*haystack == *needle) and (strcmp(haystack, needle) == 0)) { return haystack; } haystack++; diff --git a/include/etl/_strings/to_floating_point.hpp b/include/etl/_strings/to_floating_point.hpp index 09a9cc61e..0cd3196a0 100644 --- a/include/etl/_strings/to_floating_point.hpp +++ b/include/etl/_strings/to_floating_point.hpp @@ -34,13 +34,13 @@ template auto const* ptr = str.data(); for (; *ptr != '\0'; ++ptr) { - if (etl::isspace(*ptr) && leadingSpaces) { + if (etl::isspace(*ptr) and leadingSpaces) { continue; } leadingSpaces = false; if (etl::isdigit(*ptr)) { - if (!afterDecimalPoint) { + if (not afterDecimalPoint) { res *= 10; // Shift the previous digits to the left res += *ptr - '0'; // Add the new one } else { diff --git a/include/etl/_tuple/tuple.hpp b/include/etl/_tuple/tuple.hpp index 424f8af2d..3638c4c22 100644 --- a/include/etl/_tuple/tuple.hpp +++ b/include/etl/_tuple/tuple.hpp @@ -84,15 +84,15 @@ struct tuple_storage, Ts...> : tuple_leaf.. // No. 2 explicit(not(is_convertible_v and ...)) constexpr tuple_storage(Ts const&... args) - requires((is_copy_constructible_v and ...) && (sizeof...(Ts) > 0)) + requires((is_copy_constructible_v and ...) and (sizeof...(Ts) > 0)) : tuple_leaf(args)... { } // No. 3 template - requires((is_constructible_v and ...) && (sizeof...(Ts) > 0) && (sizeof...(Ts) == sizeof...(Us))) - explicit(!(is_convertible_v and ...)) constexpr tuple_storage(Us&&... args) + requires((is_constructible_v and ...) and (sizeof...(Ts) > 0) and (sizeof...(Ts) == sizeof...(Us))) + explicit(not(is_convertible_v and ...)) constexpr tuple_storage(Us&&... args) : tuple_leaf(etl::forward(args))... { } @@ -102,7 +102,7 @@ struct tuple_storage, Ts...> : tuple_leaf.. using tuple_leaf::operator[]...; - constexpr auto swap(tuple_storage& other) noexcept((is_nothrow_swappable_v && ...)) -> void + constexpr auto swap(tuple_storage& other) noexcept((is_nothrow_swappable_v and ...)) -> void { (tuple_leaf::swap(etl::index_v, other[etl::index_v]), ...); } @@ -113,23 +113,23 @@ struct tuple_storage, Ts...> : tuple_leaf.. template struct tuple { // No. 1 - explicit(not(is_implicit_default_constructible_v && ...)) constexpr tuple() + explicit(not(is_implicit_default_constructible_v and ...)) constexpr tuple() requires((is_default_constructible_v and ...)) : _storage() { } // No. 2 - explicit(not(is_convertible_v && ...)) constexpr tuple(Ts const&... args) - requires((is_copy_constructible_v && ...) and (sizeof...(Ts) > 0)) + explicit(not(is_convertible_v and ...)) constexpr tuple(Ts const&... args) + requires((is_copy_constructible_v and ...) and (sizeof...(Ts) > 0)) : _storage(args...) { } // No. 3 template - requires((is_constructible_v && ...) and (sizeof...(Ts) > 0) and (sizeof...(Ts) == sizeof...(Us))) - explicit(!(is_convertible_v && ...)) constexpr tuple(Us&&... args) + requires((is_constructible_v and ...) and (sizeof...(Ts) > 0) and (sizeof...(Ts) == sizeof...(Us))) + explicit(not(is_convertible_v and ...)) constexpr tuple(Us&&... args) : _storage(etl::forward(args)...) { } diff --git a/include/etl/_type_traits/conjunction.hpp b/include/etl/_type_traits/conjunction.hpp index 3267dcaa4..2f7446674 100644 --- a/include/etl/_type_traits/conjunction.hpp +++ b/include/etl/_type_traits/conjunction.hpp @@ -13,7 +13,7 @@ namespace etl { /// performing a logical AND on the sequence of traits. /// \ingroup type_traits template -struct conjunction : bool_constant<(B::value && ...)> { }; +struct conjunction : bool_constant<(B::value and ...)> { }; /// \ingroup type_traits /// \relates conjunction diff --git a/include/etl/_type_traits/invoke_result.hpp b/include/etl/_type_traits/invoke_result.hpp index 02f71aa85..5dbf3a576 100644 --- a/include/etl/_type_traits/invoke_result.hpp +++ b/include/etl/_type_traits/invoke_result.hpp @@ -33,7 +33,7 @@ struct invoke_impl { static auto get(T&& t) -> decltype(t.get()); template > - requires(!is_base_of_v and !is_reference_wrapper::value) + requires(not is_base_of_v and !is_reference_wrapper::value) static auto get(T&& t) -> decltype(*etl::forward(t)); template diff --git a/include/etl/_type_traits/is_convertible.hpp b/include/etl/_type_traits/is_convertible.hpp index c30eec279..448671e96 100644 --- a/include/etl/_type_traits/is_convertible.hpp +++ b/include/etl/_type_traits/is_convertible.hpp @@ -40,8 +40,8 @@ template struct is_convertible : bool_constant< (decltype(detail::test_returnable(0))::value - && decltype(detail::test_nonvoid_convertible(0))::value) - || (is_void_v && is_void_v) + and decltype(detail::test_nonvoid_convertible(0))::value) + or (is_void_v and is_void_v) > { }; template diff --git a/include/etl/_type_traits/is_nothrow_constructible.hpp b/include/etl/_type_traits/is_nothrow_constructible.hpp index 7e23b8a4a..7024cbf21 100644 --- a/include/etl/_type_traits/is_nothrow_constructible.hpp +++ b/include/etl/_type_traits/is_nothrow_constructible.hpp @@ -34,7 +34,7 @@ struct nothrow_constructible_impl : nothrow_constructible_im template struct nothrow_constructible_impl - : bool_constant<(nothrow_constructible_impl::value && ...)> { }; + : bool_constant<(nothrow_constructible_impl::value and ...)> { }; #endif template diff --git a/include/etl/_type_traits/is_nothrow_convertible.hpp b/include/etl/_type_traits/is_nothrow_convertible.hpp index b1a35481b..46a3e99e4 100644 --- a/include/etl/_type_traits/is_nothrow_convertible.hpp +++ b/include/etl/_type_traits/is_nothrow_convertible.hpp @@ -14,7 +14,7 @@ namespace etl { template -struct is_nothrow_convertible : bool_constant && is_void_v> { }; +struct is_nothrow_convertible : bool_constant and is_void_v> { }; template requires requires { diff --git a/include/etl/_type_traits/is_nothrow_swappable_with.hpp b/include/etl/_type_traits/is_nothrow_swappable_with.hpp index 509fd6170..87bbd361c 100644 --- a/include/etl/_type_traits/is_nothrow_swappable_with.hpp +++ b/include/etl/_type_traits/is_nothrow_swappable_with.hpp @@ -14,7 +14,7 @@ namespace etl { // clang-format off template -struct _swap_no_throw : bool_constant(), declval())) && noexcept(swap(declval(), declval()))> { }; // NOLINT +struct _swap_no_throw : bool_constant(), declval())) and noexcept(swap(declval(), declval()))> { }; // NOLINT // clang-format on /// \ingroup type_traits diff --git a/include/etl/_type_traits/is_swappable_with.hpp b/include/etl/_type_traits/is_swappable_with.hpp index 32aaaa146..973ba0b3f 100644 --- a/include/etl/_type_traits/is_swappable_with.hpp +++ b/include/etl/_type_traits/is_swappable_with.hpp @@ -24,9 +24,9 @@ template struct is_nothrow_swappable; template - requires(etl::is_move_constructible_v && etl::is_move_assignable_v) + requires(etl::is_move_constructible_v and etl::is_move_assignable_v) constexpr auto -swap(T& a, T& b) noexcept(etl::is_nothrow_move_constructible_v && etl::is_nothrow_move_assignable_v) -> void; +swap(T& a, T& b) noexcept(etl::is_nothrow_move_constructible_v and etl::is_nothrow_move_assignable_v) -> void; template requires(etl::is_swappable::value) diff --git a/include/etl/_utility/pair.hpp b/include/etl/_utility/pair.hpp index 188648bd0..940b346da 100644 --- a/include/etl/_utility/pair.hpp +++ b/include/etl/_utility/pair.hpp @@ -40,7 +40,7 @@ struct pair { /// \brief Default constructor. Value-initializes both elements. explicit( - not is_implicit_default_constructible_v || not is_implicit_default_constructible_v + not is_implicit_default_constructible_v or not is_implicit_default_constructible_v ) constexpr pair() requires(is_default_constructible_v and is_default_constructible_v) : first{} @@ -61,7 +61,7 @@ struct pair { /// \brief Initializes first with forward(x) and second with forward(y). template requires(is_constructible_v and is_constructible_v) - explicit(not is_convertible_v || not is_convertible_v) constexpr pair(U1&& x, U2&& y) + explicit(not is_convertible_v or not is_convertible_v) constexpr pair(U1&& x, U2&& y) : first(etl::forward(x)) , second(etl::forward(y)) { @@ -81,7 +81,7 @@ struct pair { /// \brief Initializes first with forward(p.first) and second with forward(p.second). template requires(is_constructible_v and is_constructible_v) - explicit(not is_convertible_v || not is_convertible_v) constexpr pair(pair&& p) + explicit(not is_convertible_v or not is_convertible_v) constexpr pair(pair&& p) : first(etl::forward(p.first)) , second(etl::forward(p.second)) { diff --git a/include/etl/_utility/swap.hpp b/include/etl/_utility/swap.hpp index c2a8ae742..08290557a 100644 --- a/include/etl/_utility/swap.hpp +++ b/include/etl/_utility/swap.hpp @@ -17,7 +17,7 @@ namespace etl { /// \brief Exchanges the given values. Swaps the values a and b. This overload /// does not participate in overload resolution unless -/// etl::is_move_constructible_v && etl::is_move_assignable_v is true. +/// etl::is_move_constructible_v and etl::is_move_assignable_v is true. /// /// \details https://en.cppreference.com/w/cpp/algorithm/swap template diff --git a/include/etl/_vector/static_vector.hpp b/include/etl/_vector/static_vector.hpp index 7ecf265ce..14f9a8af7 100644 --- a/include/etl/_vector/static_vector.hpp +++ b/include/etl/_vector/static_vector.hpp @@ -201,7 +201,7 @@ struct static_vector_trivial_storage { requires(is_constructible_v and is_assignable_v) constexpr auto emplace_back(Args&&... args) noexcept -> void { - TETL_PRECONDITION(!full()); + TETL_PRECONDITION(not full()); index(_data, size()) = T(etl::forward(args)...); unsafe_set_size(static_cast(size()) + 1U); } @@ -209,7 +209,7 @@ struct static_vector_trivial_storage { /// \brief Remove the last element from the container. constexpr auto pop_back() noexcept -> void { - TETL_PRECONDITION(!empty()); + TETL_PRECONDITION(not empty()); unsafe_set_size(static_cast(size() - 1)); } @@ -248,7 +248,7 @@ struct static_vector_trivial_storage { /// \brief Storage for non-trivial elements. template struct static_vector_non_trivial_storage { - static_assert(!is_trivial_v); + static_assert(not is_trivial_v); static_assert(Capacity != size_t{0}); using size_type = etl::smallest_size_t; @@ -324,7 +324,7 @@ struct static_vector_non_trivial_storage { template auto emplace_back(Args&&... args) noexcept(noexcept(new (end()) T(etl::forward(args)...))) -> void { - TETL_PRECONDITION(!full()); + TETL_PRECONDITION(not full()); new (end()) T(etl::forward(args)...); unsafe_set_size(static_cast(size() + 1)); } @@ -332,7 +332,7 @@ struct static_vector_non_trivial_storage { /// \brief Remove the last element from the container. auto pop_back() noexcept(is_nothrow_destructible_v) -> void { - TETL_PRECONDITION(!empty()); + TETL_PRECONDITION(not empty()); auto* ptr = end() - 1; ptr->~T(); unsafe_set_size(static_cast(size() - 1)); @@ -435,7 +435,7 @@ struct static_vector : detail::static_vector_storage_type { private: constexpr auto emplace_n(size_type n) noexcept( (is_move_constructible_v and is_nothrow_move_constructible_v) - || (is_copy_constructible_v and is_nothrow_copy_constructible_v) + or (is_copy_constructible_v and is_nothrow_copy_constructible_v) ) -> void { TETL_PRECONDITION(n <= capacity()); @@ -524,7 +524,7 @@ struct static_vector : detail::static_vector_storage_type { requires(is_constructible_v and is_assignable_v) constexpr auto push_back(U&& value) noexcept(noexcept(emplace_back(etl::forward(value)))) -> void { - TETL_PRECONDITION(!full()); + TETL_PRECONDITION(not full()); emplace_back(etl::forward(value)); } @@ -556,7 +556,7 @@ struct static_vector : detail::static_vector_storage_type { noexcept(move_insert(position, declval(), declval())) ) -> iterator { - TETL_PRECONDITION(!full()); + TETL_PRECONDITION(not full()); assert_iterator_in_range(position); value_type a(etl::forward(args)...); return move_insert(position, &a, &a + 1); @@ -569,7 +569,7 @@ struct static_vector : detail::static_vector_storage_type { -> iterator requires(is_move_constructible_v) { - TETL_PRECONDITION(!full()); + TETL_PRECONDITION(not full()); assert_iterator_in_range(position); return move_insert(position, &x, &x + 1); } @@ -594,7 +594,7 @@ struct static_vector : detail::static_vector_storage_type { insert(const_iterator position, const_reference x) noexcept(noexcept(insert(position, size_type(1), x))) -> iterator requires(is_copy_constructible_v) { - TETL_PRECONDITION(!full()); + TETL_PRECONDITION(not full()); assert_iterator_in_range(position); return insert(position, size_type(1), x); } @@ -603,7 +603,7 @@ struct static_vector : detail::static_vector_storage_type { constexpr auto insert(const_iterator position, InputIt first, InputIt last) noexcept(noexcept(emplace_back(*first))) -> iterator requires( - detail::InputIterator && is_constructible_v> + detail::InputIterator and is_constructible_v> ) { assert_iterator_in_range(position); @@ -662,7 +662,7 @@ struct static_vector : detail::static_vector_storage_type { /// \brief Copy assignment. constexpr auto operator=(static_vector const& other) noexcept( - noexcept(clear()) && noexcept(insert(begin(), other.begin(), other.end())) + noexcept(clear()) and noexcept(insert(begin(), other.begin(), other.end())) ) -> static_vector& requires(is_assignable_v) { @@ -688,7 +688,7 @@ struct static_vector : detail::static_vector_storage_type { /// \brief Initializes vector with n default-constructed elements. explicit constexpr static_vector(size_type n) noexcept(noexcept(emplace_n(n))) - requires(is_copy_constructible_v || is_move_constructible_v) + requires(is_copy_constructible_v or is_move_constructible_v) { TETL_PRECONDITION(n <= capacity()); emplace_n(n); @@ -785,13 +785,13 @@ struct static_vector : detail::static_vector_storage_type { /// \brief back [[nodiscard]] constexpr auto back() noexcept -> reference { - TETL_PRECONDITION(!empty()); + TETL_PRECONDITION(not empty()); return detail::index(*this, static_cast(size() - 1)); } [[nodiscard]] constexpr auto back() const noexcept -> const_reference { - TETL_PRECONDITION(!empty()); + TETL_PRECONDITION(not empty()); return detail::index(*this, static_cast(size() - 1)); } @@ -828,8 +828,8 @@ struct static_vector : detail::static_vector_storage_type { /// \brief Resizes the container to contain sz elements. If elements need to /// be appended, these are move-constructed from `T{}` (or copy-constructed constexpr auto resize(size_type sz) noexcept( - (is_move_constructible_v && is_nothrow_move_constructible_v) - || (is_copy_constructible_v && is_nothrow_copy_constructible_v) + (is_move_constructible_v and is_nothrow_move_constructible_v) + or (is_copy_constructible_v and is_nothrow_copy_constructible_v) ) -> void requires(detail::is_movable_v) { diff --git a/tests/functional/hash.t.cpp b/tests/functional/hash.t.cpp index 8cddf56b9..86c039293 100644 --- a/tests/functional/hash.t.cpp +++ b/tests/functional/hash.t.cpp @@ -28,7 +28,7 @@ static constexpr auto test() -> bool CHECK(etl::hash{}(42) == etl::hash{}(42)); #if __has_builtin(__builtin_is_constant_evaluated) - if (!etl::is_constant_evaluated()) { + if (not etl::is_constant_evaluated()) { auto val = T{42}; CHECK(etl::hash{}(&val) != 0); } diff --git a/tests/mutex/test_mutex.hpp b/tests/mutex/test_mutex.hpp index dd5acee2e..84d68de59 100644 --- a/tests/mutex/test_mutex.hpp +++ b/tests/mutex/test_mutex.hpp @@ -27,7 +27,7 @@ struct Mutex { constexpr auto try_lock() noexcept -> bool { - if (not _isLocked && not _failOnTryLock) { + if (not _isLocked and not _failOnTryLock) { _isLocked = true; return true; } From 37741bb9f0043c19f1377b5e4fc6a0c58b1f0c2c Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 19:37:14 +0200 Subject: [PATCH 29/34] Upgrade clang-format to v21.1.1 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4595e2699..1b32a4685 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,7 +25,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v21.1.0 + rev: v21.1.1 hooks: - id: clang-format types_or: [c++, c] From 3bef7793cfcf77ce53acc361e851b3b2d9c215b5 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 19:52:18 +0200 Subject: [PATCH 30/34] [cmath] Add tests for pow --- include/etl/_cmath/pow.hpp | 84 ++++++++++++++++++++++++-------------- tests/cmath/CMakeLists.txt | 1 + tests/cmath/pow.t.cpp | 53 ++++++++++++++++++++++++ tests/testing/approx.hpp | 2 +- 4 files changed, 109 insertions(+), 31 deletions(-) create mode 100644 tests/cmath/pow.t.cpp diff --git a/include/etl/_cmath/pow.hpp b/include/etl/_cmath/pow.hpp index 3b0061388..5e4025722 100644 --- a/include/etl/_cmath/pow.hpp +++ b/include/etl/_cmath/pow.hpp @@ -11,6 +11,52 @@ namespace etl { +namespace detail { + +inline constexpr struct pow { + template + [[nodiscard]] constexpr auto operator()(Float base, Float exponent) const noexcept -> Float + { + if (is_constant_evaluated()) { +#if __has_constexpr_builtin(__builtin_powf) + if constexpr (etl::same_as) { + return __builtin_powf(base, exponent); + } +#endif +#if __has_constexpr_builtin(__builtin_pow) + if constexpr (etl::same_as) { + return __builtin_pow(base, exponent); + } +#endif +#if __has_constexpr_builtin(__builtin_powl) + if constexpr (etl::same_as) { + return __builtin_powl(base, exponent); + } +#endif + } else { +#if __has_builtin(__builtin_powf) + if constexpr (etl::same_as) { + return __builtin_powf(base, exponent); + } +#endif +#if __has_builtin(__builtin_pow) + if constexpr (etl::same_as) { + return __builtin_pow(base, exponent); + } +#endif +#if __has_builtin(__builtin_powl) + if constexpr (etl::same_as) { + return __builtin_powl(base, exponent); + } +#endif + } + + return etl::detail::gcem::pow(base, exponent); + } +} pow; + +} // namespace detail + /// \ingroup cmath /// @{ @@ -18,78 +64,56 @@ namespace etl { /// \details https://en.cppreference.com/w/cpp/numeric/math/pow [[nodiscard]] constexpr auto pow(float base, float exp) -> float { - if (is_constant_evaluated()) { -#if __has_constexpr_builtin(__builtin_powf) - return __builtin_powf(base, exp); -#else - return etl::detail::gcem::pow(base, exp); -#endif - } -#if __has_builtin(__builtin_powf) - return __builtin_powf(base, exp); -#else - return etl::detail::gcem::pow(base, exp); -#endif + return etl::detail::pow(base, exp); } /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow [[nodiscard]] constexpr auto powf(float base, float exp) -> float { - return etl::pow(base, exp); + return etl::detail::pow(base, exp); } /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow [[nodiscard]] constexpr auto pow(double base, double exp) -> double { - if (is_constant_evaluated()) { -#if __has_constexpr_builtin(__builtin_pow) - return __builtin_pow(base, exp); -#else - return etl::detail::gcem::pow(base, exp); -#endif - } -#if __has_builtin(__builtin_pow) - return __builtin_pow(base, exp); -#else - return etl::detail::gcem::pow(base, exp); -#endif + return etl::detail::pow(base, exp); } /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow [[nodiscard]] constexpr auto pow(long double base, long double exp) -> long double { - return detail::gcem::pow(base, exp); + return etl::detail::pow(base, exp); } /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow [[nodiscard]] constexpr auto powl(long double base, long double exp) -> long double { - return etl::pow(base, exp); + return etl::detail::pow(base, exp); } /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow [[nodiscard]] constexpr auto pow(float base, int iexp) -> float { - return etl::pow(base, static_cast(iexp)); + return etl::detail::pow(base, static_cast(iexp)); } /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow [[nodiscard]] constexpr auto pow(double base, int iexp) -> double { - return etl::pow(base, static_cast(iexp)); + return etl::detail::pow(base, static_cast(iexp)); } /// Computes the value of base raised to the power exp /// \details https://en.cppreference.com/w/cpp/numeric/math/pow [[nodiscard]] constexpr auto pow(long double base, int iexp) -> long double { - return etl::pow(base, static_cast(iexp)); + return etl::detail::pow(base, static_cast(iexp)); } /// @} diff --git a/tests/cmath/CMakeLists.txt b/tests/cmath/CMakeLists.txt index 72ed62a08..fa847d9f7 100644 --- a/tests/cmath/CMakeLists.txt +++ b/tests/cmath/CMakeLists.txt @@ -29,6 +29,7 @@ tetl_add_test(${PROJECT_NAME} log) tetl_add_test(${PROJECT_NAME} log2) tetl_add_test(${PROJECT_NAME} log10) tetl_add_test(${PROJECT_NAME} nextafter) +tetl_add_test(${PROJECT_NAME} pow) tetl_add_test(${PROJECT_NAME} round) tetl_add_test(${PROJECT_NAME} signbit) tetl_add_test(${PROJECT_NAME} sin) diff --git a/tests/cmath/pow.t.cpp b/tests/cmath/pow.t.cpp new file mode 100644 index 000000000..64ae4dc7d --- /dev/null +++ b/tests/cmath/pow.t.cpp @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: BSL-1.0 +// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch + +#include "testing/approx.hpp" +#include "testing/testing.hpp" + +#if defined(TETL_ENABLE_CXX_MODULES) +import etl; +#else + #include + #include +#endif + +template +static constexpr auto test_type() -> bool +{ + CHECK_APPROX(etl::pow(T(0), T(1)), T(0)); + CHECK_APPROX(etl::pow(T(2), T(0)), T(1)); + CHECK_APPROX(etl::pow(T(2), T(1)), T(2)); + CHECK_APPROX(etl::pow(T(2), T(2)), T(4)); + CHECK_APPROX(etl::pow(T(etl::numbers::pi), T(1)), T(etl::numbers::pi)); + + return true; +} + +static constexpr auto test_all() -> bool +{ + // float + CHECK_APPROX(etl::pow(4.0F, 2), 16.0F); + CHECK_APPROX(etl::pow(4.0F, 2.0F), 16.0F); + CHECK_APPROX(etl::powf(4.0F, 2.0F), 16.0F); + + // double + CHECK_APPROX(etl::pow(4.0, 2), 16.0); + CHECK_APPROX(etl::pow(4.0, 2.0), 16.0); + + // long double + CHECK_APPROX(etl::pow(4.0L, 2), 16.0L); + CHECK_APPROX(etl::pow(4.0L, 2.0L), 16.0L); + CHECK_APPROX(etl::powl(4.0L, 2.0L), 16.0L); + + CHECK(test_type()); + CHECK(test_type()); + CHECK(test_type()); + + return true; +} + +auto main() -> int +{ + STATIC_CHECK(test_all()); + return 0; +} diff --git a/tests/testing/approx.hpp b/tests/testing/approx.hpp index 56e6b4702..e9897366c 100644 --- a/tests/testing/approx.hpp +++ b/tests/testing/approx.hpp @@ -11,7 +11,7 @@ import etl; #endif template -constexpr auto approx(T a, T b, T epsilon = static_cast(0.001)) -> bool +constexpr auto approx(T a, T b, T epsilon = static_cast(0.0001)) -> bool { return etl::fabs(a - b) < epsilon; } From 1c2f00c113dd34ede207399c32cc29f0dbbf40c9 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 20:06:09 +0200 Subject: [PATCH 31/34] Cleanup internal includes --- include/etl/_bit/byteswap.hpp | 1 - include/etl/_cmath/atan2.hpp | 1 + include/etl/_cmath/atanh.hpp | 1 + include/etl/_cmath/ceil.hpp | 1 + include/etl/_cmath/cosh.hpp | 1 + include/etl/_cmath/erf.hpp | 1 + include/etl/_cmath/fdim.hpp | 3 +++ include/etl/_cmath/fmax.hpp | 1 + include/etl/_cmath/fmin.hpp | 1 + include/etl/_cmath/fmod.hpp | 1 + include/etl/_cmath/isfinite.hpp | 1 + include/etl/_cmath/isinf.hpp | 1 - include/etl/_cmath/isnan.hpp | 1 - include/etl/_cmath/lgamma.hpp | 1 + include/etl/_cmath/log1p.hpp | 1 + include/etl/_cmath/remainder.hpp | 1 + include/etl/_cmath/sinh.hpp | 1 + include/etl/_cmath/sqrt.hpp | 1 + include/etl/_cmath/tgamma.hpp | 1 + include/etl/_contracts/check.hpp | 1 - 20 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/etl/_bit/byteswap.hpp b/include/etl/_bit/byteswap.hpp index dab4cbb1f..6d359c7a0 100644 --- a/include/etl/_bit/byteswap.hpp +++ b/include/etl/_bit/byteswap.hpp @@ -8,7 +8,6 @@ #include #include #include -#include namespace etl { diff --git a/include/etl/_cmath/atan2.hpp b/include/etl/_cmath/atan2.hpp index 043db5170..104f0ec82 100644 --- a/include/etl/_cmath/atan2.hpp +++ b/include/etl/_cmath/atan2.hpp @@ -5,6 +5,7 @@ #define TETL_CMATH_ATAN2_HPP #include +#include namespace etl { diff --git a/include/etl/_cmath/atanh.hpp b/include/etl/_cmath/atanh.hpp index 445d1b551..aafb61a07 100644 --- a/include/etl/_cmath/atanh.hpp +++ b/include/etl/_cmath/atanh.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { diff --git a/include/etl/_cmath/ceil.hpp b/include/etl/_cmath/ceil.hpp index 6e3bb5b4e..8c479486c 100644 --- a/include/etl/_cmath/ceil.hpp +++ b/include/etl/_cmath/ceil.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { diff --git a/include/etl/_cmath/cosh.hpp b/include/etl/_cmath/cosh.hpp index d2d966bc8..d64b2354d 100644 --- a/include/etl/_cmath/cosh.hpp +++ b/include/etl/_cmath/cosh.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { diff --git a/include/etl/_cmath/erf.hpp b/include/etl/_cmath/erf.hpp index 2e471e9da..789777368 100644 --- a/include/etl/_cmath/erf.hpp +++ b/include/etl/_cmath/erf.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { diff --git a/include/etl/_cmath/fdim.hpp b/include/etl/_cmath/fdim.hpp index d1864e98a..aa1a30b2e 100644 --- a/include/etl/_cmath/fdim.hpp +++ b/include/etl/_cmath/fdim.hpp @@ -4,7 +4,10 @@ #ifndef TETL_CMATH_FDIM_HPP #define TETL_CMATH_FDIM_HPP +#include + #include +#include namespace etl { diff --git a/include/etl/_cmath/fmax.hpp b/include/etl/_cmath/fmax.hpp index d52f1ca34..a3a979d79 100644 --- a/include/etl/_cmath/fmax.hpp +++ b/include/etl/_cmath/fmax.hpp @@ -5,6 +5,7 @@ #define TETL_CMATH_FMAX_HPP #include +#include namespace etl { diff --git a/include/etl/_cmath/fmin.hpp b/include/etl/_cmath/fmin.hpp index ea2df3975..f117c575b 100644 --- a/include/etl/_cmath/fmin.hpp +++ b/include/etl/_cmath/fmin.hpp @@ -5,6 +5,7 @@ #define TETL_CMATH_FMIN_HPP #include +#include namespace etl { diff --git a/include/etl/_cmath/fmod.hpp b/include/etl/_cmath/fmod.hpp index 2023eb25f..25b602da8 100644 --- a/include/etl/_cmath/fmod.hpp +++ b/include/etl/_cmath/fmod.hpp @@ -5,6 +5,7 @@ #define TETL_CMATH_FMOD_HPP #include +#include namespace etl { diff --git a/include/etl/_cmath/isfinite.hpp b/include/etl/_cmath/isfinite.hpp index 6fbf89f57..96d4c34c8 100644 --- a/include/etl/_cmath/isfinite.hpp +++ b/include/etl/_cmath/isfinite.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { diff --git a/include/etl/_cmath/isinf.hpp b/include/etl/_cmath/isinf.hpp index 1e800e935..8565ce1bc 100644 --- a/include/etl/_cmath/isinf.hpp +++ b/include/etl/_cmath/isinf.hpp @@ -8,7 +8,6 @@ #include #include -#include namespace etl { diff --git a/include/etl/_cmath/isnan.hpp b/include/etl/_cmath/isnan.hpp index e20607ff8..cf68a03a6 100644 --- a/include/etl/_cmath/isnan.hpp +++ b/include/etl/_cmath/isnan.hpp @@ -7,7 +7,6 @@ #include #include -#include namespace etl { diff --git a/include/etl/_cmath/lgamma.hpp b/include/etl/_cmath/lgamma.hpp index 11649d9ea..a62a407aa 100644 --- a/include/etl/_cmath/lgamma.hpp +++ b/include/etl/_cmath/lgamma.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { diff --git a/include/etl/_cmath/log1p.hpp b/include/etl/_cmath/log1p.hpp index 2ca5ccc31..b5bc74103 100644 --- a/include/etl/_cmath/log1p.hpp +++ b/include/etl/_cmath/log1p.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { diff --git a/include/etl/_cmath/remainder.hpp b/include/etl/_cmath/remainder.hpp index 0da249a8f..b0ec7b7d0 100644 --- a/include/etl/_cmath/remainder.hpp +++ b/include/etl/_cmath/remainder.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { diff --git a/include/etl/_cmath/sinh.hpp b/include/etl/_cmath/sinh.hpp index 669b05baf..61016c91c 100644 --- a/include/etl/_cmath/sinh.hpp +++ b/include/etl/_cmath/sinh.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { diff --git a/include/etl/_cmath/sqrt.hpp b/include/etl/_cmath/sqrt.hpp index fb9632cd3..910e89bcb 100644 --- a/include/etl/_cmath/sqrt.hpp +++ b/include/etl/_cmath/sqrt.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace etl { diff --git a/include/etl/_cmath/tgamma.hpp b/include/etl/_cmath/tgamma.hpp index c15f4dead..e138a0d21 100644 --- a/include/etl/_cmath/tgamma.hpp +++ b/include/etl/_cmath/tgamma.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace etl { diff --git a/include/etl/_contracts/check.hpp b/include/etl/_contracts/check.hpp index 7762c7fdd..23ddea6b5 100644 --- a/include/etl/_contracts/check.hpp +++ b/include/etl/_contracts/check.hpp @@ -5,7 +5,6 @@ #define TETL_CONTRACTS_CHECK_HPP #include -#include #if defined(TETL_ENABLE_CONTRACT_CHECKS_SAFE) #define TETL_PRECONDITION_SAFE(...) TETL_ASSERT_IMPL(__VA_ARGS__) From 08e1e8cf1e22e9424d64363192bfbde37a8539e9 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 20:36:13 +0200 Subject: [PATCH 32/34] [cmath] Fix pow(long double) on Windows --- include/etl/_cmath/pow.hpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/include/etl/_cmath/pow.hpp b/include/etl/_cmath/pow.hpp index 5e4025722..aeacf86a8 100644 --- a/include/etl/_cmath/pow.hpp +++ b/include/etl/_cmath/pow.hpp @@ -27,11 +27,6 @@ inline constexpr struct pow { if constexpr (etl::same_as) { return __builtin_pow(base, exponent); } -#endif -#if __has_constexpr_builtin(__builtin_powl) - if constexpr (etl::same_as) { - return __builtin_powl(base, exponent); - } #endif } else { #if __has_builtin(__builtin_powf) @@ -43,11 +38,6 @@ inline constexpr struct pow { if constexpr (etl::same_as) { return __builtin_pow(base, exponent); } -#endif -#if __has_builtin(__builtin_powl) - if constexpr (etl::same_as) { - return __builtin_powl(base, exponent); - } #endif } From 496902236664cedfd8957d833b2a130eea9642cc Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Tue, 16 Sep 2025 23:29:15 +0200 Subject: [PATCH 33/34] [bitset] Fix string_view constructor --- fuzzing/src/bitset.fuzz.cpp | 26 +++++++++++++++++------ include/etl/_bitset/bitset.hpp | 38 +++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/fuzzing/src/bitset.fuzz.cpp b/fuzzing/src/bitset.fuzz.cpp index 6051cd835..7d3f36929 100644 --- a/fuzzing/src/bitset.fuzz.cpp +++ b/fuzzing/src/bitset.fuzz.cpp @@ -4,18 +4,22 @@ #include "fuzzing.hpp" #include +#include #include #include +template auto fuzz_bitset(FuzzedDataProvider& p) -> int { - auto const val = p.ConsumeIntegral(); + using UInt = etl::conditional_t<(Size > 32), etl::uint64_t, etl::uint32_t>; - auto const eset = etl::bitset<32>{val}; - auto const sset = std::bitset<32>{val}; + auto const val = p.ConsumeIntegral(); - auto const estr = eset.to_string<32>(); + auto const eset = etl::bitset{val}; + auto const sset = std::bitset{val}; + + auto const estr = eset.template to_string(); auto const sstr = sset.to_string(); auto const eview = etl::string_view{estr.data(), estr.size()}; @@ -26,12 +30,20 @@ auto fuzz_bitset(FuzzedDataProvider& p) -> int if ((eview != sview) or (elong != slong)) { std::printf("etl::bitset::to_ullong\n"); - std::printf("val: '%u'\n", val); + std::printf("val: '%llu'\n", static_cast(val)); std::printf("estr: '%s'\nsstr: '%s'\n", estr.c_str(), sstr.c_str()); std::printf("elong: '%llu' slong: '%llu'\n", elong, slong); return 1; } + auto const efromstr = etl::bitset{estr.c_str()}; + + if (eset != efromstr) { + std::printf("etl::bitset(string_view)\n"); + std::printf("estr: '%s'\nefromstr: '%s'\n", estr.c_str(), efromstr.template to_string().c_str()); + return 1; + } + return 0; } @@ -41,6 +53,8 @@ extern "C" auto LLVMFuzzerTestOneInput(std::uint8_t const* data, std::size_t siz return 0; } auto p = FuzzedDataProvider{data, size}; - RUN(fuzz_bitset(p)); + RUN(fuzz_bitset<24>(p)); + RUN(fuzz_bitset<32>(p)); + RUN(fuzz_bitset<64>(p)); return 0; } diff --git a/include/etl/_bitset/bitset.hpp b/include/etl/_bitset/bitset.hpp index 326d7d5eb..0c7def435 100644 --- a/include/etl/_bitset/bitset.hpp +++ b/include/etl/_bitset/bitset.hpp @@ -5,6 +5,9 @@ #define TETL_BITSET_BITSET_HPP #include +#include +#include +#include #include #include #include @@ -59,17 +62,20 @@ struct bitset { CharT zero = CharT('0'), CharT one = CharT('1') ) - : bitset(0ULL) + : bitset() { - auto const len = etl::min(n, str.size() - pos); + using size_type = decltype(pos); + + auto const len = etl::min(n, str.size() - pos); + auto const substr = str.substr(pos, len); TETL_PRECONDITION(len >= 0); TETL_PRECONDITION(len <= size()); - for (decltype(pos) i = 0; i < len; ++i) { - if (Traits::eq(str[i + pos], one)) { + for (size_type i{0}; i < len; ++i) { + if (Traits::eq(substr[len - i - 1], one)) { set(i, true); } - if (Traits::eq(str[i + pos], zero)) { + if (Traits::eq(substr[len - i - 1], zero)) { set(i, false); } } @@ -308,15 +314,23 @@ struct bitset { template [[nodiscard]] constexpr auto to_unsigned_type() const noexcept -> UInt { - constexpr auto digits = static_cast(etl::numeric_limits::digits); - auto const idx = etl::min(static_cast(size()), digits); - UInt result{}; - for (UInt i{0}; i != idx; ++i) { - if (test(static_cast(i))) { - result = etl::set_bit(result, i); + if constexpr (sizeof(UInt) * CHAR_BIT == Bits) { + if constexpr (etl::endian::native == etl::endian::little) { + return etl::bit_cast(_bits); + } else { + return etl::byteswap(etl::bit_cast(_bits)); + } + } else { + constexpr auto digits = static_cast(etl::numeric_limits::digits); + auto const idx = etl::min(static_cast(size()), digits); + UInt result{}; + for (UInt i{0}; i != idx; ++i) { + if (test(static_cast(i))) { + result = etl::set_bit(result, i); + } } + return result; } - return result; } basic_bitset _bits; From 6598fa7b5f6b77c431944d717443eea833619db7 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Wed, 17 Sep 2025 00:16:11 +0200 Subject: [PATCH 34/34] [bitset] Fix to_ulong on Windows --- include/etl/_bitset/bitset.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/etl/_bitset/bitset.hpp b/include/etl/_bitset/bitset.hpp index 0c7def435..c052f289b 100644 --- a/include/etl/_bitset/bitset.hpp +++ b/include/etl/_bitset/bitset.hpp @@ -314,7 +314,7 @@ struct bitset { template [[nodiscard]] constexpr auto to_unsigned_type() const noexcept -> UInt { - if constexpr (sizeof(UInt) * CHAR_BIT == Bits) { + if constexpr (sizeof(UInt) == sizeof(_bits)) { if constexpr (etl::endian::native == etl::endian::little) { return etl::bit_cast(_bits); } else {