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
30namespace boost { namespace hof { namespace test {
31
32typedef std::function<void()> test_case;
33static std::vector<test_case> test_cases;
34
35struct auto_register
36{
37 auto_register(test_case tc)
38 {
39 test_cases.push_back(x: tc);
40 }
41};
42
43#define BOOST_HOF_DETAIL_TEST_CASE(name) \
44struct name \
45{ void operator()() const; }; \
46static boost::hof::test::auto_register BOOST_HOF_PP_CAT(name, _register) = boost::hof::test::auto_register(name()); \
47void name::operator()() const
48
49template<class T>
50T bare(const T&);
51
52template<class T>
53inline 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
95struct binary_class
96{
97 template<class T, class U>
98 constexpr T operator()(T x, U y) const noexcept
99 {
100 return x+y;
101 }
102
103};
104
105struct 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>
117 T operator()(T & x, U y) const
118 {
119 return x+=y;
120 }
121
122};
123
124struct unary_class
125{
126 template<class T>
127 constexpr T&& operator()(T&& x) const noexcept
128 {
129 return boost::hof::forward<T>(x);
130 }
131
132};
133
134struct void_class
135{
136 template<class T>
137 void operator()(T) const
138 {
139 }
140};
141
142struct mono_class
143{
144 constexpr int operator()(int x) const
145 {
146 return x+1;
147 }
148};
149
150struct 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>
155 constexpr int operator()(const T& t) const
156 {
157 return std::get<0>(t) + 1;
158 }
159};
160
161template<class R>
162struct explicit_class
163{
164 template<class T>
165 R operator()(T x)
166 {
167 return static_cast<R>(x);
168 }
169};
170
171struct move_class
172{
173 std::unique_ptr<int> i;
174 move_class() : i(new int(0))
175 {}
176
177 template<class T, class U>
178 constexpr T operator()(T x, U y) const
179 {
180 return x+y+*i;
181 }
182};
183
184int main()
185{
186 for(const auto& tc: boost::hof::test::test_cases) tc();
187 return 0;
188}
189
190#endif
191

source code of boost/libs/hof/test/test.hpp