• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2017 Paul Fultz II
3     test.hpp
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 #ifndef GUARD_TEST_H
8 #define GUARD_TEST_H
9 
10 #include <type_traits>
11 #include <tuple>
12 #include <iostream>
13 #include <functional>
14 #include <vector>
15 #include <memory>
16 #include <boost/hof/detail/forward.hpp>
17 
18 #ifndef BOOST_HOF_HAS_STATIC_TEST_CHECK
19 #if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) || defined(_MSC_VER)
20 #define BOOST_HOF_HAS_STATIC_TEST_CHECK 0
21 #else
22 #define BOOST_HOF_HAS_STATIC_TEST_CHECK 1
23 #endif
24 #endif
25 
26 
27 #define BOOST_HOF_PP_CAT(x, y) BOOST_HOF_PP_PRIMITIVE_CAT(x, y)
28 #define BOOST_HOF_PP_PRIMITIVE_CAT(x, y) x ## y
29 
30 namespace boost { namespace hof { namespace test {
31 
32 typedef std::function<void()> test_case;
33 static std::vector<test_case> test_cases;
34 
35 struct auto_register
36 {
auto_registerboost::hof::test::auto_register37     auto_register(test_case tc)
38     {
39         test_cases.push_back(tc);
40     }
41 };
42 
43 #define BOOST_HOF_DETAIL_TEST_CASE(name) \
44 struct name \
45 { void operator()() const; }; \
46 static boost::hof::test::auto_register BOOST_HOF_PP_CAT(name, _register) = boost::hof::test::auto_register(name()); \
47 void name::operator()() const
48 
49 template<class T>
50 T bare(const T&);
51 
52 template<class T>
unused(T &&)53 inline void unused(T&&) {}
54 
55 }}} // namespace boost::hof
56 
57 #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
58 #define BOOST_HOF_STATIC_AUTO constexpr auto
59 #else
60 #define BOOST_HOF_STATIC_AUTO const constexpr auto
61 #endif
62 
63 #define STATIC_ASSERT_SAME(...) static_assert(std::is_same<__VA_ARGS__>::value, "Types are not the same")
64 #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
65 #define STATIC_ASSERT_MOVE_ONLY(T)
66 #else
67 #define STATIC_ASSERT_MOVE_ONLY(T) static_assert(!std::is_copy_constructible<T>::value && std::is_move_constructible<T>::value, "Not movable")
68 #endif
69 #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
70 #define STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(T)
71 #else
72 #define STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(T) static_assert(!std::is_default_constructible<T>::value, "Default constructible")
73 #endif
74 #define STATIC_ASSERT_EMPTY(x) static_assert(std::is_empty<decltype(boost::hof::test::bare(x))>::value, "Not empty");
75 
76 
77 #define BOOST_HOF_TEST_CASE() BOOST_HOF_DETAIL_TEST_CASE(BOOST_HOF_PP_CAT(test_, __LINE__))
78 #define BOOST_HOF_STATIC_TEST_CASE() struct BOOST_HOF_PP_CAT(test_, __LINE__)
79 
80 #define BOOST_HOF_TEST_TEMPLATE(...) typedef std::integral_constant<int, sizeof(__VA_ARGS__)> BOOST_HOF_PP_CAT(test_template_, __LINE__)
81 
82 #define BOOST_HOF_TEST_CHECK(...) if (!(__VA_ARGS__)) std::cout << "***** FAILED *****: " << #__VA_ARGS__ << "@" << __FILE__ << ": " << __LINE__ << std::endl
83 #define BOOST_HOF_STRINGIZE(...) #__VA_ARGS__
84 
85 #if BOOST_HOF_HAS_STATIC_TEST_CHECK
86 #define BOOST_HOF_STATIC_TEST_CHECK(...) static_assert(__VA_ARGS__, BOOST_HOF_STRINGIZE(__VA_ARGS__))
87 #else
88 #define BOOST_HOF_STATIC_TEST_CHECK(...)
89 #endif
90 
91 #ifndef BOOST_HOF_HAS_CONSTEXPR_TUPLE
92 #define BOOST_HOF_HAS_CONSTEXPR_TUPLE BOOST_HOF_HAS_STD_14
93 #endif
94 
95 struct binary_class
96 {
97     template<class T, class U>
operator ()binary_class98     constexpr T operator()(T x, U y) const noexcept
99     {
100         return x+y;
101     }
102 
103 };
104 
105 struct mutable_class
106 {
107     template<class F>
108     struct result;
109 
110     template<class F, class T, class U>
111     struct result<F(T&, U)>
112     {
113         typedef T type;
114     };
115 
116     template<class T, class U>
operator ()mutable_class117     T operator()(T & x, U y) const
118     {
119         return x+=y;
120     }
121 
122 };
123 
124 struct unary_class
125 {
126     template<class T>
operator ()unary_class127     constexpr T&& operator()(T&& x) const noexcept
128     {
129         return boost::hof::forward<T>(x);
130     }
131 
132 };
133 
134 struct void_class
135 {
136     template<class T>
operator ()void_class137     void operator()(T) const
138     {
139     }
140 };
141 
142 struct mono_class
143 {
operator ()mono_class144     constexpr int operator()(int x) const
145     {
146         return x+1;
147     }
148 };
149 
150 struct tuple_class
151 {
152     // Note: Taking the tuple by value causes the compiler to ICE on gcc 4.7
153     // when called in a constexpr context.
154     template<class T>
operator ()tuple_class155     constexpr int operator()(const T& t) const
156     {
157         return std::get<0>(t) + 1;
158     }
159 };
160 
161 template<class R>
162 struct explicit_class
163 {
164     template<class T>
operator ()explicit_class165     R operator()(T x)
166     {
167         return static_cast<R>(x);
168     }
169 };
170 
171 struct move_class
172 {
173     std::unique_ptr<int> i;
move_classmove_class174     move_class() : i(new int(0))
175     {}
176 
177     template<class T, class U>
operator ()move_class178     constexpr T operator()(T x, U y) const
179     {
180         return x+y+*i;
181     }
182 };
183 
main()184 int main()
185 {
186     for(const auto& tc: boost::hof::test::test_cases) tc();
187     return 0;
188 }
189 
190 #endif
191