]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*! |
2 | @file | |
3 | Defines `boost::hana::detail::variadic::foldr1`. | |
4 | ||
5 | @copyright Louis Dionne 2013-2016 | |
6 | Distributed under the Boost Software License, Version 1.0. | |
7 | (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) | |
8 | */ | |
9 | ||
10 | #ifndef BOOST_HANA_DETAIL_VARIADIC_FOLDR1_HPP | |
11 | #define BOOST_HANA_DETAIL_VARIADIC_FOLDR1_HPP | |
12 | ||
13 | #include <boost/hana/config.hpp> | |
14 | #include <boost/hana/core/when.hpp> | |
15 | ||
16 | ||
17 | BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic { | |
18 | template <unsigned int n, typename = when<true>> | |
19 | struct foldr1_impl; | |
20 | ||
21 | template <> | |
22 | struct foldr1_impl<1> { | |
23 | template <typename F, typename X1> | |
24 | static constexpr X1 apply(F&&, X1&& x1) | |
25 | { return static_cast<X1&&>(x1); } | |
26 | }; | |
27 | ||
28 | template <> | |
29 | struct foldr1_impl<2> { | |
30 | template <typename F, typename X1, typename X2> | |
31 | static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2) { | |
32 | return static_cast<F&&>(f)(static_cast<X1&&>(x1), | |
33 | static_cast<X2&&>(x2)); | |
34 | } | |
35 | }; | |
36 | ||
37 | template <> | |
38 | struct foldr1_impl<3> { | |
39 | template <typename F, typename X1, typename X2, typename X3> | |
40 | static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3) { | |
41 | return f(static_cast<X1&&>(x1), | |
42 | f(static_cast<X2&&>(x2), | |
43 | static_cast<X3&&>(x3))); | |
44 | } | |
45 | }; | |
46 | ||
47 | template <> | |
48 | struct foldr1_impl<4> { | |
49 | template <typename F, typename X1, typename X2, typename X3, typename X4> | |
50 | static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4) { | |
51 | return f(static_cast<X1&&>(x1), | |
52 | f(static_cast<X2&&>(x2), | |
53 | f(static_cast<X3&&>(x3), | |
54 | static_cast<X4&&>(x4)))); | |
55 | } | |
56 | }; | |
57 | ||
58 | template <> | |
59 | struct foldr1_impl<5> { | |
60 | template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5> | |
61 | static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5) { | |
62 | return f(static_cast<X1&&>(x1), | |
63 | f(static_cast<X2&&>(x2), | |
64 | f(static_cast<X3&&>(x3), | |
65 | f(static_cast<X4&&>(x4), | |
66 | static_cast<X5&&>(x5))))); | |
67 | } | |
68 | }; | |
69 | ||
70 | template <> | |
71 | struct foldr1_impl<6> { | |
72 | template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6> | |
73 | static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6) { | |
74 | return f(static_cast<X1&&>(x1), | |
75 | f(static_cast<X2&&>(x2), | |
76 | f(static_cast<X3&&>(x3), | |
77 | f(static_cast<X4&&>(x4), | |
78 | f(static_cast<X5&&>(x5), | |
79 | static_cast<X6&&>(x6)))))); | |
80 | } | |
81 | }; | |
82 | ||
83 | template <unsigned int n> | |
84 | struct foldr1_impl<n, when<(n >= 7) && (n < 14)>> { | |
85 | template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename ...Xn> | |
86 | static constexpr decltype(auto) | |
87 | apply(F&& f | |
88 | , X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7 | |
89 | , Xn&& ...xn) | |
90 | { | |
91 | return f(static_cast<X1&&>(x1), | |
92 | f(static_cast<X2&&>(x2), | |
93 | f(static_cast<X3&&>(x3), | |
94 | f(static_cast<X4&&>(x4), | |
95 | f(static_cast<X5&&>(x5), | |
96 | f(static_cast<X6&&>(x6), | |
97 | foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X7&&>(x7), static_cast<Xn&&>(xn)...))))))); | |
98 | } | |
99 | }; | |
100 | ||
101 | template <unsigned int n> | |
102 | struct foldr1_impl<n, when<(n >= 14) && (n < 28)>> { | |
103 | template < | |
104 | typename F | |
105 | , typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7 | |
106 | , typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14 | |
107 | , typename ...Xn | |
108 | > | |
109 | static constexpr decltype(auto) | |
110 | apply(F&& f | |
111 | , X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7 | |
112 | , X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14 | |
113 | , Xn&& ...xn) | |
114 | { | |
115 | return f(static_cast<X1&&>(x1), f(static_cast<X2&&>(x2), f(static_cast<X3&&>(x3), f(static_cast<X4&&>(x4), f(static_cast<X5&&>(x5), f(static_cast<X6&&>(x6), f(static_cast<X7&&>(x7), | |
116 | f(static_cast<X8&&>(x8), f(static_cast<X9&&>(x9), f(static_cast<X10&&>(x10), f(static_cast<X11&&>(x11), f(static_cast<X12&&>(x12), f(static_cast<X13&&>(x13), | |
117 | foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X14&&>(x14), static_cast<Xn&&>(xn)...)))))))))))))); | |
118 | } | |
119 | }; | |
120 | ||
121 | template <unsigned int n> | |
122 | struct foldr1_impl<n, when<(n >= 28) && (n < 56)>> { | |
123 | template < | |
124 | typename F | |
125 | , typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7 | |
126 | , typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14 | |
127 | , typename X15, typename X16, typename X17, typename X18, typename X19, typename X20, typename X21 | |
128 | , typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, typename X28 | |
129 | , typename ...Xn | |
130 | > | |
131 | static constexpr decltype(auto) | |
132 | apply(F&& f | |
133 | , X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7 | |
134 | , X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14 | |
135 | , X15&& x15, X16&& x16, X17&& x17, X18&& x18, X19&& x19, X20&& x20, X21&& x21 | |
136 | , X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, X28&& x28 | |
137 | , Xn&& ...xn) | |
138 | { | |
139 | return f(static_cast<X1&&>(x1), f(static_cast<X2&&>(x2), f(static_cast<X3&&>(x3), f(static_cast<X4&&>(x4), f(static_cast<X5&&>(x5), f(static_cast<X6&&>(x6), f(static_cast<X7&&>(x7), | |
140 | f(static_cast<X8&&>(x8), f(static_cast<X9&&>(x9), f(static_cast<X10&&>(x10), f(static_cast<X11&&>(x11), f(static_cast<X12&&>(x12), f(static_cast<X13&&>(x13), f(static_cast<X14&&>(x14), | |
141 | f(static_cast<X15&&>(x15), f(static_cast<X16&&>(x16), f(static_cast<X17&&>(x17), f(static_cast<X18&&>(x18), f(static_cast<X19&&>(x19), f(static_cast<X20&&>(x20), f(static_cast<X21&&>(x21), | |
142 | f(static_cast<X22&&>(x22), f(static_cast<X23&&>(x23), f(static_cast<X24&&>(x24), f(static_cast<X25&&>(x25), f(static_cast<X26&&>(x26), f(static_cast<X27&&>(x27), | |
143 | foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X28&&>(x28), static_cast<Xn&&>(xn)...)))))))))))))))))))))))))))); | |
144 | } | |
145 | }; | |
146 | ||
147 | template <unsigned int n> | |
148 | struct foldr1_impl<n, when<(n >= 56)>> { | |
149 | template < | |
150 | typename F | |
151 | , typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7 | |
152 | , typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14 | |
153 | , typename X15, typename X16, typename X17, typename X18, typename X19, typename X20, typename X21 | |
154 | , typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, typename X28 | |
155 | , typename X29, typename X30, typename X31, typename X32, typename X33, typename X34, typename X35 | |
156 | , typename X36, typename X37, typename X38, typename X39, typename X40, typename X41, typename X42 | |
157 | , typename X43, typename X44, typename X45, typename X46, typename X47, typename X48, typename X49 | |
158 | , typename X50, typename X51, typename X52, typename X53, typename X54, typename X55, typename X56 | |
159 | , typename ...Xn | |
160 | > | |
161 | static constexpr decltype(auto) | |
162 | apply(F&& f | |
163 | , X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7 | |
164 | , X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14 | |
165 | , X15&& x15, X16&& x16, X17&& x17, X18&& x18, X19&& x19, X20&& x20, X21&& x21 | |
166 | , X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, X28&& x28 | |
167 | , X29&& x29, X30&& x30, X31&& x31, X32&& x32, X33&& x33, X34&& x34, X35&& x35 | |
168 | , X36&& x36, X37&& x37, X38&& x38, X39&& x39, X40&& x40, X41&& x41, X42&& x42 | |
169 | , X43&& x43, X44&& x44, X45&& x45, X46&& x46, X47&& x47, X48&& x48, X49&& x49 | |
170 | , X50&& x50, X51&& x51, X52&& x52, X53&& x53, X54&& x54, X55&& x55, X56&& x56 | |
171 | , Xn&& ...xn) | |
172 | { | |
173 | return f(static_cast<X1&&>(x1), f(static_cast<X2&&>(x2), f(static_cast<X3&&>(x3), f(static_cast<X4&&>(x4), f(static_cast<X5&&>(x5), f(static_cast<X6&&>(x6), f(static_cast<X7&&>(x7), | |
174 | f(static_cast<X8&&>(x8), f(static_cast<X9&&>(x9), f(static_cast<X10&&>(x10), f(static_cast<X11&&>(x11), f(static_cast<X12&&>(x12), f(static_cast<X13&&>(x13), f(static_cast<X14&&>(x14), | |
175 | f(static_cast<X15&&>(x15), f(static_cast<X16&&>(x16), f(static_cast<X17&&>(x17), f(static_cast<X18&&>(x18), f(static_cast<X19&&>(x19), f(static_cast<X20&&>(x20), f(static_cast<X21&&>(x21), | |
176 | f(static_cast<X22&&>(x22), f(static_cast<X23&&>(x23), f(static_cast<X24&&>(x24), f(static_cast<X25&&>(x25), f(static_cast<X26&&>(x26), f(static_cast<X27&&>(x27), f(static_cast<X28&&>(x28), | |
177 | f(static_cast<X29&&>(x29), f(static_cast<X30&&>(x30), f(static_cast<X31&&>(x31), f(static_cast<X32&&>(x32), f(static_cast<X33&&>(x33), f(static_cast<X34&&>(x34), f(static_cast<X35&&>(x35), | |
178 | f(static_cast<X36&&>(x36), f(static_cast<X37&&>(x37), f(static_cast<X38&&>(x38), f(static_cast<X39&&>(x39), f(static_cast<X40&&>(x40), f(static_cast<X41&&>(x41), f(static_cast<X42&&>(x42), | |
179 | f(static_cast<X43&&>(x43), f(static_cast<X44&&>(x44), f(static_cast<X45&&>(x45), f(static_cast<X46&&>(x46), f(static_cast<X47&&>(x47), f(static_cast<X48&&>(x48), f(static_cast<X49&&>(x49), | |
180 | f(static_cast<X50&&>(x50), f(static_cast<X51&&>(x51), f(static_cast<X52&&>(x52), f(static_cast<X53&&>(x53), f(static_cast<X54&&>(x54), f(static_cast<X55&&>(x55), | |
181 | foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X56&&>(x56), static_cast<Xn&&>(xn)...)))))))))))))))))))))))))))))))))))))))))))))))))))))))); | |
182 | } | |
183 | }; | |
184 | ||
185 | struct foldr1_t { | |
186 | template <typename F, typename X1, typename ...Xn> | |
187 | constexpr decltype(auto) operator()(F&& f, X1&& x1, Xn&& ...xn) const { | |
188 | return foldr1_impl<sizeof...(xn) + 1>::apply( | |
189 | static_cast<F&&>(f), static_cast<X1&&>(x1), static_cast<Xn&&>(xn)... | |
190 | ); | |
191 | } | |
192 | }; | |
193 | ||
194 | constexpr foldr1_t foldr1{}; | |
195 | ||
196 | struct foldr_t { | |
197 | template <typename F, typename State, typename ...Xn> | |
198 | constexpr decltype(auto) operator()(F&& f, State&& state, Xn&& ...xn) const { | |
199 | return foldr1_impl<sizeof...(xn) + 1>::apply( | |
200 | static_cast<F&&>(f), static_cast<Xn&&>(xn)..., static_cast<State&&>(state) | |
201 | ); | |
202 | } | |
203 | }; | |
204 | ||
205 | constexpr foldr_t foldr{}; | |
206 | }} BOOST_HANA_NAMESPACE_END | |
207 | ||
208 | #endif // !BOOST_HANA_DETAIL_VARIADIC_FOLDR1_HPP |