]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/experimental/strong_datatypes.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / experimental / strong_datatypes.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/ap.hpp>
6 #include <boost/hana/config.hpp>
7 #include <boost/hana/core/make.hpp>
8 #include <boost/hana/core/tag_of.hpp>
9 #include <boost/hana/tuple.hpp>
10 namespace hana = boost::hana;
11
12
13 namespace wrap_detail {
14 template <typename Datatype, typename X>
15 struct wrapper {
16 X unwrap;
17 using hana_tag = Datatype;
18 };
19
20 template <typename Datatype>
21 struct wrap_impl {
22 template <typename X>
23 constexpr auto operator()(X x) const {
24 return wrapper<Datatype, X>{x};
25 }
26 };
27 }
28
29 template <typename Datatype>
30 constexpr wrap_detail::wrap_impl<Datatype> wrap{};
31
32 BOOST_HANA_CONSTEXPR_LAMBDA auto unwrap = [](auto x) {
33 return x.unwrap;
34 };
35
36 //////////////////////////////////////////////////////////////////////////////
37 // core
38 //////////////////////////////////////////////////////////////////////////////
39 template <typename ...>
40 struct not_implemented;
41
42
43 //////////////////////////////////////////////////////////////////////////////
44 // Functor
45 //////////////////////////////////////////////////////////////////////////////
46 template <typename X, typename F, typename Enable = void>
47 not_implemented<X, F> fmap_impl{};
48
49 auto fmap = [](auto x, auto f) {
50 return fmap_impl<
51 hana::tag_of_t<decltype(x)>,
52 hana::tag_of_t<decltype(f)>
53 >(x, f);
54 };
55
56
57 //////////////////////////////////////////////////////////////////////////////
58 // Applicative
59 //////////////////////////////////////////////////////////////////////////////
60 template <typename F, typename X, typename Enable = void>
61 not_implemented<F, X> ap_impl{};
62
63 auto ap = [](auto f, auto x) {
64 return ap_impl<
65 hana::tag_of_t<decltype(f)>,
66 hana::tag_of_t<decltype(x)>
67 >(f, x);
68 };
69
70 template <typename A, typename Enable = void>
71 not_implemented<A> lift_impl{};
72
73 template <template <typename> class A>
74 auto lift = [](auto x) {
75 return lift_impl<A<hana::tag_of_t<decltype(x)>>>(x);
76 };
77
78
79 //////////////////////////////////////////////////////////////////////////////
80 // Function
81 //////////////////////////////////////////////////////////////////////////////
82 template <typename F, typename X, typename Enable = void>
83 not_implemented<F, X> apply_impl{};
84
85 auto apply = [](auto f, auto x) {
86 return apply_impl<
87 hana::tag_of_t<decltype(f)>,
88 hana::tag_of_t<decltype(x)>
89 >(f, x);
90 };
91
92 template <typename Domain, typename Codomain>
93 struct Function;
94
95 template <typename Domain, typename Codomain>
96 auto function = [](auto f) {
97 return wrap<Function<Domain, Codomain>>(f);
98 };
99
100 template <typename X, typename Y>
101 auto apply_impl<Function<X, Y>, X> = [](auto f, auto x) {
102 return unwrap(f)(x);
103 };
104
105
106 //////////////////////////////////////////////////////////////////////////////
107 // List
108 //////////////////////////////////////////////////////////////////////////////
109 template <typename T>
110 struct List;
111
112 template <typename T>
113 auto list = [](auto ...xs) {
114 return wrap<List<T>>(
115 [=](auto f) { return f(xs...); }
116 );
117 };
118
119 template <typename X, typename Y>
120 auto fmap_impl<List<X>, Function<X, Y>> = [](auto xs, auto f) {
121 return unwrap(xs)([=](auto ...xs) {
122 return list<Y>(apply(f, xs)...);
123 });
124 };
125
126 template <typename X>
127 auto lift_impl<List<X>> = [](auto x) {
128 return list<X>(x);
129 };
130
131 template <typename X, typename Y>
132 auto ap_impl<List<Function<X, Y>>, List<X>> = [](auto fs, auto xs) {
133 auto hana_fs = unwrap(fs)([](auto ...fs) {
134 return hana::make_tuple(hana::partial(apply, fs)...);
135 });
136 auto hana_xs = unwrap(xs)(hana::make_tuple);
137 auto hana_result = hana::ap(hana_fs, hana_xs);
138
139 return hana::unpack(hana_result, list<Y>);
140 };
141
142
143 //////////////////////////////////////////////////////////////////////////////
144 // Any
145 //////////////////////////////////////////////////////////////////////////////
146 struct Any;
147
148 auto any = [](auto x) {
149 return wrap<Any>(x);
150 };
151
152
153 int main() {
154 auto f = function<int, int>([](auto x) { return x + 1; });
155 auto xs = list<int>(1, 2, 3, 4);
156 fmap(xs, f);
157
158 lift<List>(2);
159 ap(list<Function<int, int>>(f, f), list<int>(1, 2));
160
161 auto g = function<Any, int>([](auto /*x*/) {
162 // We can't do anything with an Any, so there's not much choice here.
163 return 1;
164 });
165 fmap(list<Any>(any(1), any('2'), any("345")), g);
166 }