]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
7c673cae
FG
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>
10namespace hana = boost::hana;
11
12
13namespace 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
29template <typename Datatype>
30constexpr wrap_detail::wrap_impl<Datatype> wrap{};
31
32BOOST_HANA_CONSTEXPR_LAMBDA auto unwrap = [](auto x) {
33 return x.unwrap;
34};
35
36//////////////////////////////////////////////////////////////////////////////
37// core
38//////////////////////////////////////////////////////////////////////////////
39template <typename ...>
40struct not_implemented;
41
42
43//////////////////////////////////////////////////////////////////////////////
44// Functor
45//////////////////////////////////////////////////////////////////////////////
46template <typename X, typename F, typename Enable = void>
47not_implemented<X, F> fmap_impl{};
48
49auto 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//////////////////////////////////////////////////////////////////////////////
60template <typename F, typename X, typename Enable = void>
61not_implemented<F, X> ap_impl{};
62
63auto 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
70template <typename A, typename Enable = void>
71not_implemented<A> lift_impl{};
72
73template <template <typename> class A>
74auto lift = [](auto x) {
75 return lift_impl<A<hana::tag_of_t<decltype(x)>>>(x);
76};
77
78
79//////////////////////////////////////////////////////////////////////////////
80// Function
81//////////////////////////////////////////////////////////////////////////////
82template <typename F, typename X, typename Enable = void>
83not_implemented<F, X> apply_impl{};
84
85auto 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
92template <typename Domain, typename Codomain>
93struct Function;
94
95template <typename Domain, typename Codomain>
96auto function = [](auto f) {
97 return wrap<Function<Domain, Codomain>>(f);
98};
99
100template <typename X, typename Y>
101auto apply_impl<Function<X, Y>, X> = [](auto f, auto x) {
102 return unwrap(f)(x);
103};
104
105
106//////////////////////////////////////////////////////////////////////////////
107// List
108//////////////////////////////////////////////////////////////////////////////
109template <typename T>
110struct List;
111
112template <typename T>
113auto list = [](auto ...xs) {
114 return wrap<List<T>>(
115 [=](auto f) { return f(xs...); }
116 );
117};
118
119template <typename X, typename Y>
120auto 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
126template <typename X>
127auto lift_impl<List<X>> = [](auto x) {
128 return list<X>(x);
129};
130
131template <typename X, typename Y>
132auto 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//////////////////////////////////////////////////////////////////////////////
146struct Any;
147
148auto any = [](auto x) {
149 return wrap<Any>(x);
150};
151
152
153int 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}