• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
14 namespace conditional_test {
15 
16 #define CONDITIONAL_FUNCTION(n) \
17 struct t ## n {}; \
18 struct f ## n \
19 { \
20     constexpr int operator()(t ## n) const \
21     { \
22         return n; \
23     } \
24 };
25 
26 CONDITIONAL_FUNCTION(1)
27 CONDITIONAL_FUNCTION(2)
28 CONDITIONAL_FUNCTION(3)
29 
30 #define CONDITIONAL_MOVE_FUNCTION(n) \
31 struct t_move ## n {}; \
32 struct 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 
42 CONDITIONAL_MOVE_FUNCTION(1)
43 CONDITIONAL_MOVE_FUNCTION(2)
44 CONDITIONAL_MOVE_FUNCTION(3)
45 
46 struct ff
47 {
operator ()conditional_test::ff48     constexpr int operator()(t2) const
49     {
50         return 500;
51     }
52 };
53 
54 static constexpr boost::hof::static_<boost::hof::first_of_adaptor<f1, f2, f3, ff> > f = {};
55 
56 BOOST_HOF_STATIC_FUNCTION(f_constexpr) = boost::hof::first_of_adaptor<f1, f2, f3, ff>();
57 
BOOST_HOF_TEST_CASE()58 BOOST_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 
BOOST_HOF_TEST_CASE()69 BOOST_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 
BOOST_HOF_TEST_CASE()81 BOOST_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 
BOOST_HOF_TEST_CASE()90 BOOST_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 
BOOST_HOF_TEST_CASE()101 BOOST_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 
BOOST_HOF_TEST_CASE()114 BOOST_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
123 static 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 
BOOST_HOF_TEST_CASE()138 BOOST_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 
146 BOOST_HOF_STATIC_LAMBDA_FUNCTION(static_fun) = boost::hof::first_of(
147     [](t1)
__anon19aeceda0102(t1) 148     {
149         return 1;
150     },
151     [](t2)
__anon19aeceda0202(t2) 152     {
153         return 2;
154     },
155     [](t3)
__anon19aeceda0302(t3) 156     {
157         return 3;
158     }
159 );
160 
BOOST_HOF_TEST_CASE()161 BOOST_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 
BOOST_HOF_TEST_CASE()168 BOOST_HOF_TEST_CASE()
169 {
170     BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::identity, boost::hof::identity)(3) == 3);
171 }
172 
173 template<class T>
174 struct throw_fo
175 {
operator ()conditional_test::throw_fo176     void operator()(T) const {}
177 };
178 
179 template<class T>
180 struct no_throw_fo
181 {
operator ()conditional_test::no_throw_fo182     void operator()(T) const noexcept {}
183 };
184 #if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
BOOST_HOF_TEST_CASE()185 BOOST_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 
BOOST_HOF_TEST_CASE()196 BOOST_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 
BOOST_HOF_TEST_CASE()207 BOOST_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