From 91a5dec3e37f211b14fd5921083cc563a5202195 Mon Sep 17 00:00:00 2001 From: Ben Deane Date: Tue, 7 Jul 2026 18:55:16 -0600 Subject: [PATCH 1/2] :art: Remove `udls.hpp` dependency on `type_traits.hpp` Problem: - `udls.hpp` depends on `type_traits` just for `to_underlying`, but this is not needed. Solution: - Remove the `type_traits` dependency. --- docs/header_graph.mmd | 1 - include/stdx/udls.hpp | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/header_graph.mmd b/docs/header_graph.mmd index 5a4fcbe..157b031 100644 --- a/docs/header_graph.mmd +++ b/docs/header_graph.mmd @@ -24,7 +24,6 @@ flowchart BT concepts(concepts.hpp) concepts --> type_traits udls(udls.hpp) - udls --> type_traits function_traits(function_traits.hpp) function_traits --> type_traits diff --git a/include/stdx/udls.hpp b/include/stdx/udls.hpp index 4421dfd..a269f2b 100644 --- a/include/stdx/udls.hpp +++ b/include/stdx/udls.hpp @@ -1,8 +1,5 @@ #pragma once -#include -#include - #include #include #include @@ -41,8 +38,7 @@ consteval auto maybe_add_digit(Sum s) { template struct raw_parser { template consteval static auto parse() { - using U = decltype(stdx::to_underlying(std::declval())); - auto x = U{}; + auto x = T{}; ((x = maybe_add_digit(x)), ...); return T{x}; } From eb3b405d66e7191e6534955095192d0430a520be Mon Sep 17 00:00:00 2001 From: Ben Deane Date: Tue, 7 Jul 2026 18:56:18 -0600 Subject: [PATCH 2/2] :fire: Remove `remove_cvref_t` Problem: - `remove_cvref_t` is a C++20 feature that has long since been available in supported toolchains. - See https://cppstat.dev/?search=remove_cvref Solution: - Remove `remove_cvref_t`. Note: - Many places were already using `std::remove_cvref_t`. --- docs/type_traits.adoc | 1 - include/stdx/byterator.hpp | 4 ++-- include/stdx/cached.hpp | 3 +-- include/stdx/call_by_need.hpp | 4 ++-- include/stdx/concepts.hpp | 6 ++++-- include/stdx/function_traits.hpp | 4 ++-- include/stdx/functional.hpp | 4 ++-- include/stdx/iterator.hpp | 4 ++-- include/stdx/latched.hpp | 4 ++-- include/stdx/optional.hpp | 33 +++++++++++++++---------------- include/stdx/span.hpp | 2 +- include/stdx/tuple.hpp | 2 +- include/stdx/tuple_algorithms.hpp | 6 +++--- include/stdx/type_traits.hpp | 9 ++------- test/CMakeLists.txt | 1 - test/call_by_need.cpp | 4 ++-- test/remove_cvref.cpp | 14 ------------- test/span.cpp | 2 +- 18 files changed, 43 insertions(+), 64 deletions(-) delete mode 100644 test/remove_cvref.cpp diff --git a/docs/type_traits.adoc b/docs/type_traits.adoc index 1da95ba..b0bae5f 100644 --- a/docs/type_traits.adoc +++ b/docs/type_traits.adoc @@ -10,7 +10,6 @@ contains a few things from the standard: * https://en.cppreference.com/w/cpp/types/is_constant_evaluated[`is_constant_evaluated`] (from C++20) * https://en.cppreference.com/w/cpp/types/is_function[`is_function_v`] (implemented with Walter Brown's method) * https://en.cppreference.com/w/cpp/types/is_scoped_enum[`is_scoped_enum_v`] (from C++23) -* https://en.cppreference.com/w/cpp/types/remove_cvref[`remove_cvref_t`] (from C++20) * https://en.cppreference.com/w/cpp/utility/to_underlying[`to_underlying`] (from C++23) * https://en.cppreference.com/w/cpp/types/type_identity[`type_identity`] (from C++20) diff --git a/include/stdx/byterator.hpp b/include/stdx/byterator.hpp index deea5d3..283d821 100644 --- a/include/stdx/byterator.hpp +++ b/include/stdx/byterator.hpp @@ -163,9 +163,9 @@ template class byterator { } template - requires std::is_trivially_copyable_v> + requires std::is_trivially_copyable_v> auto write(V &&v) -> void { - using R = remove_cvref_t; + using R = std::remove_cvref_t; std::memcpy(ptr, std::addressof(v), sizeof(R)); advance(); } diff --git a/include/stdx/cached.hpp b/include/stdx/cached.hpp index 8b12115..8006ca1 100644 --- a/include/stdx/cached.hpp +++ b/include/stdx/cached.hpp @@ -2,7 +2,6 @@ #include #include -#include namespace stdx { inline namespace v1 { @@ -17,7 +16,7 @@ template struct cached : latched { } }; -template cached(F) -> cached>; +template cached(F) -> cached>; template using cached_value_t = latched_value_t; } // namespace v1 diff --git a/include/stdx/call_by_need.hpp b/include/stdx/call_by_need.hpp index daef889..e4355cc 100644 --- a/include/stdx/call_by_need.hpp +++ b/include/stdx/call_by_need.hpp @@ -156,8 +156,8 @@ constexpr auto call_by_need(Fs &&fs, Args &&args) { std::forward(fs)))...>:: template compute_call_info( std::forward(args)))...>(); - }(std::make_index_sequence>>{}, - std::make_index_sequence>>{}); + }(std::make_index_sequence>>{}, + std::make_index_sequence>>{}); auto new_fs = [&](std::index_sequence) { return tuple{get(std::forward(fs))..., diff --git a/include/stdx/concepts.hpp b/include/stdx/concepts.hpp index ea09f8b..3cd60e7 100644 --- a/include/stdx/concepts.hpp +++ b/include/stdx/concepts.hpp @@ -50,7 +50,8 @@ template constexpr auto same_none = not same_any; template -concept same_as_unqualified = same_as, remove_cvref_t>; +concept same_as_unqualified = + same_as, std::remove_cvref_t>; template concept equality_comparable = requires(T const &t) { @@ -137,7 +138,8 @@ template typename TypeTrait> concept has_trait = TypeTrait::value; template -concept same_as_unqualified = same_as, remove_cvref_t>; +concept same_as_unqualified = + same_as, std::remove_cvref_t>; template concept structural = is_structural_v; diff --git a/include/stdx/function_traits.hpp b/include/stdx/function_traits.hpp index 9fc2e2e..05adb7d 100644 --- a/include/stdx/function_traits.hpp +++ b/include/stdx/function_traits.hpp @@ -128,8 +128,8 @@ template struct detect_call_operator { }; template struct detect_call_operator< - F, std::void_t::operator())>> - : function_traits::operator())> {}; + F, std::void_t::operator())>> + : function_traits::operator())> {}; template struct function_traits : detect_call_operator {}; } // namespace detail diff --git a/include/stdx/functional.hpp b/include/stdx/functional.hpp index 291c947..c5355b9 100644 --- a/include/stdx/functional.hpp +++ b/include/stdx/functional.hpp @@ -56,7 +56,7 @@ struct bind_front_t, BoundArgs...> { template constexpr auto bind_front(F &&f, Args &&...args) { - return detail::bind_front_t, + return detail::bind_front_t, std::make_index_sequence, std::decay_t...>{ std::forward(f), {std::forward(args)...}}; @@ -112,7 +112,7 @@ struct bind_back_t, BoundArgs...> { template constexpr auto bind_back(F &&f, Args &&...args) { - return detail::bind_back_t, + return detail::bind_back_t, std::make_index_sequence, std::decay_t...>{ std::forward(f), {std::forward(args)...}}; diff --git a/include/stdx/iterator.hpp b/include/stdx/iterator.hpp index da7a324..90f7acc 100644 --- a/include/stdx/iterator.hpp +++ b/include/stdx/iterator.hpp @@ -13,7 +13,7 @@ namespace stdx { inline namespace v1 { namespace detail { template struct ct_capacity_fail { - static_assert(always_false_v>, + static_assert(always_false_v>, "Type does not support compile-time capacity"); }; } // namespace detail @@ -31,7 +31,7 @@ template constexpr auto ct_capacity_v = ct_capacity_v; template consteval auto ct_capacity([[maybe_unused]] T &&) -> std::size_t { - return ct_capacity_v>; + return ct_capacity_v>; } template >> diff --git a/include/stdx/latched.hpp b/include/stdx/latched.hpp index 20a78c7..12a6bad 100644 --- a/include/stdx/latched.hpp +++ b/include/stdx/latched.hpp @@ -11,7 +11,7 @@ namespace stdx { inline namespace v1 { template struct latched { - using value_type = stdx::remove_cvref_t>; + using value_type = std::remove_cvref_t>; constexpr explicit latched(F const &f) : lazy{f} {} constexpr explicit latched(F &&f) : lazy{std::move(f)} {} @@ -56,6 +56,6 @@ template struct latched { }; template -using latched_value_t = typename stdx::remove_cvref_t::value_type; +using latched_value_t = typename std::remove_cvref_t::value_type; } // namespace v1 } // namespace stdx diff --git a/include/stdx/optional.hpp b/include/stdx/optional.hpp index 00a5b49..a8bb172 100644 --- a/include/stdx/optional.hpp +++ b/include/stdx/optional.hpp @@ -79,10 +79,10 @@ struct unwrap_invoker, template constexpr auto unwrap_invoke(F &&f, Arg &&arg) { - return unwrap_invoker, - stdx::remove_cvref_t>::invoke(std::forward(f), - std::forward( - arg)); + return unwrap_invoker, + std::remove_cvref_t>::invoke(std::forward(f), + std::forward( + arg)); } template @@ -109,10 +109,9 @@ template > class optional { : val{std::forward(args)...} {} template - requires( - std::is_constructible_v and - not std::is_same_v, std::in_place_t> and - not std::is_same_v, optional>) + requires(std::is_constructible_v and + not std::is_same_v, std::in_place_t> and + not std::is_same_v, optional>) constexpr explicit optional(U &&u) : val{std::forward(u)} {} constexpr auto operator=(std::nullopt_t) -> optional & { @@ -123,7 +122,7 @@ template > class optional { template requires(std::is_constructible_v and std::is_assignable_v and - not std::is_same_v, optional> and + not std::is_same_v, optional> and (std::is_scalar_v or not std::is_same_v, T>)) constexpr auto operator=(U &&u) -> optional & { @@ -310,27 +309,27 @@ template optional(T) -> optional; namespace detail { template concept optional_like = - stdx::is_specialization_of_v, optional> or - stdx::is_specialization_of_v, std::optional>; + stdx::is_specialization_of_v, optional> or + stdx::is_specialization_of_v, std::optional>; template , - optional>)>> + typename = std::enable_if_t<( + ... and + stdx::is_specialization_of_v, optional>)>> auto convert_optional(Ts const &...) -> optional; template , + (... and stdx::is_specialization_of_v, std::optional>)>> auto convert_optional(Ts const &...) -> std::optional; } // namespace detail template constexpr auto transform(F &&f, Ts &&...ts) { - using func_t = stdx::remove_cvref_t; + using func_t = std::remove_cvref_t; using R = std::invoke_result_t< func_t, - forward_like_t::value_type>...>; + forward_like_t::value_type>...>; using O = decltype(detail::convert_optional(ts...)); if ((... and ts.has_value())) { return O{with_result_of{[&] { diff --git a/include/stdx/span.hpp b/include/stdx/span.hpp index 316979f..4671d08 100644 --- a/include/stdx/span.hpp +++ b/include/stdx/span.hpp @@ -66,7 +66,7 @@ class span : public detail::span_base { public: using element_type = T; - using value_type = stdx::remove_cvref_t; + using value_type = std::remove_cvref_t; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using pointer = T *; diff --git a/include/stdx/tuple.hpp b/include/stdx/tuple.hpp index 213c3d8..73f0617 100644 --- a/include/stdx/tuple.hpp +++ b/include/stdx/tuple.hpp @@ -432,7 +432,7 @@ template concept tuple_comparable = requires { typename T::common_tuple_comparable; }; template -concept tuplelike = requires { typename remove_cvref_t::is_tuple; }; +concept tuplelike = requires { typename std::remove_cvref_t::is_tuple; }; template struct tuple_element; diff --git a/include/stdx/tuple_algorithms.hpp b/include/stdx/tuple_algorithms.hpp index 30851b2..fbc65a5 100644 --- a/include/stdx/tuple_algorithms.hpp +++ b/include/stdx/tuple_algorithms.hpp @@ -271,7 +271,7 @@ constexpr auto contains_type = template