]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/experimental/lambda_tuple.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / experimental / lambda_tuple.cpp
1 // Copyright Louis Dionne 2013-2016
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4
5 #include <boost/hana/at.hpp>
6 #include <boost/hana/bool.hpp>
7 #include <boost/hana/config.hpp>
8 #include <boost/hana/detail/variadic/at.hpp>
9 #include <boost/hana/detail/variadic/drop_into.hpp>
10 #include <boost/hana/detail/variadic/take.hpp>
11 #include <boost/hana/functional/always.hpp>
12 #include <boost/hana/functional/id.hpp>
13 #include <boost/hana/functional/on.hpp>
14 #include <boost/hana/fwd/append.hpp>
15 #include <boost/hana/fwd/at.hpp>
16 #include <boost/hana/fwd/concat.hpp>
17 #include <boost/hana/fwd/concept/sequence.hpp>
18 #include <boost/hana/fwd/core/make.hpp>
19 #include <boost/hana/fwd/drop_front.hpp>
20 #include <boost/hana/fwd/empty.hpp>
21 #include <boost/hana/fwd/front.hpp>
22 #include <boost/hana/fwd/prepend.hpp>
23 #include <boost/hana/fwd/take_front.hpp>
24 #include <boost/hana/fwd/transform.hpp>
25 #include <boost/hana/fwd/unpack.hpp>
26 #include <boost/hana/fwd/zip_shortest_with.hpp>
27 #include <boost/hana/integral_constant.hpp>
28 #include <boost/hana/is_empty.hpp>
29 #include <boost/hana/length.hpp>
30 #include <boost/hana/min.hpp>
31 #include <boost/hana/minimum.hpp>
32 #include <boost/hana/range.hpp>
33 #include <boost/hana/unpack.hpp>
34
35 #include <utility>
36 namespace hana = boost::hana;
37
38
39 struct lambda_tuple_tag { };
40
41 template <typename Storage>
42 struct lambda_tuple_t {
43 explicit constexpr lambda_tuple_t(Storage&& s)
44 : storage(std::move(s))
45 { }
46
47 using hana_tag = lambda_tuple_tag;
48 Storage storage;
49 };
50
51 BOOST_HANA_CONSTEXPR_LAMBDA auto lambda_tuple = [](auto ...xs) -> decltype(auto) {
52 auto storage = [=](auto f) -> decltype(auto) { return f(xs...); };
53 return lambda_tuple_t<decltype(storage)>{std::move(storage)};
54 };
55
56 namespace boost { namespace hana {
57 //////////////////////////////////////////////////////////////////////////
58 // Foldable
59 //////////////////////////////////////////////////////////////////////////
60 template <>
61 struct unpack_impl<lambda_tuple_tag> {
62 template <typename Xs, typename F>
63 static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
64 return static_cast<Xs&&>(xs)
65 .storage(static_cast<F&&>(f));
66 }
67 };
68
69 //////////////////////////////////////////////////////////////////////////
70 // Functor
71 //////////////////////////////////////////////////////////////////////////
72 template <>
73 struct transform_impl<lambda_tuple_tag> {
74 template <typename Xs, typename F>
75 static constexpr decltype(auto) apply(Xs&& xs, F f) {
76 return static_cast<Xs&&>(xs).storage(
77 [f(std::move(f))](auto&& ...xs) -> decltype(auto) {
78 return lambda_tuple(f(static_cast<decltype(xs)&&>(xs))...);
79 }
80 );
81 }
82 };
83
84 //////////////////////////////////////////////////////////////////////////
85 // Iterable
86 //////////////////////////////////////////////////////////////////////////
87 template <>
88 struct front_impl<lambda_tuple_tag> {
89 template <typename Xs>
90 static constexpr decltype(auto) apply(Xs&& xs) {
91 return static_cast<Xs&&>(xs).storage(
92 [](auto&& x, auto&& ...) -> decltype(auto) {
93 return id(static_cast<decltype(x)&&>(x));
94 }
95 );
96 }
97 };
98
99 template <>
100 struct is_empty_impl<lambda_tuple_tag> {
101 template <typename Xs>
102 static constexpr decltype(auto) apply(Xs&& xs) {
103 return static_cast<Xs&&>(xs).storage(
104 [](auto const& ...xs) -> decltype(auto) {
105 return hana::bool_c<sizeof...(xs) == 0>;
106 }
107 );
108 }
109 };
110
111 template <>
112 struct at_impl<lambda_tuple_tag> {
113 template <typename Xs, typename Index>
114 static constexpr decltype(auto) apply(Xs&& xs, Index const&) {
115 return static_cast<Xs&&>(xs).storage(
116 detail::variadic::at<Index::value>
117 );
118 }
119 };
120
121 template <>
122 struct drop_front_impl<lambda_tuple_tag> {
123 template <typename Xs, typename N>
124 static constexpr decltype(auto) apply(Xs&& xs, N const& n) {
125 auto m = min(n, length(xs));
126 return static_cast<Xs&&>(xs).storage(
127 detail::variadic::drop_into<hana::value(m)>(lambda_tuple)
128 );
129 }
130 };
131
132 //////////////////////////////////////////////////////////////////////////
133 // MonadPlus
134 //////////////////////////////////////////////////////////////////////////
135 template <>
136 struct concat_impl<lambda_tuple_tag> {
137 template <typename Xs, typename Ys>
138 static constexpr decltype(auto) apply(Xs&& xs, Ys&& ys) {
139 return static_cast<Xs&&>(xs).storage(
140 [ys(static_cast<Ys&&>(ys))](auto&& ...xs) -> decltype(auto) {
141 return std::move(ys).storage(
142 // We can't initialize the capture with perfect
143 // forwarding since that's not supported by the
144 // language.
145 [=](auto&& ...ys) -> decltype(auto) {
146 return lambda_tuple(
147 std::move(xs)...,
148 static_cast<decltype(ys)&&>(ys)...
149 );
150 }
151 );
152 }
153 );
154 }
155 };
156
157 template <>
158 struct prepend_impl<lambda_tuple_tag> {
159 template <typename Xs, typename X>
160 static constexpr decltype(auto) apply(Xs&& xs, X&& x) {
161 return static_cast<Xs&&>(xs).storage(
162 [x(static_cast<X&&>(x))](auto&& ...xs) -> decltype(auto) {
163 return lambda_tuple(
164 std::move(x),
165 static_cast<decltype(xs)&&>(xs)...
166 );
167 }
168 );
169 }
170 };
171
172 template <>
173 struct append_impl<lambda_tuple_tag> {
174 template <typename Xs, typename X>
175 static constexpr decltype(auto) apply(Xs&& xs, X&& x) {
176 return static_cast<Xs&&>(xs).storage(
177 [x(static_cast<X&&>(x))](auto&& ...xs) -> decltype(auto) {
178 return lambda_tuple(
179 static_cast<decltype(xs)&&>(xs)...,
180 std::move(x)
181 );
182 }
183 );
184 }
185 };
186
187 template <>
188 struct empty_impl<lambda_tuple_tag> {
189 static BOOST_HANA_CONSTEXPR_LAMBDA decltype(auto) apply() {
190 return lambda_tuple();
191 }
192 };
193
194 //////////////////////////////////////////////////////////////////////////
195 // Sequence
196 //////////////////////////////////////////////////////////////////////////
197 template <>
198 struct Sequence<lambda_tuple_tag> {
199 static constexpr bool value = true;
200 };
201
202 template <>
203 struct take_front_impl<lambda_tuple_tag> {
204 template <typename Xs, typename N>
205 static constexpr decltype(auto) apply(Xs&& xs, N const& n) {
206 auto m = min(n, length(xs));
207 return static_cast<Xs&&>(xs).storage(
208 detail::variadic::take<decltype(m)::value>
209 )(lambda_tuple);
210 }
211 };
212
213 template <>
214 struct zip_shortest_with_impl<lambda_tuple_tag> {
215 template <typename F, typename ...Xss>
216 static constexpr auto apply(F f, Xss ...tuples) {
217 auto go = [=](auto index, auto ...nothing) {
218 return always(f)(nothing...)(at(tuples, index)...);
219 };
220 auto zip_length = minimum(lambda_tuple(length(tuples)...));
221 return unpack(make_range(size_c<0>, zip_length),
222 on(lambda_tuple, go)
223 );
224 }
225 };
226
227 //////////////////////////////////////////////////////////////////////////
228 // make
229 //////////////////////////////////////////////////////////////////////////
230 template <>
231 struct make_impl<lambda_tuple_tag> {
232 template <typename ...Xs>
233 static constexpr decltype(auto) apply(Xs&& ...xs) {
234 return lambda_tuple(static_cast<Xs&&>(xs)...);
235 }
236 };
237 }} // end namespace boost::hana
238
239
240 int main() {
241 auto xs = lambda_tuple(1, '2', 3.3);
242 static_assert(!decltype(hana::is_empty(xs))::value, "");
243 }