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