]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/test/functional/apply.cpp
1 // Copyright Louis Dionne 2013-2017
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
5 #include <boost/hana/assert.hpp>
6 #include <boost/hana/equal.hpp>
7 #include <boost/hana/functional/apply.hpp>
9 #include <laws/base.hpp>
10 #include <support/tracked.hpp>
12 #include <type_traits>
14 namespace hana
= boost::hana
;
18 struct nonpod
: Tracked
{
19 nonpod() : Tracked
{i
} { }
23 NonCopyable() = default;
24 NonCopyable(NonCopyable
const&) = delete;
25 NonCopyable
& operator=(NonCopyable
const&) = delete;
29 explicit TestClass(int x
) : data(x
) { }
30 TestClass(TestClass
const&) = delete;
31 TestClass
& operator=(TestClass
const&) = delete;
33 int& operator()(NonCopyable
&&) & { return data
; }
34 int const& operator()(NonCopyable
&&) const & { return data
; }
35 int volatile& operator()(NonCopyable
&&) volatile & { return data
; }
36 int const volatile& operator()(NonCopyable
&&) const volatile & { return data
; }
38 int&& operator()(NonCopyable
&&) && { return std::move(data
); }
39 int const&& operator()(NonCopyable
&&) const && { return std::move(data
); }
40 int volatile&& operator()(NonCopyable
&&) volatile && { return std::move(data
); }
41 int const volatile&& operator()(NonCopyable
&&) const volatile && { return std::move(data
); }
46 struct DerivedFromTestClass
: TestClass
{
47 explicit DerivedFromTestClass(int x
) : TestClass(x
) { }
51 template <typename Signature
, typename Expect
, typename Functor
>
52 void test_b12(Functor
&& f
) {
53 // Create the callable object.
54 using ClassFunc
= Signature
TestClass::*;
55 ClassFunc func_ptr
= &TestClass::operator();
57 // Create the dummy arg.
60 // Check that the deduced return type of invoke is what is expected.
61 using DeducedReturnType
= decltype(
62 hana::apply(func_ptr
, std::forward
<Functor
>(f
), std::move(arg
))
64 static_assert(std::is_same
<DeducedReturnType
, Expect
>::value
, "");
66 // Check that result_of_t matches Expect.
67 using ResultOfReturnType
= typename
std::result_of
<ClassFunc
&&(Functor
&&, NonCopyable
&&)>::type
;
68 static_assert(std::is_same
<ResultOfReturnType
, Expect
>::value
, "");
70 // Run invoke and check the return value.
71 DeducedReturnType ret
= hana::apply(func_ptr
, std::forward
<Functor
>(f
), std::move(arg
));
72 BOOST_HANA_RUNTIME_CHECK(ret
== 42);
75 template <typename Expect
, typename Functor
>
76 void test_b34(Functor
&& f
) {
77 // Create the callable object.
78 using ClassFunc
= int TestClass::*;
79 ClassFunc func_ptr
= &TestClass::data
;
81 // Check that the deduced return type of invoke is what is expected.
82 using DeducedReturnType
= decltype(
83 hana::apply(func_ptr
, std::forward
<Functor
>(f
))
85 static_assert(std::is_same
<DeducedReturnType
, Expect
>::value
, "");
87 // Check that result_of_t matches Expect.
88 using ResultOfReturnType
= typename
std::result_of
<ClassFunc
&&(Functor
&&)>::type
;
89 static_assert(std::is_same
<ResultOfReturnType
, Expect
>::value
, "");
91 // Run invoke and check the return value.
92 DeducedReturnType ret
= hana::apply(func_ptr
, std::forward
<Functor
>(f
));
93 BOOST_HANA_RUNTIME_CHECK(ret
== 42);
96 template <typename Expect
, typename Functor
>
97 void test_b5(Functor
&& f
) {
100 // Check that the deduced return type of invoke is what is expected.
101 using DeducedReturnType
= decltype(
102 hana::apply(std::forward
<Functor
>(f
), std::move(arg
))
104 static_assert(std::is_same
<DeducedReturnType
, Expect
>::value
, "");
106 // Check that result_of_t matches Expect.
107 using ResultOfReturnType
= typename
std::result_of
<Functor
&&(NonCopyable
&&)>::type
;
108 static_assert(std::is_same
<ResultOfReturnType
, Expect
>::value
, "");
110 // Run invoke and check the return value.
111 DeducedReturnType ret
= hana::apply(std::forward
<Functor
>(f
), std::move(arg
));
112 BOOST_HANA_RUNTIME_CHECK(ret
== 42);
115 int& foo(NonCopyable
&&) {
116 static int data
= 42;
121 // Test normal usage with a function object
123 hana::test::_injection
<0> f
{};
124 using hana::test::ct_eq
;
126 BOOST_HANA_CONSTANT_CHECK(hana::equal(
130 BOOST_HANA_CONSTANT_CHECK(hana::equal(
131 hana::apply(f
, ct_eq
<0>{}),
134 BOOST_HANA_CONSTANT_CHECK(hana::equal(
135 hana::apply(f
, ct_eq
<0>{}, ct_eq
<1>{}),
136 f(ct_eq
<0>{}, ct_eq
<1>{})
138 BOOST_HANA_CONSTANT_CHECK(hana::equal(
139 hana::apply(f
, ct_eq
<0>{}, ct_eq
<1>{}, ct_eq
<2>{}),
140 f(ct_eq
<0>{}, ct_eq
<1>{}, ct_eq
<2>{})
142 BOOST_HANA_CONSTANT_CHECK(hana::equal(
143 hana::apply(f
, ct_eq
<0>{}, ct_eq
<1>{}, ct_eq
<2>{}, ct_eq
<3>{}),
144 f(ct_eq
<0>{}, ct_eq
<1>{}, ct_eq
<2>{}, ct_eq
<3>{})
147 // Make sure we can use apply with non-PODs
148 hana::apply(f
, nonpod
<>{});
151 // Bullets 1 & 2 in the standard
154 test_b12
<int&(NonCopyable
&&) &, int&>(cl
);
155 test_b12
<int const&(NonCopyable
&&) const &, int const&>(cl
);
156 test_b12
<int volatile&(NonCopyable
&&) volatile &, int volatile&>(cl
);
157 test_b12
<int const volatile&(NonCopyable
&&) const volatile &, int const volatile&>(cl
);
159 test_b12
<int&&(NonCopyable
&&) &&, int&&>(std::move(cl
));
160 test_b12
<int const&&(NonCopyable
&&) const &&, int const&&>(std::move(cl
));
161 test_b12
<int volatile&&(NonCopyable
&&) volatile &&, int volatile&&>(std::move(cl
));
162 test_b12
<int const volatile&&(NonCopyable
&&) const volatile &&, int const volatile&&>(std::move(cl
));
165 DerivedFromTestClass
cl(42);
166 test_b12
<int&(NonCopyable
&&) &, int&>(cl
);
167 test_b12
<int const&(NonCopyable
&&) const &, int const&>(cl
);
168 test_b12
<int volatile&(NonCopyable
&&) volatile &, int volatile&>(cl
);
169 test_b12
<int const volatile&(NonCopyable
&&) const volatile &, int const volatile&>(cl
);
171 test_b12
<int&&(NonCopyable
&&) &&, int&&>(std::move(cl
));
172 test_b12
<int const&&(NonCopyable
&&) const &&, int const&&>(std::move(cl
));
173 test_b12
<int volatile&&(NonCopyable
&&) volatile &&, int volatile&&>(std::move(cl
));
174 test_b12
<int const volatile&&(NonCopyable
&&) const volatile &&, int const volatile&&>(std::move(cl
));
177 TestClass
cl_obj(42);
178 TestClass
*cl
= &cl_obj
;
179 test_b12
<int&(NonCopyable
&&) &, int&>(cl
);
180 test_b12
<int const&(NonCopyable
&&) const &, int const&>(cl
);
181 test_b12
<int volatile&(NonCopyable
&&) volatile &, int volatile&>(cl
);
182 test_b12
<int const volatile&(NonCopyable
&&) const volatile &, int const volatile&>(cl
);
185 DerivedFromTestClass
cl_obj(42);
186 DerivedFromTestClass
*cl
= &cl_obj
;
187 test_b12
<int&(NonCopyable
&&) &, int&>(cl
);
188 test_b12
<int const&(NonCopyable
&&) const &, int const&>(cl
);
189 test_b12
<int volatile&(NonCopyable
&&) volatile &, int volatile&>(cl
);
190 test_b12
<int const volatile&(NonCopyable
&&) const volatile &, int const volatile&>(cl
);
193 // Bullets 3 & 4 in the standard
195 using Fn
= TestClass
;
198 test_b34
<int const&>(static_cast<Fn
const&>(cl
));
199 test_b34
<int volatile&>(static_cast<Fn
volatile&>(cl
));
200 test_b34
<int const volatile&>(static_cast<Fn
const volatile &>(cl
));
202 test_b34
<int&&>(static_cast<Fn
&&>(cl
));
203 test_b34
<int const&&>(static_cast<Fn
const&&>(cl
));
204 test_b34
<int volatile&&>(static_cast<Fn
volatile&&>(cl
));
205 test_b34
<int const volatile&&>(static_cast<Fn
const volatile&&>(cl
));
208 using Fn
= DerivedFromTestClass
;
211 test_b34
<int const&>(static_cast<Fn
const&>(cl
));
212 test_b34
<int volatile&>(static_cast<Fn
volatile&>(cl
));
213 test_b34
<int const volatile&>(static_cast<Fn
const volatile &>(cl
));
215 test_b34
<int&&>(static_cast<Fn
&&>(cl
));
216 test_b34
<int const&&>(static_cast<Fn
const&&>(cl
));
217 test_b34
<int volatile&&>(static_cast<Fn
volatile&&>(cl
));
218 test_b34
<int const volatile&&>(static_cast<Fn
const volatile&&>(cl
));
221 using Fn
= TestClass
;
225 test_b34
<int const&>(static_cast<Fn
const*>(cl
));
226 test_b34
<int volatile&>(static_cast<Fn
volatile*>(cl
));
227 test_b34
<int const volatile&>(static_cast<Fn
const volatile *>(cl
));
230 using Fn
= DerivedFromTestClass
;
234 test_b34
<int const&>(static_cast<Fn
const*>(cl
));
235 test_b34
<int volatile&>(static_cast<Fn
volatile*>(cl
));
236 test_b34
<int const volatile&>(static_cast<Fn
const volatile *>(cl
));
239 // Bullet 5 in the standard
240 using FooType
= int&(NonCopyable
&&);
250 using Fn
= TestClass
;
253 test_b5
<int const&>(static_cast<Fn
const&>(cl
));
254 test_b5
<int volatile&>(static_cast<Fn
volatile&>(cl
));
255 test_b5
<int const volatile&>(static_cast<Fn
const volatile &>(cl
));
257 test_b5
<int&&>(static_cast<Fn
&&>(cl
));
258 test_b5
<int const&&>(static_cast<Fn
const&&>(cl
));
259 test_b5
<int volatile&&>(static_cast<Fn
volatile&&>(cl
));
260 test_b5
<int const volatile&&>(static_cast<Fn
const volatile&&>(cl
));