diff --git a/docs/type_traits.adoc b/docs/type_traits.adoc index 5c93fa2..8f6d7cb 100644 --- a/docs/type_traits.adoc +++ b/docs/type_traits.adoc @@ -155,6 +155,26 @@ NOTE: Detecting structurality of a type is not yet possible in the general case, so there are certain structural types for which this trait will be `false`. In practice those types should be rare, and there should be no false positives. +=== `nth_t` + +`nth_t` is a type alias that extracts the nth element from a pack of types (starting at 0 of course): + +[source,cpp] +---- +// nth_t +static_assert(std::is_same_v, float>); +---- + +=== `nth_v` + +`nth_v` is a `constexpr` variable template that extracts the nth element from a pack of values (starting at 0 of course): + +[source,cpp] +---- +// nth_v +static_assert(stdx::nth_v<1, 6, 28, 496> == 28); +---- + === `template_for_each` A xref:type_traits.adoc#_type_list_and_value_list[`type_list` or a `value_list`] diff --git a/include/stdx/env.hpp b/include/stdx/env.hpp index aae4e3d..a4c6a40 100644 --- a/include/stdx/env.hpp +++ b/include/stdx/env.hpp @@ -34,7 +34,7 @@ template struct env { CONSTEVAL static auto query(Q) noexcept { using I = boost::mp11::mp_find_if_q, _env::has_query>; - using E = boost::mp11::mp_at, I>; + using E = nth_t; return Q{}(E{}); } }; @@ -61,18 +61,11 @@ template struct autowrap> { template autowrap(T) -> autowrap; template autowrap(str_lit_t) -> autowrap>; -template struct wrap { - constexpr static auto value = V; -}; - template struct for_each_pair; template struct for_each_pair> { template - using type = env< - _env::ct_prop...>, - 2 * Is>::value.value, - boost::mp11::mp_at_c...>, - (2 * Is) + 1>::value.value>...>; + using type = env.value, + nth_v<(2 * Is) + 1, Args...>.value>...>; }; template > diff --git a/include/stdx/function_traits.hpp b/include/stdx/function_traits.hpp index 2d43967..ae2cb9e 100644 --- a/include/stdx/function_traits.hpp +++ b/include/stdx/function_traits.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -21,11 +23,8 @@ struct function_traits> { using decayed_args = List...>; using arity = std::integral_constant; - template - using nth_arg = boost::mp11::mp_at_c, N>; - template - using decayed_nth_arg = - boost::mp11::mp_at_c, N>; + template using nth_arg = nth_t; + template using decayed_nth_arg = std::decay_t>; }; } // namespace detail diff --git a/include/stdx/type_traits.hpp b/include/stdx/type_traits.hpp index eb4136c..03189f8 100644 --- a/include/stdx/type_traits.hpp +++ b/include/stdx/type_traits.hpp @@ -1,5 +1,9 @@ #pragma once +#include + +#include + #include #include @@ -227,5 +231,43 @@ using shrink_t = decltype([]() -> T (*)() { return nullptr; }); template using expand_t = decltype(T{}()()); #endif + +STDX_PRAGMA(diagnostic push) +#ifdef __clang__ +STDX_PRAGMA(diagnostic ignored "-Wunknown-warning-option") +STDX_PRAGMA(diagnostic ignored "-Wc++26-extensions") +#endif +template +using nth_t = +#if __cpp_pack_indexing >= 202311L + Ts...[N]; +#elif __has_builtin(__type_pack_element) + __type_pack_element; +#else + boost::mp11::mp_at_c, N>; +#endif +STDX_PRAGMA(diagnostic pop) + +#if __cplusplus >= 202002L +namespace detail { +template struct value_wrapper { + constexpr static auto value = V; +}; +} // namespace detail + +STDX_PRAGMA(diagnostic push) +#ifdef __clang__ +STDX_PRAGMA(diagnostic ignored "-Wunknown-warning-option") +STDX_PRAGMA(diagnostic ignored "-Wc++26-extensions") +#endif +template +constexpr auto nth_v = +#if __cpp_pack_indexing >= 202311L + Vs...[N]; +#else + boost::mp11::mp_at_c...>, N>::value; +#endif +STDX_PRAGMA(diagnostic pop) +#endif } // namespace v1 } // namespace stdx diff --git a/test/type_traits.cpp b/test/type_traits.cpp index bccce12..2efec3d 100644 --- a/test/type_traits.cpp +++ b/test/type_traits.cpp @@ -258,3 +258,14 @@ TEST_CASE("type shrinkage", "[type_traits]") { static_assert(std::same_as, C>); } #endif + +TEST_CASE("nth type in pack", "[type_traits]") { + static_assert( + std::is_same_v, float>); +} + +#if __cplusplus >= 202002L +TEST_CASE("nth value in pack", "[type_traits]") { + static_assert(stdx::nth_v<2, 0, true, 'b', 3> == 'b'); +} +#endif