• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2017 Paul Fultz II
3     flow.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/flow.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 flow_test {
15 struct increment
16 {
17     template<class T>
operator ()flow_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 ()flow_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 ()flow_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_movableflow_test::increment_movable45     increment_movable()
46     : n(new int(1))
47     {}
48     template<class T>
operator ()flow_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_movableflow_test::decrement_movable58     decrement_movable()
59     : n(new int(1))
60     {}
61     template<class T>
operator ()flow_test::decrement_movable62     T operator()(T x) const
63     {
64         return x - *n;
65     }
66 };
67 #if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
BOOST_HOF_TEST_CASE()68 BOOST_HOF_TEST_CASE()
69 {
70     static_assert(noexcept(boost::hof::flow(increment(), decrement(), increment())(3)), "noexcept flow");
71 }
72 #endif
73 
BOOST_HOF_TEST_CASE()74 BOOST_HOF_TEST_CASE()
75 {
76     BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::identity)(3) == 3);
77     BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity)(3) == 3);
78     BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3);
79 
80     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::identity)(3) == 3);
81     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity)(3) == 3);
82     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3);
83 }
84 
BOOST_HOF_TEST_CASE()85 BOOST_HOF_TEST_CASE()
86 {
87     int r = boost::hof::flow(increment(), decrement(), increment())(3);
88     BOOST_HOF_TEST_CHECK(r == 4);
89     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(increment(), decrement(), increment())(3) == 4);
90 }
91 
BOOST_HOF_TEST_CASE()92 BOOST_HOF_TEST_CASE()
93 {
94     int r = boost::hof::flow(increment(), negate(), decrement(), decrement())(3);
95     BOOST_HOF_TEST_CHECK(r == -6);
96     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(increment(), negate(), decrement(), decrement())(3) == -6);
97 }
98 #ifndef _MSC_VER
BOOST_HOF_TEST_CASE()99 BOOST_HOF_TEST_CASE()
100 {
101     constexpr auto f = boost::hof::flow(increment(), decrement());
102     static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty");
103     int r = f(3);
104     BOOST_HOF_TEST_CHECK(r == 3);
105     BOOST_HOF_STATIC_TEST_CHECK(f(3) == 3);
106 }
107 #endif
108 
BOOST_HOF_TEST_CASE()109 BOOST_HOF_TEST_CASE()
110 {
111     STATIC_ASSERT_MOVE_ONLY(increment_movable);
112     STATIC_ASSERT_MOVE_ONLY(decrement_movable);
113     int r = boost::hof::flow(increment_movable(), decrement_movable(), increment_movable())(3);
114     BOOST_HOF_TEST_CHECK(r == 4);
115 }
116 
BOOST_HOF_TEST_CASE()117 BOOST_HOF_TEST_CASE()
118 {
119     const auto f = boost::hof::flow([](int i) { return i+1; }, [](int i) { return i-1; }, [](int i) { return i+1; });
120 #ifndef _MSC_VER
121     static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty");
122 #endif
123     int r = f(3);
124     BOOST_HOF_TEST_CHECK(r == 4);
125 }
126 
127 
128 BOOST_HOF_STATIC_FUNCTION(f_flow_single_function) = boost::hof::flow(increment());
129 
BOOST_HOF_TEST_CASE()130 BOOST_HOF_TEST_CASE()
131 {
132     BOOST_HOF_TEST_CHECK(f_flow_single_function(3) == 4);
133     BOOST_HOF_STATIC_TEST_CHECK(f_flow_single_function(3) == 4);
134 }
135 
136 BOOST_HOF_STATIC_FUNCTION(f_flow_function) = boost::hof::flow(increment(), decrement(), increment());
137 
BOOST_HOF_TEST_CASE()138 BOOST_HOF_TEST_CASE()
139 {
140     BOOST_HOF_TEST_CHECK(f_flow_function(3) == 4);
141     BOOST_HOF_STATIC_TEST_CHECK(f_flow_function(3) == 4);
142 }
143 
144 BOOST_HOF_STATIC_FUNCTION(f_flow_function_4) = boost::hof::flow(increment(), negate(), decrement(), decrement());
145 
BOOST_HOF_TEST_CASE()146 BOOST_HOF_TEST_CASE()
147 {
148     BOOST_HOF_TEST_CHECK(f_flow_function_4(3) == -6);
149     BOOST_HOF_STATIC_TEST_CHECK(f_flow_function_4(3) == -6);
150 }
151 
152 BOOST_HOF_STATIC_LAMBDA_FUNCTION(f_flow_lambda) = boost::hof::flow(
__anon0eaf7d350402(int i) 153     [](int i) { return i+1; },
__anon0eaf7d350502(int i) 154     [](int i) { return i-1; },
__anon0eaf7d350602(int i) 155     [](int i) { return i+1; }
156 );
157 
BOOST_HOF_TEST_CASE()158 BOOST_HOF_TEST_CASE()
159 {
160     int r = f_flow_lambda(3);
161     BOOST_HOF_TEST_CHECK(r == 4);
162 }
163 
BOOST_HOF_TEST_CASE()164 BOOST_HOF_TEST_CASE()
165 {
166     BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::_1 + boost::hof::_1, boost::hof::_1 * boost::hof::_1)(3) == 36);
167     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::_1 + boost::hof::_1, boost::hof::_1 * boost::hof::_1)(3) == 36);
168 }
169 }
170