1 // Copyright Louis Dionne 2013-2017
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)
5 #ifndef TEST_SUPPORT_IDENTITY_HPP
6 #define TEST_SUPPORT_IDENTITY_HPP
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>
21 #include <type_traits>
29 using hana_tag = Identity;
32 struct make_identity {
34 constexpr identity_t<typename std::decay<T>::type> operator()(T&& t) const {
35 return {static_cast<T&&>(t)};
39 constexpr make_identity identity{};
42 namespace boost { namespace hana {
43 //////////////////////////////////////////////////////////////////////////
45 //////////////////////////////////////////////////////////////////////////
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); }
53 //////////////////////////////////////////////////////////////////////////
55 //////////////////////////////////////////////////////////////////////////
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); }
63 //////////////////////////////////////////////////////////////////////////
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
70 // If neither is defined, the MCD used is unspecified.
71 //////////////////////////////////////////////////////////////////////////
72 #ifdef BOOST_HANA_TEST_FUNCTOR_TRANSFORM_MCD
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)); }
81 struct adjust_if_impl<Identity> {
84 constexpr auto operator()(T t) const { return t.value; }
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)
98 //////////////////////////////////////////////////////////////////////////
101 // Define either one to select which MCD is used:
102 // BOOST_HANA_TEST_APPLICATIVE_FULL_MCD
103 // BOOST_HANA_TEST_APPLICATIVE_MONAD_MCD
105 // If neither is defined, the MCD used is unspecified.
106 //////////////////////////////////////////////////////////////////////////
108 struct lift_impl<Identity> {
109 template <typename X>
110 static constexpr auto apply(X x)
111 { return ::identity(x); }
113 #ifdef BOOST_HANA_TEST_APPLICATIVE_FULL_MCD
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)); }
122 struct ap_impl<Identity> {
123 template <typename F, typename X>
124 static constexpr decltype(auto) apply(F&& f, X&& x) {
127 hana::partial(hana::transform, static_cast<X&&>(x))
133 //////////////////////////////////////////////////////////////////////////
136 // Define either one to select which MCD is used:
137 // BOOST_HANA_TEST_MONAD_FLATTEN_MCD
138 // BOOST_HANA_TEST_MONAD_CHAIN_MCD
140 // If neither is defined, the MCD used is unspecified.
141 //////////////////////////////////////////////////////////////////////////
142 #ifdef BOOST_HANA_TEST_MONAD_FLATTEN_MCD
144 struct flatten_impl<Identity> {
145 template <typename Id>
146 static constexpr auto apply(Id self)
147 { return self.value; }
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); }
157 }} // end namespace boost::hana
159 #endif // !TEST_SUPPORT_IDENTITY_HPP