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
14namespace flow_test {
15struct increment
16{
17 template<class T>
18 constexpr T operator()(T x) const noexcept
19 {
20 return x + 1;
21 }
22};
23
24struct decrement
25{
26 template<class T>
27 constexpr T operator()(T x) const noexcept
28 {
29 return x - 1;
30 }
31};
32
33struct negate
34{
35 template<class T>
36 constexpr T operator()(T x) const noexcept
37 {
38 return -x;
39 }
40};
41
42struct increment_movable
43{
44 std::unique_ptr<int> n;
45 increment_movable()
46 : n(new int(1))
47 {}
48 template<class T>
49 T operator()(T x) const
50 {
51 return x + *n;
52 }
53};
54
55struct decrement_movable
56{
57 std::unique_ptr<int> n;
58 decrement_movable()
59 : n(new int(1))
60 {}
61 template<class T>
62 T operator()(T x) const
63 {
64 return x - *n;
65 }
66};
67#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
68BOOST_HOF_TEST_CASE()
69{
70 static_assert(noexcept(boost::hof::flow(increment(), decrement(), increment())(3)), "noexcept flow");
71}
72#endif
73
74BOOST_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
85BOOST_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
92BOOST_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
99BOOST_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
109BOOST_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
117BOOST_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
128BOOST_HOF_STATIC_FUNCTION(f_flow_single_function) = boost::hof::flow(increment());
129
130BOOST_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
136BOOST_HOF_STATIC_FUNCTION(f_flow_function) = boost::hof::flow(increment(), decrement(), increment());
137
138BOOST_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
144BOOST_HOF_STATIC_FUNCTION(f_flow_function_4) = boost::hof::flow(increment(), negate(), decrement(), decrement());
145
146BOOST_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
152BOOST_HOF_STATIC_LAMBDA_FUNCTION(f_flow_lambda) = boost::hof::flow(
153 [](int i) { return i+1; },
154 [](int i) { return i-1; },
155 [](int i) { return i+1; }
156);
157
158BOOST_HOF_TEST_CASE()
159{
160 int r = f_flow_lambda(3);
161 BOOST_HOF_TEST_CHECK(r == 4);
162}
163
164BOOST_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

source code of boost/libs/hof/test/flow.cpp