Skip to content

Commit

Permalink
Merge pull request #119 from elbeno/improve-template-for-each
Browse files Browse the repository at this point in the history
🆕 Allow `template_for_each` to iterate `std::integer_sequence`
  • Loading branch information
lukevalenty authored Jun 25, 2024
2 parents 4d2dcd0 + 7ddf5bd commit 54abfb1
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 3 deletions.
11 changes: 11 additions & 0 deletions docs/type_traits.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,17 @@ stdx::template_for_each<L2>([&] <auto V> () { y += V; });
// y is now 3
----

`template_for_each` can also be used with a
https://en.cppreference.com/w/cpp/utility/integer_sequence[`std::integer_sequence`]:

[source,cpp]
----
using L3 = stdx::make_index_sequence<3>;
int y{};
stdx::template_for_each<L3>([&] <auto V> () { y += V; });
// y is now 3
----

NOTE: A primary use case of `template_for_each` is to be able to use a list of
tag types without those types having to be complete.

Expand Down
12 changes: 9 additions & 3 deletions include/stdx/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ template <typename...> struct type_list {};
template <auto...> struct value_list {};

template <typename L> struct for_each_t {
static_assert(
always_false_v<L>,
"template_for_each must be called with a type list (or value list)");
static_assert(always_false_v<L>,
"template_for_each must be called with a type list, "
"value_list, or std::integer_sequence");
};

template <template <typename...> typename L, typename... Ts>
Expand All @@ -136,6 +136,12 @@ struct for_each_t<L<Vs...>> {
(f.template operator()<Vs>(), ...);
}
};
template <template <typename, auto...> typename L, typename T, T... Vs>
struct for_each_t<L<T, Vs...>> {
template <typename F> constexpr auto operator()(F &&f) const {
(f.template operator()<Vs>(), ...);
}
};

template <typename L> constexpr static auto template_for_each = for_each_t<L>{};

Expand Down
8 changes: 8 additions & 0 deletions test/type_traits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <cstddef>
#include <type_traits>
#include <utility>

namespace {
template <typename> struct unary_t {};
Expand Down Expand Up @@ -130,6 +131,13 @@ TEST_CASE("template_for_each with empty value list", "[type_traits]") {
CHECK(value == 17);
}

TEST_CASE("template_for_each with index sequence", "[type_traits]") {
value = 0;
using L = std::make_index_sequence<3>;
stdx::template_for_each<L>(add_value{});
CHECK(value == 3);
}

TEST_CASE("is_same_unqualified", "[type_traits]") {
static_assert(stdx::is_same_unqualified_v<int, int>);
static_assert(not stdx::is_same_unqualified_v<int, void>);
Expand Down

0 comments on commit 54abfb1

Please sign in to comment.