From 79ee48e0f68a3c2db2e75615cf26d4c7a239744a Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 15 Nov 2022 09:19:04 +0100 Subject: entity: add visit_tuple --- src/entity.hpp | 27 ++++++++++++++++++++++++++- test/entity.cpp | 9 +++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/entity.hpp b/src/entity.hpp index 32ab759f..31a13632 100644 --- a/src/entity.hpp +++ b/src/entity.hpp @@ -131,11 +131,12 @@ struct Entity final { }; namespace detail { + template requires std::invocable(std::declval()))> constexpr CORRADE_ALWAYS_INLINE void visit_tuple(F&& fun, Tuple&& tuple) { - using Size = std::tuple_size>; + using Size = std::tuple_size>; static_assert(N < Size()); fun(std::get(tuple)); @@ -143,6 +144,20 @@ constexpr CORRADE_ALWAYS_INLINE void visit_tuple(F&& fun, Tuple&& tuple) visit_tuple(std::forward(fun), std::forward(tuple)); } +template +requires std::is_invocable_r_v(std::declval()))> +constexpr CORRADE_ALWAYS_INLINE bool find_in_tuple(F&& fun, Tuple&& tuple) +{ + using Size = std::tuple_size>; + static_assert(N < Size()); + + if (fun(std::get(tuple))) + return true; + if constexpr(N+1 < Size()) + return find_in_tuple(std::forward(fun), std::forward(tuple)); + return false; +} + } // namespace detail template @@ -153,6 +168,16 @@ constexpr void visit_tuple(F&& fun, Tuple&& tuple) detail::visit_tuple(std::forward(fun), std::forward(tuple)); } +template +constexpr bool find_in_tuple(F&& fun, Tuple&& tuple) +{ + using Size = std::tuple_size>; + if constexpr(Size() > 0) + return detail::find_in_tuple(std::forward(fun), std::forward(tuple)); + else + return false; +} + enum class erased_field_type : std::uint32_t { none, string, diff --git a/test/entity.cpp b/test/entity.cpp index 312fb18a..8266ec47 100644 --- a/test/entity.cpp +++ b/test/entity.cpp @@ -45,9 +45,9 @@ static constexpr bool test_accessors() static constexpr bool test_visitor() { { + constexpr auto tuple = std::make_tuple((unsigned char)1, (unsigned short)2, (int)3, (long)4); long ret = 0; - visit_tuple([&](auto x) { ret += (long)x; }, - std::make_tuple((unsigned char)1, (unsigned short)2, (int)3, (long)4)); + visit_tuple([&](auto x) { ret += (long)x; }, tuple); fm_assert(ret == 1 + 2 + 3 + 4); } { @@ -55,6 +55,11 @@ static constexpr bool test_visitor() visit_tuple([&] { ret++; }, std::tuple<>{}); fm_assert(ret == 0); } + { + constexpr auto tuple = std::make_tuple((char)1, (short)2, (long)3); + static_assert(find_in_tuple([](auto x) { return x == 3; }, tuple)); + static_assert(!find_in_tuple([](auto x) { return x == 5; }, tuple)); + } return true; } -- cgit v1.2.3