1/*=============================================================================
2 Copyright (c) 2017 Paul Fultz II
3 first_of.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/first_of.hpp>
8#include <boost/hof/static.hpp>
9#include <boost/hof/lambda.hpp>
10#include <boost/hof/function.hpp>
11#include <memory>
12#include "test.hpp"
13
14namespace conditional_test {
15
16#define CONDITIONAL_FUNCTION(n) \
17struct t ## n {}; \
18struct f ## n \
19{ \
20 constexpr int operator()(t ## n) const \
21 { \
22 return n; \
23 } \
24};
25
26CONDITIONAL_FUNCTION(1)
27CONDITIONAL_FUNCTION(2)
28CONDITIONAL_FUNCTION(3)
29
30#define CONDITIONAL_MOVE_FUNCTION(n) \
31struct t_move ## n {}; \
32struct f_move ## n \
33{ \
34 std::unique_ptr<int> i;\
35 f_move ## n(int ip) : i(new int(ip)) {}; \
36 int operator()(t_move ## n) const \
37 { \
38 return *i; \
39 } \
40};
41
42CONDITIONAL_MOVE_FUNCTION(1)
43CONDITIONAL_MOVE_FUNCTION(2)
44CONDITIONAL_MOVE_FUNCTION(3)
45
46struct ff
47{
48 constexpr int operator()(t2) const
49 {
50 return 500;
51 }
52};
53
54static constexpr boost::hof::static_<boost::hof::first_of_adaptor<f1, f2, f3, ff> > f = {};
55
56BOOST_HOF_STATIC_FUNCTION(f_constexpr) = boost::hof::first_of_adaptor<f1, f2, f3, ff>();
57
58BOOST_HOF_TEST_CASE()
59{
60 BOOST_HOF_TEST_CHECK(f(t1()) == 1);
61 BOOST_HOF_TEST_CHECK(f(t2()) == 2);
62 BOOST_HOF_TEST_CHECK(f(t3()) == 3);
63
64 BOOST_HOF_STATIC_TEST_CHECK(f_constexpr(t1()) == 1);
65 BOOST_HOF_STATIC_TEST_CHECK(f_constexpr(t2()) == 2);
66 BOOST_HOF_STATIC_TEST_CHECK(f_constexpr(t3()) == 3);
67}
68
69BOOST_HOF_TEST_CASE()
70{
71 BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t1()) == 1);
72 BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t2()) == 2);
73
74 BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t1()) == 1);
75 BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t2()) == 2);
76}
77
78#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7)
79#else
80
81BOOST_HOF_TEST_CASE()
82{
83 BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t1()) == 1);
84 BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t2()) == 2);
85
86 BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t1()) == 1);
87 BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t2()) == 2);
88}
89
90BOOST_HOF_TEST_CASE()
91{
92 BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t1()) == 1);
93 BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t2()) == 2);
94 BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t3()) == 3);
95
96 BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t1()) == 1);
97 BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t2()) == 2);
98 BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t3()) == 3);
99}
100
101BOOST_HOF_TEST_CASE()
102{
103 BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t1()) == 1);
104 BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t2()) == 2);
105 BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t3()) == 3);
106
107 BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t1()) == 1);
108 BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t2()) == 2);
109 BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t3()) == 3);
110}
111
112#endif
113
114BOOST_HOF_TEST_CASE()
115{
116 auto f_move_local = boost::hof::first_of(f_move1(1), f_move2(2), f_move3(3));
117 STATIC_ASSERT_MOVE_ONLY(decltype(f_move_local));
118 BOOST_HOF_TEST_CHECK(f_move_local(t_move1()) == 1);
119 BOOST_HOF_TEST_CHECK(f_move_local(t_move2()) == 2);
120 BOOST_HOF_TEST_CHECK(f_move_local(t_move3()) == 3);
121}
122#ifndef _MSC_VER
123static constexpr auto lam = boost::hof::first_of(
124 BOOST_HOF_STATIC_LAMBDA(t1)
125 {
126 return 1;
127 },
128 BOOST_HOF_STATIC_LAMBDA(t2)
129 {
130 return 2;
131 },
132 BOOST_HOF_STATIC_LAMBDA(t3)
133 {
134 return 3;
135 }
136);
137
138BOOST_HOF_TEST_CASE()
139{
140 BOOST_HOF_TEST_CHECK(lam(t1()) == 1);
141 BOOST_HOF_TEST_CHECK(lam(t2()) == 2);
142 BOOST_HOF_TEST_CHECK(lam(t3()) == 3);
143}
144#endif
145
146BOOST_HOF_STATIC_LAMBDA_FUNCTION(static_fun) = boost::hof::first_of(
147 [](t1)
148 {
149 return 1;
150 },
151 [](t2)
152 {
153 return 2;
154 },
155 [](t3)
156 {
157 return 3;
158 }
159);
160
161BOOST_HOF_TEST_CASE()
162{
163 BOOST_HOF_TEST_CHECK(static_fun(t1()) == 1);
164 BOOST_HOF_TEST_CHECK(static_fun(t2()) == 2);
165 BOOST_HOF_TEST_CHECK(static_fun(t3()) == 3);
166}
167
168BOOST_HOF_TEST_CASE()
169{
170 BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::identity, boost::hof::identity)(3) == 3);
171}
172
173template<class T>
174struct throw_fo
175{
176 void operator()(T) const {}
177};
178
179template<class T>
180struct no_throw_fo
181{
182 void operator()(T) const noexcept {}
183};
184#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
185BOOST_HOF_TEST_CASE()
186{
187 typedef boost::hof::first_of_adaptor<throw_fo<t1>, no_throw_fo<t2>> fun;
188 auto g = fun{};
189 static_assert(noexcept(g(t2{})), "noexcept conditional");
190 static_assert(!noexcept(g(t1{})), "noexcept conditional");
191
192 static_assert(noexcept(fun{}(t2{})), "noexcept conditional");
193 static_assert(!noexcept(fun{}(t1{})), "noexcept conditional");
194}
195
196BOOST_HOF_TEST_CASE()
197{
198 typedef boost::hof::first_of_adaptor<no_throw_fo<t2>, throw_fo<t1>> fun;
199 auto g = fun{};
200 static_assert(noexcept(g(t2{})), "noexcept conditional");
201 static_assert(!noexcept(g(t1{})), "noexcept conditional");
202
203 static_assert(noexcept(fun{}(t2{})), "noexcept conditional");
204 static_assert(!noexcept(fun{}(t1{})), "noexcept conditional");
205}
206
207BOOST_HOF_TEST_CASE()
208{
209 static_assert(noexcept(boost::hof::first_of_adaptor<no_throw_fo<t2>, throw_fo<t1>>{}(t2{})), "noexcept conditional");
210 static_assert(!noexcept(boost::hof::first_of_adaptor<no_throw_fo<t2>, throw_fo<t1>>{}(t1{})), "noexcept conditional");
211
212 static_assert(noexcept(boost::hof::first_of(no_throw_fo<t2>{}, throw_fo<t1>{})(t2{})), "noexcept conditional");
213 static_assert(!noexcept(boost::hof::first_of(no_throw_fo<t2>{}, throw_fo<t1>{})(t1{})), "noexcept conditional");
214}
215#endif
216}
217

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