]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/example/misc/lambda_tuple.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / hana / example / misc / lambda_tuple.cpp
CommitLineData
b32b8144 1// Copyright Louis Dionne 2013-2017
7c673cae
FG
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>
36namespace hana = boost::hana;
37
38
b32b8144
FG
39// An interesting way of implementing tuple using lambda captures.
40
7c673cae
FG
41struct lambda_tuple_tag { };
42
43template <typename Storage>
44struct lambda_tuple_t {
45 explicit constexpr lambda_tuple_t(Storage&& s)
46 : storage(std::move(s))
47 { }
48
49 using hana_tag = lambda_tuple_tag;
50 Storage storage;
51};
52
b32b8144 53auto lambda_tuple = [](auto ...xs) {
7c673cae
FG
54 auto storage = [=](auto f) -> decltype(auto) { return f(xs...); };
55 return lambda_tuple_t<decltype(storage)>{std::move(storage)};
56};
57
58namespace boost { namespace hana {
59 //////////////////////////////////////////////////////////////////////////
60 // Foldable
61 //////////////////////////////////////////////////////////////////////////
62 template <>
63 struct unpack_impl<lambda_tuple_tag> {
64 template <typename Xs, typename F>
65 static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
b32b8144 66 return static_cast<Xs&&>(xs).storage(static_cast<F&&>(f));
7c673cae
FG
67 }
68 };
69
70 //////////////////////////////////////////////////////////////////////////
71 // Functor
72 //////////////////////////////////////////////////////////////////////////
73 template <>
74 struct transform_impl<lambda_tuple_tag> {
75 template <typename Xs, typename F>
76 static constexpr decltype(auto) apply(Xs&& xs, F f) {
77 return static_cast<Xs&&>(xs).storage(
78 [f(std::move(f))](auto&& ...xs) -> decltype(auto) {
79 return lambda_tuple(f(static_cast<decltype(xs)&&>(xs))...);
80 }
81 );
82 }
83 };
84
85 //////////////////////////////////////////////////////////////////////////
86 // Iterable
87 //////////////////////////////////////////////////////////////////////////
88 template <>
89 struct front_impl<lambda_tuple_tag> {
90 template <typename Xs>
91 static constexpr decltype(auto) apply(Xs&& xs) {
92 return static_cast<Xs&&>(xs).storage(
93 [](auto&& x, auto&& ...) -> decltype(auto) {
94 return id(static_cast<decltype(x)&&>(x));
95 }
96 );
97 }
98 };
99
100 template <>
101 struct is_empty_impl<lambda_tuple_tag> {
102 template <typename Xs>
103 static constexpr decltype(auto) apply(Xs&& xs) {
104 return static_cast<Xs&&>(xs).storage(
105 [](auto const& ...xs) -> decltype(auto) {
106 return hana::bool_c<sizeof...(xs) == 0>;
107 }
108 );
109 }
110 };
111
112 template <>
113 struct at_impl<lambda_tuple_tag> {
114 template <typename Xs, typename Index>
115 static constexpr decltype(auto) apply(Xs&& xs, Index const&) {
116 return static_cast<Xs&&>(xs).storage(
117 detail::variadic::at<Index::value>
118 );
119 }
120 };
121
122 template <>
123 struct drop_front_impl<lambda_tuple_tag> {
124 template <typename Xs, typename N>
125 static constexpr decltype(auto) apply(Xs&& xs, N const& n) {
126 auto m = min(n, length(xs));
127 return static_cast<Xs&&>(xs).storage(
128 detail::variadic::drop_into<hana::value(m)>(lambda_tuple)
129 );
130 }
131 };
132
133 //////////////////////////////////////////////////////////////////////////
134 // MonadPlus
135 //////////////////////////////////////////////////////////////////////////
136 template <>
137 struct concat_impl<lambda_tuple_tag> {
138 template <typename Xs, typename Ys>
139 static constexpr decltype(auto) apply(Xs&& xs, Ys&& ys) {
140 return static_cast<Xs&&>(xs).storage(
141 [ys(static_cast<Ys&&>(ys))](auto&& ...xs) -> decltype(auto) {
142 return std::move(ys).storage(
143 // We can't initialize the capture with perfect
144 // forwarding since that's not supported by the
145 // language.
146 [=](auto&& ...ys) -> decltype(auto) {
147 return lambda_tuple(
148 std::move(xs)...,
149 static_cast<decltype(ys)&&>(ys)...
150 );
151 }
152 );
153 }
154 );
155 }
156 };
157
158 template <>
159 struct prepend_impl<lambda_tuple_tag> {
160 template <typename Xs, typename X>
161 static constexpr decltype(auto) apply(Xs&& xs, X&& x) {
162 return static_cast<Xs&&>(xs).storage(
163 [x(static_cast<X&&>(x))](auto&& ...xs) -> decltype(auto) {
164 return lambda_tuple(
165 std::move(x),
166 static_cast<decltype(xs)&&>(xs)...
167 );
168 }
169 );
170 }
171 };
172
173 template <>
174 struct append_impl<lambda_tuple_tag> {
175 template <typename Xs, typename X>
176 static constexpr decltype(auto) apply(Xs&& xs, X&& x) {
177 return static_cast<Xs&&>(xs).storage(
178 [x(static_cast<X&&>(x))](auto&& ...xs) -> decltype(auto) {
179 return lambda_tuple(
180 static_cast<decltype(xs)&&>(xs)...,
181 std::move(x)
182 );
183 }
184 );
185 }
186 };
187
188 template <>
189 struct empty_impl<lambda_tuple_tag> {
190 static BOOST_HANA_CONSTEXPR_LAMBDA decltype(auto) apply() {
191 return lambda_tuple();
192 }
193 };
194
195 //////////////////////////////////////////////////////////////////////////
196 // Sequence
197 //////////////////////////////////////////////////////////////////////////
198 template <>
199 struct Sequence<lambda_tuple_tag> {
200 static constexpr bool value = true;
201 };
202
203 template <>
204 struct take_front_impl<lambda_tuple_tag> {
205 template <typename Xs, typename N>
206 static constexpr decltype(auto) apply(Xs&& xs, N const& n) {
207 auto m = min(n, length(xs));
208 return static_cast<Xs&&>(xs).storage(
209 detail::variadic::take<decltype(m)::value>
210 )(lambda_tuple);
211 }
212 };
213
214 template <>
215 struct zip_shortest_with_impl<lambda_tuple_tag> {
216 template <typename F, typename ...Xss>
217 static constexpr auto apply(F f, Xss ...tuples) {
218 auto go = [=](auto index, auto ...nothing) {
219 return always(f)(nothing...)(at(tuples, index)...);
220 };
221 auto zip_length = minimum(lambda_tuple(length(tuples)...));
222 return unpack(make_range(size_c<0>, zip_length),
223 on(lambda_tuple, go)
224 );
225 }
226 };
227
228 //////////////////////////////////////////////////////////////////////////
229 // make
230 //////////////////////////////////////////////////////////////////////////
231 template <>
232 struct make_impl<lambda_tuple_tag> {
233 template <typename ...Xs>
234 static constexpr decltype(auto) apply(Xs&& ...xs) {
235 return lambda_tuple(static_cast<Xs&&>(xs)...);
236 }
237 };
238}} // end namespace boost::hana
239
240
241int main() {
242 auto xs = lambda_tuple(1, '2', 3.3);
243 static_assert(!decltype(hana::is_empty(xs))::value, "");
244}