-
Notifications
You must be signed in to change notification settings - Fork 0
/
constexpr_range.hpp
164 lines (139 loc) · 4.75 KB
/
constexpr_range.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include<utility> // std::index_constexpr_range
#include<cstddef> // std::size_t
#include<tuple> // std::tuple
#include<iostream> //std::cout
#include "get_nth_element.hpp"
namespace mlib
{
template<auto... vals>
struct constexpr_range;
template<auto lambda, auto... values>
constexpr auto make_index_holds_true()
{
int index = 0;
int values_[sizeof...(values)] = {};
auto function = [&](auto value)
{
values_[index] = value;
};
(function(values), ...);
return std::move(values_);
}
template<auto... values, typename T, auto Idx>
constexpr auto get_idxs_out(const T(&arr)[Idx])
{
return[&]<std::size_t... indexes>(std::index_sequence<indexes...>)
{
return (get_nth_element<arr[indexes]>(constexpr_range<values>{}) + ...);
}(std::make_index_sequence<Idx>{});
}
template<auto... vals>
struct value_constexpr_range
{
};
template<auto val, auto... vals>
constexpr auto pop_front_(constexpr_range<val, vals...>)
{
return constexpr_range<vals...>{};
}
struct Size {};
template<auto... vals>
struct constexpr_range
{
template<auto lambda>
constexpr auto map()
{
return[&]<std::size_t... indexes>(std::index_sequence<indexes...>)
{
return constexpr_range<lambda(vals)...>{};
}(std::make_index_sequence<sizeof...(vals) > {});
}
template<auto lambda>
constexpr auto map_with_location()
{
return[&]<std::size_t... indexes>(std::index_sequence<indexes...>)
{
return constexpr_range<lambda(vals, indexes)...>{};
}(std::make_index_sequence<sizeof...(vals) > {});
}
constexpr auto sum()
{
constexpr auto value = [&]()
{
return (vals + ...);
}();
return constexpr_range<value>{};
}
constexpr auto tuple()
{
return std::tuple{ vals... };
}
template<auto value>
constexpr auto add()
{
return constexpr_range<vals..., value>{};
}
constexpr auto add(Size)
{
return constexpr_range<vals..., sizeof...(vals)>{};
}
constexpr auto pop_front()
{
return pop_front_(constexpr_range<vals...>{});
}
template<auto... values_>
constexpr auto operator+(constexpr_range<values_...>) const
{
return constexpr_range<vals..., values_...>{};
}
template<auto... values_>
constexpr auto join_with(constexpr_range<values_...>)
{
return constexpr_range<vals..., values_...>{};
}
template<auto... values_>
constexpr auto join_with()
{
return constexpr_range<vals..., values_...>{};
}
template<auto index>
constexpr auto remove_at()
{
constexpr auto first_part = [&]<std::size_t... indexes>(std::index_sequence<indexes...>)
{
return constexpr_range<get_nth_element<indexes>(vals...)...>{};
}(std::make_index_sequence<sizeof...(vals)>{});
constexpr auto second_part = [&]<std::size_t... indexes>(std::index_sequence<indexes...>)
{
return constexpr_range<get_nth_element<indexes + index + 1>(vals...)...>{};
}(std::make_index_sequence<sizeof...(vals) -index - 1 > {});
return first_part + second_part;
}
template<auto index, auto to_add>
constexpr auto add_at()
{
constexpr auto first_part = [&]<std::size_t... indexes>(std::index_sequence<indexes...>)
{
return constexpr_range<get_nth_element<indexes>(vals...)...>{};
}(std::make_index_sequence<sizeof...(vals)>{});
constexpr auto second_part = [&]<std::size_t... indexes>(std::index_sequence<indexes...>)
{
return constexpr_range<get_nth_element<indexes + index>(vals...)...>{};
}(std::make_index_sequence<sizeof...(vals) - index > {});
return (first_part + mlib::constexpr_range<to_add>{}) + second_part;
}
template<auto index>
constexpr auto at()
{
return get_nth_element<index>(vals...);
}
template<auto T>
constexpr auto instances() const noexcept -> int
{
return[=]<std::size_t... indexes>(std::index_sequence<indexes...>)
{
return ((T == mlib::get_nth_element<indexes>(vals)) + ...);
}(std::make_index_sequence<sizeof...(vals)>{});
}
};
} // namespace mlib