1 /*=============================================================================
2     Copyright (c) 2017 Paul Fultz II
3     if.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/if.hpp>
8 #include "test.hpp"
9 
10 #include <boost/hof/first_of.hpp>
11 #include <boost/hof/placeholders.hpp>
12 
13 
14 struct is_5
15 {
16     template<class T>
operator ()is_517     constexpr bool operator()(T i) const
18     {
19         return i == 5;
20     }
21 };
22 
23 struct is_not_5
24 {
25     template<class T>
operator ()is_not_526     constexpr bool operator()(T i) const
27     {
28         return i != 5;
29     }
30 };
31 
32 template<class F>
33 struct test_int
34 {
35     template<class T>
operator ()test_int36     constexpr bool operator()(T x) const
37     {
38         return boost::hof::first_of(
39             boost::hof::if_(std::is_integral<T>())(F()),
40             boost::hof::always(true)
41         )(x);
42     }
43 };
44 
BOOST_HOF_TEST_CASE()45 BOOST_HOF_TEST_CASE()
46 {
47     BOOST_HOF_TEST_CHECK(test_int<is_5>()(5));
48     BOOST_HOF_TEST_CHECK(test_int<is_5>()(5L));
49     BOOST_HOF_TEST_CHECK(test_int<is_5>()(5.0));
50     BOOST_HOF_TEST_CHECK(test_int<is_5>()(6.0));
51 
52     BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(6));
53     BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(6L));
54     BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(5.0));
55     BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(6.0));
56 
57     BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(5));
58     BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(5L));
59     BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(5.0));
60     BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(6.0));
61 
62     BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(6));
63     BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(6L));
64     BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(5.0));
65     BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(6.0));
66 }
67 
68 template<class F>
69 struct test_int_c
70 {
71     template<class T>
operator ()test_int_c72     constexpr bool operator()(T x) const
73     {
74         return boost::hof::first_of(
75             boost::hof::if_c<std::is_integral<T>::value>(F()),
76             boost::hof::always(true)
77         )(x);
78     }
79 };
80 
BOOST_HOF_TEST_CASE()81 BOOST_HOF_TEST_CASE()
82 {
83     BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(5));
84     BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(5L));
85     BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(5.0));
86     BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(6.0));
87 
88     BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(6));
89     BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(6L));
90     BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(5.0));
91     BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(6.0));
92 
93     BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(5));
94     BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(5L));
95     BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(5.0));
96     BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(6.0));
97 
98     BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(6));
99     BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(6L));
100     BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(5.0));
101     BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(6.0));
102 }
103 
104 struct sum_f
105 {
106     template<class T>
operator ()sum_f107     constexpr int operator()(T x, T y) const
108     {
109         return boost::hof::first_of(
110             boost::hof::if_(std::is_integral<T>())(boost::hof::_ + boost::hof::_),
111             boost::hof::always(0)
112         )(x, y);
113     }
114 };
115 
BOOST_HOF_TEST_CASE()116 BOOST_HOF_TEST_CASE()
117 {
118     BOOST_HOF_TEST_CHECK(sum_f()(1, 2) == 3);
119     BOOST_HOF_TEST_CHECK(sum_f()(1.0, 2.0) == 0);
120     BOOST_HOF_TEST_CHECK(sum_f()("", "") == 0);
121 
122     BOOST_HOF_STATIC_TEST_CHECK(sum_f()(1, 2) == 3);
123     BOOST_HOF_STATIC_TEST_CHECK(sum_f()("", "") == 0);
124 }
125 
126 
127 struct sum_f_c
128 {
129     template<class T>
operator ()sum_f_c130     constexpr int operator()(T x, T y) const
131     {
132         return boost::hof::first_of(
133             boost::hof::if_c<std::is_integral<T>::value>(boost::hof::_ + boost::hof::_),
134             boost::hof::always(0)
135         )(x, y);
136     }
137 };
138 
BOOST_HOF_TEST_CASE()139 BOOST_HOF_TEST_CASE()
140 {
141     BOOST_HOF_TEST_CHECK(sum_f_c()(1, 2) == 3);
142     BOOST_HOF_TEST_CHECK(sum_f_c()(1.0, 2.0) == 0);
143     BOOST_HOF_TEST_CHECK(sum_f_c()("", "") == 0);
144 
145     BOOST_HOF_STATIC_TEST_CHECK(sum_f_c()(1, 2) == 3);
146     BOOST_HOF_STATIC_TEST_CHECK(sum_f_c()("", "") == 0);
147 }
148 
149 #if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
BOOST_HOF_TEST_CASE()150 BOOST_HOF_TEST_CASE()
151 {
152     static_assert(noexcept(boost::hof::if_(std::is_integral<int>())(boost::hof::identity)(1)), "noexcept if");
153 }
154 #endif
155