-
Notifications
You must be signed in to change notification settings - Fork 7
/
for_temp.hpp
101 lines (89 loc) · 3.74 KB
/
for_temp.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright (c) 2015-2020 Vittorio Romeo
// License: Academic Free License ("AFL") v. 3.0
// AFL License page: http://opensource.org/licenses/AFL-3.0
// http://vittorioromeo.info | vittorio.romeo@outlook.com
#pragma once
#include <tuple>
#include <vrm/core/config.hpp>
#include <vrm/core/assert.hpp>
#include <vrm/core/utility_macros.hpp>
#include <vrm/core/for_args.hpp>
#include <vrm/core/variadic_min_max.hpp>
#include <vrm/core/type_traits/size_t_constant.hpp>
#define VRM_CORE_IMPL_TPLFOR_DATAEXEC_BODY() \
for_args( \
[&](auto i) \
{ \
f(for_tuple_data_type<i>{}, std::get<i>(FWD(ts))...); \
}, \
size_t_constant<TIs>{}...)
#define VRM_CORE_IMPL_TPLFOR_CALL() \
::vrm::core::impl::for_tuple_data_helper< \
::vrm::core::variadic_min(std::tuple_size<std::decay_t<Ts>>()...), \
Ts...>::exec(FWD(f), FWD(ts)...)
namespace vrm::core
{
namespace impl
{
template <typename... Ts>
constexpr std::size_t min_tuple_size{
variadic_min(std::tuple_size<std::decay_t<Ts>>()...)};
template <typename... Ts>
VRM_CORE_ALWAYS_INLINE constexpr auto make_min_tuple_size_seq() noexcept
{
return std::make_index_sequence<min_tuple_size<Ts...>>();
}
template <std::size_t TI>
struct for_tuple_data_type
{
static constexpr std::size_t index{TI};
};
template <std::size_t... TIs, typename TF, typename... Ts>
VRM_CORE_ALWAYS_INLINE constexpr decltype(auto) for_tuple_data_exec(
std::index_sequence<TIs...>, TF&& f, Ts&&... ts) // noexcept(
// noexcept(VRM_CORE_IMPL_TPLFORHELPER_BODY()))
{
// VRM_CORE_IMPL_TPLFORHELPER_BODY();
return for_args(
[&](auto i)
{
f(for_tuple_data_type<i>{}, std::get<i>(FWD(ts))...);
},
size_t_constant<TIs>{}...);
}
}
/// @brief Iterates over a tuple's elements passing current iteration
/// data
/// and them to `f` one at a time.
/// @details Can iterate over multiple tuples at once, passing the Nth
/// element of every tuple to `f` simultaneously.
/// If the tuples have different sizes, the minimum size will be used.
template <typename TF, typename... Ts>
VRM_CORE_ALWAYS_INLINE constexpr decltype(auto) for_tuple_data(TF && f,
Ts && ... ts) // noexcept(noexcept(VRM_CORE_IMPL_TPLFOR_CALL()))
{
// VRM_CORE_IMPL_TPLFOR_CALL();
return impl::for_tuple_data_exec(
impl::make_min_tuple_size_seq<Ts...>(), FWD(f), FWD(ts)...);
}
/// @brief Iterates over a tuple's elements passing them to `f` one at a
/// time.
/// @details Can iterate over multiple tuples at once, passing the Nth
/// element of every tuple to `f` simultaneously.
/// If the tuples have different sizes, the minimum size will be used.
template <typename TF, typename... Ts>
VRM_CORE_ALWAYS_INLINE // .
constexpr decltype(auto) for_tuple(TF && f, Ts && ... xs) // .
// noexcept(noexcept(for_args_data<TArity>(
// impl::ignore_first_arg<decltype(f)>{f}, FWD(xs)...)))
{
return for_tuple_data(
[&f](auto, auto&&... rest)
{
f(FWD(rest)...);
},
FWD(xs)...);
}
}
#undef VRM_CORE_IMPL_TPLFOR_CALL
#undef VRM_CORE_IMPL_DEFINE_TPLFOR_FN