• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2017 Paul Fultz II
3     compose.cpp
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #include <boost/hof/compose.hpp>
8 #include <boost/hof/function.hpp>
9 #include <boost/hof/lambda.hpp>
10 #include <boost/hof/placeholders.hpp>
11 #include <memory>
12 #include "test.hpp"
13 
14 namespace compose_test {
15 struct increment
16 {
17     template<class T>
operator ()compose_test::increment18     constexpr T operator()(T x) const noexcept
19     {
20         return x + 1;
21     }
22 };
23 
24 struct decrement
25 {
26     template<class T>
operator ()compose_test::decrement27     constexpr T operator()(T x) const noexcept
28     {
29         return x - 1;
30     }
31 };
32 
33 struct negate
34 {
35     template<class T>
operator ()compose_test::negate36     constexpr T operator()(T x) const noexcept
37     {
38         return -x;
39     }
40 };
41 
42 struct increment_movable
43 {
44     std::unique_ptr<int> n;
increment_movablecompose_test::increment_movable45     increment_movable()
46     : n(new int(1))
47     {}
48     template<class T>
operator ()compose_test::increment_movable49     T operator()(T x) const
50     {
51         return x + *n;
52     }
53 };
54 
55 struct decrement_movable
56 {
57     std::unique_ptr<int> n;
decrement_movablecompose_test::decrement_movable58     decrement_movable()
59     : n(new int(1))
60     {}
61     template<class T>
operator ()compose_test::decrement_movable62     T operator()(T x) const
63     {
64         return x - *n;
65     }
66 };
67 
68 #if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
BOOST_HOF_TEST_CASE()69 BOOST_HOF_TEST_CASE()
70 {
71     static_assert(noexcept(boost::hof::compose(increment(), decrement(), increment())(3)), "noexcept compose");
72 }
73 #endif
74 
BOOST_HOF_TEST_CASE()75 BOOST_HOF_TEST_CASE()
76 {
77     BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::identity)(3) == 3);
78     BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity)(3) == 3);
79     BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3);
80 
81     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::identity)(3) == 3);
82     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity)(3) == 3);
83     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3);
84 }
85 
BOOST_HOF_TEST_CASE()86 BOOST_HOF_TEST_CASE()
87 {
88     int r = boost::hof::compose(increment(), decrement(), increment())(3);
89     BOOST_HOF_TEST_CHECK(r == 4);
90     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(increment(), decrement(), increment())(3) == 4);
91 }
92 
BOOST_HOF_TEST_CASE()93 BOOST_HOF_TEST_CASE()
94 {
95     int r = boost::hof::compose(increment(), negate(), decrement(), decrement())(3);
96     BOOST_HOF_TEST_CHECK(r == 0);
97     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(increment(), negate(), decrement(), decrement())(3) == 0);
98 }
BOOST_HOF_TEST_CASE()99 BOOST_HOF_TEST_CASE()
100 {
101     constexpr auto f = boost::hof::compose(increment(), decrement());
102 #ifndef _MSC_VER
103     static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty");
104 #endif
105     static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(decltype(f)), "Compose function not default constructible");
106     int r = f(3);
107     BOOST_HOF_TEST_CHECK(r == 3);
108     BOOST_HOF_STATIC_TEST_CHECK(f(3) == 3);
109 }
110 
111 #ifndef _MSC_VER
BOOST_HOF_TEST_CASE()112 BOOST_HOF_TEST_CASE()
113 {
114     constexpr auto f = boost::hof::compose(increment(), negate(), decrement(), decrement());
115     static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty");
116     static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(decltype(f)), "Compose function not default constructible");
117     int r = f(3);
118     BOOST_HOF_TEST_CHECK(r == 0);
119     BOOST_HOF_STATIC_TEST_CHECK(f(3) == 0);
120 }
121 #endif
122 
BOOST_HOF_TEST_CASE()123 BOOST_HOF_TEST_CASE()
124 {
125     STATIC_ASSERT_MOVE_ONLY(increment_movable);
126     STATIC_ASSERT_MOVE_ONLY(decrement_movable);
127     int r = boost::hof::compose(increment_movable(), decrement_movable(), increment_movable())(3);
128     BOOST_HOF_TEST_CHECK(r == 4);
129 }
130 
131 template<class T>
132 struct print;
133 
BOOST_HOF_TEST_CASE()134 BOOST_HOF_TEST_CASE()
135 {
136     const auto f = boost::hof::compose([](int i) { return i+1; }, [](int i) { return i-1; }, [](int i) { return i+1; });
137 #ifndef _MSC_VER
138     static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty");
139 #endif
140     int r = f(3);
141     BOOST_HOF_TEST_CHECK(r == 4);
142 }
143 
144 
145 BOOST_HOF_STATIC_FUNCTION(f_compose_single_function) = boost::hof::compose(increment());
146 
BOOST_HOF_TEST_CASE()147 BOOST_HOF_TEST_CASE()
148 {
149     BOOST_HOF_TEST_CHECK(f_compose_single_function(3) == 4);
150     BOOST_HOF_STATIC_TEST_CHECK(f_compose_single_function(3) == 4);
151 }
152 
153 BOOST_HOF_STATIC_FUNCTION(f_compose_function) = boost::hof::compose(increment(), decrement(), increment());
154 
BOOST_HOF_TEST_CASE()155 BOOST_HOF_TEST_CASE()
156 {
157     BOOST_HOF_TEST_CHECK(f_compose_function(3) == 4);
158     BOOST_HOF_STATIC_TEST_CHECK(f_compose_function(3) == 4);
159 }
160 
161 BOOST_HOF_STATIC_FUNCTION(f_compose_function_4) = boost::hof::compose(increment(), negate(), decrement(), decrement());
162 
BOOST_HOF_TEST_CASE()163 BOOST_HOF_TEST_CASE()
164 {
165     BOOST_HOF_TEST_CHECK(f_compose_function_4(3) == 0);
166     BOOST_HOF_STATIC_TEST_CHECK(f_compose_function_4(3) == 0);
167 }
168 
169 BOOST_HOF_STATIC_LAMBDA_FUNCTION(f_compose_lambda) = boost::hof::compose(
__anon562db9130402(int i) 170     [](int i) { return i+1; },
__anon562db9130502(int i) 171     [](int i) { return i-1; },
__anon562db9130602(int i) 172     [](int i) { return i+1; }
173 );
174 
BOOST_HOF_TEST_CASE()175 BOOST_HOF_TEST_CASE()
176 {
177     int r = f_compose_lambda(3);
178     BOOST_HOF_TEST_CHECK(r == 4);
179 }
180 
BOOST_HOF_TEST_CASE()181 BOOST_HOF_TEST_CASE()
182 {
183     BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1)(3) == 36);
184     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1)(3) == 36);
185 }
186 }
187