1 /*!
2 @file
3 Defines `boost::hana::detail::variadic::foldl1`.
4 
5 @copyright Louis Dionne 2013-2017
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_FOLDL1_HPP
11 #define BOOST_HANA_DETAIL_VARIADIC_FOLDL1_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     //! @cond
19     template <unsigned int n, typename = when<true>>
20     struct foldl1_impl;
21 
22     template <>
23     struct foldl1_impl<1> {
24         template <typename F, typename X1>
applydetail::variadic::foldl1_impl25         static constexpr X1 apply(F&&, X1&& x1)
26         { return static_cast<X1&&>(x1); }
27     };
28 
29     template <>
30     struct foldl1_impl<2> {
31         template <typename F, typename X1, typename X2>
applydetail::variadic::foldl1_impl32         static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2) {
33             return static_cast<F&&>(f)(static_cast<X1&&>(x1),
34                                        static_cast<X2&&>(x2));
35         }
36     };
37 
38     template <>
39     struct foldl1_impl<3> {
40         template <typename F, typename X1, typename X2, typename X3>
applydetail::variadic::foldl1_impl41         static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3) {
42             return f(f(static_cast<X1&&>(x1),
43                        static_cast<X2&&>(x2)),
44                        static_cast<X3&&>(x3));
45         }
46     };
47 
48     template <>
49     struct foldl1_impl<4> {
50         template <typename F, typename X1, typename X2, typename X3, typename X4>
applydetail::variadic::foldl1_impl51         static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4) {
52             return f(f(f(static_cast<X1&&>(x1),
53                          static_cast<X2&&>(x2)),
54                          static_cast<X3&&>(x3)),
55                          static_cast<X4&&>(x4));
56         }
57     };
58 
59     template <>
60     struct foldl1_impl<5> {
61         template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5>
applydetail::variadic::foldl1_impl62         static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5) {
63             return f(f(f(f(static_cast<X1&&>(x1),
64                            static_cast<X2&&>(x2)),
65                            static_cast<X3&&>(x3)),
66                            static_cast<X4&&>(x4)),
67                            static_cast<X5&&>(x5));
68         }
69     };
70 
71     template <>
72     struct foldl1_impl<6> {
73         template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6>
applydetail::variadic::foldl1_impl74         static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6) {
75             return f(f(f(f(f(static_cast<X1&&>(x1),
76                              static_cast<X2&&>(x2)),
77                              static_cast<X3&&>(x3)),
78                              static_cast<X4&&>(x4)),
79                              static_cast<X5&&>(x5)),
80                              static_cast<X6&&>(x6));
81         }
82     };
83 
84     template <unsigned int n>
85     struct foldl1_impl<n, when<(n >= 7) && (n < 14)>> {
86         template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename ...Xn>
87         static constexpr decltype(auto)
applydetail::variadic::foldl1_impl88         apply(F&& f
89               , X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
90               , Xn&& ...xn)
91         {
92             return foldl1_impl<sizeof...(xn) + 1>::apply(
93                 f,
94                 f(f(f(f(f(f(static_cast<X1&&>(x1),
95                             static_cast<X2&&>(x2)),
96                             static_cast<X3&&>(x3)),
97                             static_cast<X4&&>(x4)),
98                             static_cast<X5&&>(x5)),
99                             static_cast<X6&&>(x6)),
100                             static_cast<X7&&>(x7)),
101                 static_cast<Xn&&>(xn)...
102             );
103         }
104     };
105 
106     template <unsigned int n>
107     struct foldl1_impl<n, when<(n >= 14) && (n < 28)>> {
108         template <
109               typename F
110             , typename X1, typename X2, typename X3,  typename X4,  typename X5,  typename X6,  typename X7
111             , typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14
112             , typename ...Xn
113         >
114         static constexpr decltype(auto)
applydetail::variadic::foldl1_impl115         apply(F&& f
116               , X1&& x1, X2&& x2, X3&& x3,   X4&& x4,   X5&& x5,   X6&& x6,   X7&& x7
117               , X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
118               , Xn&& ...xn)
119         {
120             return foldl1_impl<sizeof...(xn) + 1>::apply(
121                 f,
122                 f(f(f(f(f(f(f(f(f(f(f(f(f(
123                     static_cast<X1&&>(x1),  static_cast<X2&&>(x2)), static_cast<X3&&>(x3)),   static_cast<X4&&>(x4)),   static_cast<X5&&>(x5)),   static_cast<X6&&>(x6)),   static_cast<X7&&>(x7)),
124                     static_cast<X8&&>(x8)), static_cast<X9&&>(x9)), static_cast<X10&&>(x10)), static_cast<X11&&>(x11)), static_cast<X12&&>(x12)), static_cast<X13&&>(x13)), static_cast<X14&&>(x14))
125                 , static_cast<Xn&&>(xn)...);
126 
127         }
128     };
129 
130     template <unsigned int n>
131     struct foldl1_impl<n, when<(n >= 28) && (n < 56)>> {
132         template <
133               typename F
134             , typename X1,  typename X2,  typename X3,  typename X4,  typename X5,  typename X6,  typename X7
135             , typename X8,  typename X9,  typename X10, typename X11, typename X12, typename X13, typename X14
136             , typename X15, typename X16, typename X17, typename X18, typename X19, typename X20, typename X21
137             , typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, typename X28
138             , typename ...Xn
139         >
140         static constexpr decltype(auto)
applydetail::variadic::foldl1_impl141         apply(F&& f
142               , X1&& x1,   X2&& x2,   X3&& x3,   X4&& x4,   X5&& x5,   X6&& x6,   X7&& x7
143               , X8&& x8,   X9&& x9,   X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
144               , X15&& x15, X16&& x16, X17&& x17, X18&& x18, X19&& x19, X20&& x20, X21&& x21
145               , X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, X28&& x28
146               , Xn&& ...xn)
147         {
148             return foldl1_impl<sizeof...(xn) + 1>::apply(
149                 f,
150                 f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
151                     static_cast<X1&&>(x1),    static_cast<X2&&>(x2)),   static_cast<X3&&>(x3)),   static_cast<X4&&>(x4)),   static_cast<X5&&>(x5)),   static_cast<X6&&>(x6)),   static_cast<X7&&>(x7)),
152                     static_cast<X8&&>(x8)),   static_cast<X9&&>(x9)),   static_cast<X10&&>(x10)), static_cast<X11&&>(x11)), static_cast<X12&&>(x12)), static_cast<X13&&>(x13)), static_cast<X14&&>(x14)),
153                     static_cast<X15&&>(x15)), static_cast<X16&&>(x16)), static_cast<X17&&>(x17)), static_cast<X18&&>(x18)), static_cast<X19&&>(x19)), static_cast<X20&&>(x20)), static_cast<X21&&>(x21)),
154                     static_cast<X22&&>(x22)), static_cast<X23&&>(x23)), static_cast<X24&&>(x24)), static_cast<X25&&>(x25)), static_cast<X26&&>(x26)), static_cast<X27&&>(x27)), static_cast<X28&&>(x28))
155                 , static_cast<Xn&&>(xn)...);
156         }
157     };
158 
159     template <unsigned int n>
160     struct foldl1_impl<n, when<(n >= 56)>> {
161         template <
162               typename F
163             , typename X1,  typename X2,  typename X3,  typename X4,  typename X5,  typename X6,  typename X7
164             , typename X8,  typename X9,  typename X10, typename X11, typename X12, typename X13, typename X14
165             , typename X15, typename X16, typename X17, typename X18, typename X19, typename X20, typename X21
166             , typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, typename X28
167             , typename X29, typename X30, typename X31, typename X32, typename X33, typename X34, typename X35
168             , typename X36, typename X37, typename X38, typename X39, typename X40, typename X41, typename X42
169             , typename X43, typename X44, typename X45, typename X46, typename X47, typename X48, typename X49
170             , typename X50, typename X51, typename X52, typename X53, typename X54, typename X55, typename X56
171             , typename ...Xn
172         >
173         static constexpr decltype(auto)
applydetail::variadic::foldl1_impl174         apply(F&& f
175               , X1&& x1,   X2&& x2,   X3&& x3,   X4&& x4,   X5&& x5,   X6&& x6,   X7&& x7
176               , X8&& x8,   X9&& x9,   X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
177               , X15&& x15, X16&& x16, X17&& x17, X18&& x18, X19&& x19, X20&& x20, X21&& x21
178               , X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, X28&& x28
179               , X29&& x29, X30&& x30, X31&& x31, X32&& x32, X33&& x33, X34&& x34, X35&& x35
180               , X36&& x36, X37&& x37, X38&& x38, X39&& x39, X40&& x40, X41&& x41, X42&& x42
181               , X43&& x43, X44&& x44, X45&& x45, X46&& x46, X47&& x47, X48&& x48, X49&& x49
182               , X50&& x50, X51&& x51, X52&& x52, X53&& x53, X54&& x54, X55&& x55, X56&& x56
183               , Xn&& ...xn)
184         {
185             return foldl1_impl<sizeof...(xn) + 1>::apply(
186                 f,
187                 f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
188                     static_cast<X1&&>(x1),    static_cast<X2&&>(x2)),   static_cast<X3&&>(x3)),   static_cast<X4&&>(x4)),   static_cast<X5&&>(x5)),   static_cast<X6&&>(x6)),   static_cast<X7&&>(x7)),
189                     static_cast<X8&&>(x8)),   static_cast<X9&&>(x9)),   static_cast<X10&&>(x10)), static_cast<X11&&>(x11)), static_cast<X12&&>(x12)), static_cast<X13&&>(x13)), static_cast<X14&&>(x14)),
190                     static_cast<X15&&>(x15)), static_cast<X16&&>(x16)), static_cast<X17&&>(x17)), static_cast<X18&&>(x18)), static_cast<X19&&>(x19)), static_cast<X20&&>(x20)), static_cast<X21&&>(x21)),
191                     static_cast<X22&&>(x22)), static_cast<X23&&>(x23)), static_cast<X24&&>(x24)), static_cast<X25&&>(x25)), static_cast<X26&&>(x26)), static_cast<X27&&>(x27)), static_cast<X28&&>(x28)),
192                     static_cast<X29&&>(x29)), static_cast<X30&&>(x30)), static_cast<X31&&>(x31)), static_cast<X32&&>(x32)), static_cast<X33&&>(x33)), static_cast<X34&&>(x34)), static_cast<X35&&>(x35)),
193                     static_cast<X36&&>(x36)), static_cast<X37&&>(x37)), static_cast<X38&&>(x38)), static_cast<X39&&>(x39)), static_cast<X40&&>(x40)), static_cast<X41&&>(x41)), static_cast<X42&&>(x42)),
194                     static_cast<X43&&>(x43)), static_cast<X44&&>(x44)), static_cast<X45&&>(x45)), static_cast<X46&&>(x46)), static_cast<X47&&>(x47)), static_cast<X48&&>(x48)), static_cast<X49&&>(x49)),
195                     static_cast<X50&&>(x50)), static_cast<X51&&>(x51)), static_cast<X52&&>(x52)), static_cast<X53&&>(x53)), static_cast<X54&&>(x54)), static_cast<X55&&>(x55)), static_cast<X56&&>(x56))
196                 , static_cast<Xn&&>(xn)...);
197         }
198     };
199     //! @endcond
200 
201     struct foldl1_t {
202         template <typename F, typename X1, typename ...Xn>
operator ()detail::variadic::foldl1_t203         constexpr decltype(auto) operator()(F&& f, X1&& x1, Xn&& ...xn) const {
204             return foldl1_impl<sizeof...(xn) + 1>::apply(
205                 static_cast<F&&>(f), static_cast<X1&&>(x1), static_cast<Xn&&>(xn)...
206             );
207         }
208     };
209 
210     constexpr foldl1_t foldl1{};
211     constexpr auto foldl = foldl1;
212 }} BOOST_HANA_NAMESPACE_END
213 
214 #endif // !BOOST_HANA_DETAIL_VARIADIC_FOLDL1_HPP
215