diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-15 09:19:04 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-15 09:53:30 +0100 |
commit | 604b4ae5720836cb4ee9a66085d3290067c63c84 (patch) | |
tree | 0865d470b757eb456929e045c1b45e9c8bad9c09 /src/entity.hpp | |
parent | 181bf16539d425d4f07501905cc9326b434ce75e (diff) |
entity: add visit_tuple
Diffstat (limited to 'src/entity.hpp')
-rw-r--r-- | src/entity.hpp | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/entity.hpp b/src/entity.hpp index 1c055ce7..ba165662 100644 --- a/src/entity.hpp +++ b/src/entity.hpp @@ -1,9 +1,10 @@ #pragma once #include "compat/integer-types.hpp" -#include <Corrade/Containers/StringView.h> #include <concepts> #include <compare> #include <type_traits> +#include <utility> +#include <Corrade/Containers/StringView.h> namespace floormat {} @@ -128,6 +129,29 @@ struct Entity final { }; }; +namespace detail { +template<typename F, typename Tuple, std::size_t N> +requires std::invocable<F, decltype(std::get<N>(std::declval<Tuple>()))> +constexpr CORRADE_ALWAYS_INLINE void visit_tuple(F&& fun, Tuple&& tuple) +{ + using Size = std::tuple_size<std::decay_t<Tuple>>; + static_assert(N < Size()); + + fun(std::get<N>(tuple)); + if constexpr(N+1 < Size()) + visit_tuple<F, Tuple, N+1>(std::forward<F>(fun), std::forward<Tuple>(tuple)); +} + +} // namespace detail + +template<typename F, typename Tuple> +constexpr void visit_tuple(F&& fun, Tuple&& tuple) +{ + using Size = std::tuple_size<std::decay_t<Tuple>>; + if constexpr(Size() > 0) + detail::visit_tuple<F, Tuple, 0>(std::forward<F>(fun), std::forward<Tuple>(tuple)); +} + enum class erased_field_type : std::uint32_t { none, string, |