]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/poly_collection/test/test_utilities.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / poly_collection / test / test_utilities.hpp
1 /* Copyright 2016-2018 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
5 *
6 * See http://www.boost.org/libs/poly_collection for library home page.
7 */
8
9 #ifndef BOOST_POLY_COLLECTION_TEST_TEST_UTILITIES_HPP
10 #define BOOST_POLY_COLLECTION_TEST_TEST_UTILITIES_HPP
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
16 #include <array>
17 #include <boost/core/lightweight_test.hpp>
18 #include <boost/iterator/iterator_adaptor.hpp>
19 #include <boost/type_traits/has_equal_to.hpp>
20 #include <iterator>
21 #include <memory>
22 #include <type_traits>
23 #include <typeinfo>
24 #include <utility>
25
26 namespace test_utilities{
27
28 template<typename... Values>
29 void do_(Values...){}
30
31 template<typename Exception,typename F>
32 void check_throw_case(F f)
33 {
34 try{
35 (void)f();
36 BOOST_TEST(false);
37 }
38 catch(const Exception&){}
39 catch(...){BOOST_TEST(false);}
40 }
41
42 template<typename Exception,typename... Fs>
43 void check_throw(Fs... f)
44 {
45 do_((check_throw_case<Exception>(f),0)...);
46 }
47
48 template<typename F1,typename F2>
49 struct compose_class
50 {
51 F1 f1;
52 F2 f2;
53
54 compose_class(const F1& f1,const F2& f2):f1(f1),f2(f2){}
55
56 template<typename T,typename... Args>
57 auto operator()(T&& x,Args&&... args)
58 ->decltype(std::declval<F2>()(std::declval<F1>()(
59 std::forward<T>(x)),std::forward<Args>(args)...))
60 {
61 return f2(f1(std::forward<T>(x)),std::forward<Args>(args)...);
62 }
63 };
64
65 template<typename F1,typename F2>
66 compose_class<F1,F2> compose(F1 f1,F2 f2)
67 {
68 return {f1,f2};
69 }
70
71 template<typename F1,typename F2>
72 struct compose_all_class
73 {
74 F1 f1;
75 F2 f2;
76
77 compose_all_class(const F1& f1,const F2& f2):f1(f1),f2(f2){}
78
79 template<typename... Args>
80 auto operator()(Args&&... args)
81 ->decltype(std::declval<F2>()(std::declval<F1>()(
82 std::forward<Args>(args))...))
83 {
84 return f2(f1(std::forward<Args>(args))...);
85 }
86 };
87
88 template<typename F1,typename F2>
89 compose_all_class<F1,F2> compose_all(F1 f1,F2 f2)
90 {
91 return {f1,f2};
92 }
93
94 using std::is_default_constructible;
95
96 using std::is_copy_constructible;
97
98 template<typename T>
99 using is_not_copy_constructible=std::integral_constant<
100 bool,
101 !std::is_copy_constructible<T>::value
102 >;
103
104 template<typename T>
105 using is_constructible_from_int=std::is_constructible<T,int>;
106
107 using std::is_copy_assignable;
108
109 template<typename T>
110 using is_not_copy_assignable=std::integral_constant<
111 bool,
112 !std::is_copy_assignable<T>::value
113 >;
114
115 template<typename T>
116 using is_equality_comparable=std::integral_constant<
117 bool,
118 boost::has_equal_to<T,T,bool>::value
119 >;
120
121 template<typename T>
122 using is_not_equality_comparable=std::integral_constant<
123 bool,
124 !is_equality_comparable<T>::value
125 >;
126
127 template<
128 typename T,
129 typename std::enable_if<is_not_copy_constructible<T>::value>::type* =nullptr
130 >
131 typename std::remove_reference<T>::type&& constref_if_copy_constructible(T&& x)
132 {
133 return std::move(x);
134 }
135
136 template<
137 typename T,
138 typename std::enable_if<is_copy_constructible<T>::value>::type* =nullptr
139 >
140 const T& constref_if_copy_constructible(T&& x)
141 {
142 return x;
143 }
144
145 template<template<typename> class... Traits>
146 struct constraints;
147
148 template<>
149 struct constraints<>
150 {
151 template<typename T>
152 struct apply:std::true_type{};
153 };
154
155 template<
156 template <typename> class Trait,
157 template <typename> class... Traits
158 >
159 struct constraints<Trait,Traits...>
160 {
161 template<typename T>
162 struct apply:std::integral_constant<
163 bool,
164 Trait<T>::value&&constraints<Traits...>::template apply<T>::value
165 >{};
166 };
167
168 template<typename... Ts>struct type_list{};
169
170 template<
171 typename Constraints,template <typename...> class Template,
172 typename TypeList,
173 typename... Ts
174 >
175 struct instantiate_with_class;
176
177 template<
178 typename Constraints,template <typename...> class Template,
179 typename... Us
180 >
181 struct instantiate_with_class<Constraints,Template,type_list<Us...>>
182 {using type=Template<Us...>;};
183
184 template<
185 typename Constraints,template <typename...> class Template,
186 typename... Us,
187 typename T,typename... Ts
188 >
189 struct instantiate_with_class<
190 Constraints,Template,type_list<Us...>,T,Ts...
191 >:instantiate_with_class<
192 Constraints,Template,
193 typename std::conditional<
194 Constraints::template apply<T>::value,
195 type_list<Us...,T>,
196 type_list<Us...>
197 >::type,
198 Ts...
199 >{};
200
201 template<
202 typename Constraints,template <typename...> class Template,
203 typename... Ts
204 >
205 using instantiate_with=typename instantiate_with_class<
206 Constraints,Template,type_list<>,Ts...
207 >::type;
208
209 template<
210 template <typename...> class Template,typename... Ts
211 >
212 using only_eq_comparable=instantiate_with<
213 constraints<is_equality_comparable>,
214 Template, Ts...
215 >;
216
217 template<typename T> struct identity{using type=T;};
218
219 template<typename Constraints,typename... Ts>
220 struct first_of_class{};
221
222 template<typename Constraints,typename T,typename... Ts>
223 struct first_of_class<Constraints,T,Ts...>:std::conditional<
224 Constraints::template apply<T>::value,
225 identity<T>,
226 first_of_class<Constraints,Ts...>
227 >::type{};
228
229 template<typename Constraints,typename... Ts>
230 using first_of=typename first_of_class<Constraints,Ts...>::type;
231
232 template<
233 typename Constraints,typename... Ts,
234 typename PolyCollection,typename ValueFactory
235 >
236 void fill(PolyCollection& p,ValueFactory& v,int n)
237 {
238 for(int i=0;i<n;++i){
239 do_(
240 (Constraints::template apply<Ts>::value?
241 (p.insert(v.template make<Ts>()),0):0)...);
242 }
243 }
244
245 template<typename PolyCollection>
246 bool is_first(
247 const PolyCollection& p,typename PolyCollection::const_iterator it)
248 {
249 return it==p.begin();
250 }
251
252 template<typename PolyCollection,typename Iterator>
253 bool is_first(const PolyCollection& p,const std::type_info& info,Iterator it)
254 {
255 return &*it==&*p.begin(info);
256 }
257
258 template<typename PolyCollection,typename Iterator>
259 bool is_last(const PolyCollection& p,const std::type_info& info,Iterator it)
260 {
261 return &*it==&*(p.end(info)-1);
262 }
263
264 template<typename T,typename PolyCollection,typename Iterator>
265 bool is_first(const PolyCollection& p,Iterator it)
266 {
267 return &*it==&*p.template begin<T>();
268 }
269
270 template<typename T,typename PolyCollection,typename Iterator>
271 bool is_last(const PolyCollection& p,Iterator it)
272 {
273 return &*it==&*(p.template end<T>()-1);
274 }
275
276 template<typename Iterator>
277 struct external_iterator_class:
278 public boost::iterator_adaptor<external_iterator_class<Iterator>,Iterator>
279 {
280 external_iterator_class(const Iterator& it):
281 external_iterator_class::iterator_adaptor_{it}{}
282 };
283
284 template<typename Iterator>
285 external_iterator_class<Iterator> external_iterator(Iterator it)
286 {
287 return it;
288 }
289
290 template<typename Iterator>
291 struct unwrap_iterator_class:public boost::iterator_adaptor<
292 unwrap_iterator_class<Iterator>,
293 Iterator,
294 typename std::iterator_traits<Iterator>::value_type::type
295 >
296 {
297 unwrap_iterator_class(const Iterator& it):
298 unwrap_iterator_class::iterator_adaptor_{it}{}
299 };
300
301 template<typename Iterator>
302 unwrap_iterator_class<Iterator> unwrap_iterator(Iterator it)
303 {
304 return it;
305 }
306
307 struct auto_increment
308 {
309 template<typename T>
310 T make(){return T(n++);}
311
312 int n=0;
313 };
314
315 struct jammed_auto_increment
316 {
317 template<typename T>
318 T make(){return T(n++/7);}
319
320 int n=0;
321 };
322
323 template<
324 typename T,
325 typename Propagate=std::true_type,typename AlwaysEqual=std::true_type
326 >
327 struct rooted_allocator:std::allocator<T>
328 {
329 using propagate_on_container_copy_assignment=Propagate;
330 using propagate_on_container_move_assignment=Propagate;
331 using propagate_on_container_swap=Propagate;
332 using is_always_equal=AlwaysEqual; /* for C++17 forward compatibility */
333 template<typename U>
334 struct rebind{using other=rooted_allocator<U,Propagate,AlwaysEqual>;};
335
336 rooted_allocator():root{nullptr}{}
337 explicit rooted_allocator(int):root{this}{}
338 template<typename U>
339 rooted_allocator(const rooted_allocator<U,Propagate,AlwaysEqual>& x):
340 root{x.root}{}
341
342 template<typename U>
343 bool operator==(const rooted_allocator<U,Propagate,AlwaysEqual>& x)const
344 {return AlwaysEqual::value?true:root==x.root;}
345 template<typename U>
346 bool operator!=(const rooted_allocator<U,Propagate,AlwaysEqual>& x)const
347 {return AlwaysEqual::value?false:root!=x.root;}
348
349 template<typename U>
350 bool comes_from(const rooted_allocator<U,Propagate,AlwaysEqual>& x)const
351 {return root==&x;}
352
353 private:
354 template<typename,typename,typename> friend struct rooted_allocator;
355
356 const void* root;
357 };
358
359 template<
360 typename PolyCollection,
361 template<typename...> class Allocator,typename... Args
362 >
363 struct realloc_poly_collection_class;
364
365 template<
366 typename PolyCollection,
367 template<typename...> class Allocator,typename... Args
368 >
369 using realloc_poly_collection=typename realloc_poly_collection_class<
370 PolyCollection,Allocator,Args...>::type;
371
372 template<
373 template<typename,typename> class PolyCollection,
374 typename T,typename OriginalAllocator,
375 template<typename...> class Allocator,typename... Args
376 >
377 struct realloc_poly_collection_class<
378 PolyCollection<T,OriginalAllocator>,Allocator,Args...
379 >
380 {
381 using value_type=typename PolyCollection<T,OriginalAllocator>::value_type;
382 using type=PolyCollection<T,Allocator<value_type,Args...>>;
383 };
384
385 template<std::size_t N>
386 struct layout_data
387 {
388 std::array<const void*,N> datas;
389 std::array<std::size_t,N> sizes;
390
391 bool operator==(const layout_data& x)const
392 {
393 return datas==x.datas&&sizes==x.sizes;
394 }
395 };
396
397 template<typename... Types,typename PolyCollection>
398 layout_data<sizeof...(Types)> get_layout_data(const PolyCollection& p)
399 {
400 return{
401 {{(p.template is_registered<Types>()?
402 &*p.template begin<Types>():nullptr)...}},
403 {{(p.template is_registered<Types>()?
404 p.template size<Types>():0)...}}
405 };
406 }
407
408 } /* namespace test_utilities */
409
410 #endif