]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/test/_include/support/identity.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / hana / test / _include / support / identity.hpp
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 #ifndef TEST_SUPPORT_IDENTITY_HPP
6 #define TEST_SUPPORT_IDENTITY_HPP
7
8 #include <boost/hana/chain.hpp>
9 #include <boost/hana/eval_if.hpp>
10 #include <boost/hana/functional/compose.hpp>
11 #include <boost/hana/functional/partial.hpp>
12 #include <boost/hana/fwd/adjust_if.hpp>
13 #include <boost/hana/fwd/ap.hpp>
14 #include <boost/hana/fwd/equal.hpp>
15 #include <boost/hana/fwd/flatten.hpp>
16 #include <boost/hana/fwd/less.hpp>
17 #include <boost/hana/fwd/lift.hpp>
18 #include <boost/hana/lazy.hpp>
19 #include <boost/hana/transform.hpp>
20
21 #include <type_traits>
22
23
24 struct Identity;
25
26 template <typename T>
27 struct identity_t {
28 T value;
29 using hana_tag = Identity;
30 };
31
32 struct make_identity {
33 template <typename T>
34 constexpr identity_t<typename std::decay<T>::type> operator()(T&& t) const {
35 return {static_cast<T&&>(t)};
36 }
37 };
38
39 constexpr make_identity identity{};
40
41
42 namespace boost { namespace hana {
43 //////////////////////////////////////////////////////////////////////////
44 // Comparable
45 //////////////////////////////////////////////////////////////////////////
46 template <>
47 struct equal_impl<Identity, Identity> {
48 template <typename Id1, typename Id2>
49 static constexpr auto apply(Id1 x, Id2 y)
50 { return hana::equal(x.value, y.value); }
51 };
52
53 //////////////////////////////////////////////////////////////////////////
54 // Orderable
55 //////////////////////////////////////////////////////////////////////////
56 template <>
57 struct less_impl<Identity, Identity> {
58 template <typename Id1, typename Id2>
59 static constexpr auto apply(Id1 x, Id2 y)
60 { return hana::less(x.value, y.value); }
61 };
62
63 //////////////////////////////////////////////////////////////////////////
64 // Functor
65 //
66 // Define either one to select which MCD is used:
67 // BOOST_HANA_TEST_FUNCTOR_TRANSFORM_MCD
68 // BOOST_HANA_TEST_FUNCTOR_ADJUST_MCD_MCD
69 //
70 // If neither is defined, the MCD used is unspecified.
71 //////////////////////////////////////////////////////////////////////////
72 #ifdef BOOST_HANA_TEST_FUNCTOR_TRANSFORM_MCD
73 template <>
74 struct transform_impl<Identity> {
75 template <typename Id, typename F>
76 static constexpr auto apply(Id self, F f)
77 { return ::identity(f(self.value)); }
78 };
79 #else
80 template <>
81 struct adjust_if_impl<Identity> {
82 struct get_value {
83 template <typename T>
84 constexpr auto operator()(T t) const { return t.value; }
85 };
86
87 template <typename Id, typename P, typename F>
88 static constexpr auto apply(Id self, P p, F f) {
89 auto x = hana::eval_if(p(self.value),
90 hana::make_lazy(hana::compose(f, get_value{}))(self),
91 hana::make_lazy(get_value{})(self)
92 );
93 return ::identity(x);
94 }
95 };
96 #endif
97
98 //////////////////////////////////////////////////////////////////////////
99 // Applicative
100 //
101 // Define either one to select which MCD is used:
102 // BOOST_HANA_TEST_APPLICATIVE_FULL_MCD
103 // BOOST_HANA_TEST_APPLICATIVE_MONAD_MCD
104 //
105 // If neither is defined, the MCD used is unspecified.
106 //////////////////////////////////////////////////////////////////////////
107 template <>
108 struct lift_impl<Identity> {
109 template <typename X>
110 static constexpr auto apply(X x)
111 { return ::identity(x); }
112 };
113 #ifdef BOOST_HANA_TEST_APPLICATIVE_FULL_MCD
114 template <>
115 struct ap_impl<Identity> {
116 template <typename F, typename X>
117 static constexpr auto apply(F f, X x)
118 { return ::identity(f.value(x.value)); }
119 };
120 #else
121 template <>
122 struct ap_impl<Identity> {
123 template <typename F, typename X>
124 static constexpr decltype(auto) apply(F&& f, X&& x) {
125 return hana::chain(
126 static_cast<F&&>(f),
127 hana::partial(hana::transform, static_cast<X&&>(x))
128 );
129 }
130 };
131 #endif
132
133 //////////////////////////////////////////////////////////////////////////
134 // Monad
135 //
136 // Define either one to select which MCD is used:
137 // BOOST_HANA_TEST_MONAD_FLATTEN_MCD
138 // BOOST_HANA_TEST_MONAD_CHAIN_MCD
139 //
140 // If neither is defined, the MCD used is unspecified.
141 //////////////////////////////////////////////////////////////////////////
142 #ifdef BOOST_HANA_TEST_MONAD_FLATTEN_MCD
143 template <>
144 struct flatten_impl<Identity> {
145 template <typename Id>
146 static constexpr auto apply(Id self)
147 { return self.value; }
148 };
149 #else
150 template <>
151 struct chain_impl<Identity> {
152 template <typename X, typename F>
153 static constexpr auto apply(X x, F f)
154 { return f(x.value); }
155 };
156 #endif
157 }} // end namespace boost::hana
158
159 #endif // !TEST_SUPPORT_IDENTITY_HPP