]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/poly_collection/test/test_utilities.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / libs / poly_collection / test / test_utilities.hpp
CommitLineData
11fdf7f2 1/* Copyright 2016-2018 Joaquin M Lopez Munoz.
b32b8144
FG
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
26namespace test_utilities{
27
28template<typename... Values>
29void do_(Values...){}
30
31template<typename Exception,typename F>
32void 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
42template<typename Exception,typename... Fs>
43void check_throw(Fs... f)
44{
45 do_((check_throw_case<Exception>(f),0)...);
46}
47
48template<typename F1,typename F2>
49struct 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
65template<typename F1,typename F2>
66compose_class<F1,F2> compose(F1 f1,F2 f2)
67{
68 return {f1,f2};
69}
70
71template<typename F1,typename F2>
72struct 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
88template<typename F1,typename F2>
89compose_all_class<F1,F2> compose_all(F1 f1,F2 f2)
90{
91 return {f1,f2};
92}
93
94using std::is_default_constructible;
95
96using std::is_copy_constructible;
97
98template<typename T>
99using is_not_copy_constructible=std::integral_constant<
100 bool,
101 !std::is_copy_constructible<T>::value
102>;
103
104template<typename T>
105using is_constructible_from_int=std::is_constructible<T,int>;
106
107using std::is_copy_assignable;
108
109template<typename T>
110using is_not_copy_assignable=std::integral_constant<
111 bool,
112 !std::is_copy_assignable<T>::value
113>;
114
115template<typename T>
116using is_equality_comparable=std::integral_constant<
117 bool,
11fdf7f2 118 boost::has_equal_to<T,T,bool>::value
b32b8144
FG
119>;
120
121template<typename T>
122using is_not_equality_comparable=std::integral_constant<
123 bool,
124 !is_equality_comparable<T>::value
125>;
126
127template<
128 typename T,
129 typename std::enable_if<is_not_copy_constructible<T>::value>::type* =nullptr
130>
131typename std::remove_reference<T>::type&& constref_if_copy_constructible(T&& x)
132{
133 return std::move(x);
134}
135
136template<
137 typename T,
138 typename std::enable_if<is_copy_constructible<T>::value>::type* =nullptr
139>
140const T& constref_if_copy_constructible(T&& x)
141{
142 return x;
143}
144
145template<template<typename> class... Traits>
146struct constraints;
147
148template<>
149struct constraints<>
150{
151 template<typename T>
152 struct apply:std::true_type{};
153};
154
155template<
156 template <typename> class Trait,
157 template <typename> class... Traits
158>
159struct 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
168template<typename... Ts>struct type_list{};
169
170template<
171 typename Constraints,template <typename...> class Template,
172 typename TypeList,
173 typename... Ts
174>
175struct instantiate_with_class;
176
177template<
178 typename Constraints,template <typename...> class Template,
179 typename... Us
180>
181struct instantiate_with_class<Constraints,Template,type_list<Us...>>
182{using type=Template<Us...>;};
183
184template<
185 typename Constraints,template <typename...> class Template,
186 typename... Us,
187 typename T,typename... Ts
188>
189struct 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
201template<
202 typename Constraints,template <typename...> class Template,
203 typename... Ts
204>
205using instantiate_with=typename instantiate_with_class<
206 Constraints,Template,type_list<>,Ts...
207>::type;
208
209template<
210 template <typename...> class Template,typename... Ts
211>
212using only_eq_comparable=instantiate_with<
213 constraints<is_equality_comparable>,
214 Template, Ts...
215>;
216
217template<typename T> struct identity{using type=T;};
218
219template<typename Constraints,typename... Ts>
220struct first_of_class{};
221
222template<typename Constraints,typename T,typename... Ts>
223struct 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
229template<typename Constraints,typename... Ts>
230using first_of=typename first_of_class<Constraints,Ts...>::type;
231
232template<
233 typename Constraints,typename... Ts,
234 typename PolyCollection,typename ValueFactory
235>
236void 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
245template<typename PolyCollection>
246bool is_first(
247 const PolyCollection& p,typename PolyCollection::const_iterator it)
248{
249 return it==p.begin();
250}
251
252template<typename PolyCollection,typename Iterator>
253bool is_first(const PolyCollection& p,const std::type_info& info,Iterator it)
254{
255 return &*it==&*p.begin(info);
256}
257
258template<typename PolyCollection,typename Iterator>
259bool is_last(const PolyCollection& p,const std::type_info& info,Iterator it)
260{
261 return &*it==&*(p.end(info)-1);
262}
263
264template<typename T,typename PolyCollection,typename Iterator>
265bool is_first(const PolyCollection& p,Iterator it)
266{
267 return &*it==&*p.template begin<T>();
268}
269
270template<typename T,typename PolyCollection,typename Iterator>
271bool is_last(const PolyCollection& p,Iterator it)
272{
273 return &*it==&*(p.template end<T>()-1);
274}
275
276template<typename Iterator>
277struct 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
284template<typename Iterator>
285external_iterator_class<Iterator> external_iterator(Iterator it)
286{
287 return it;
288}
289
290template<typename Iterator>
291struct 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
301template<typename Iterator>
302unwrap_iterator_class<Iterator> unwrap_iterator(Iterator it)
303{
304 return it;
305}
306
307struct auto_increment
308{
309 template<typename T>
310 T make(){return T(n++);}
311
312 int n=0;
313};
314
315struct jammed_auto_increment
316{
317 template<typename T>
318 T make(){return T(n++/10);}
319
320 int n=0;
321};
322
323template<typename T>
324struct rooted_allocator:std::allocator<T>
325{
326 using propagate_on_container_copy_assignment=std::false_type;
327 using propagate_on_container_move_assignment=std::true_type;
328 using propagate_on_container_swap=std::false_type;
329 template<typename U>
330 struct rebind{using other=rooted_allocator<U>;};
331
332 rooted_allocator()=default;
333 explicit rooted_allocator(int):root{this}{}
334 template<typename U>
335 rooted_allocator(const rooted_allocator<U>& x):root{x.root}{}
336
337 const void* root;
338};
339
340template<typename PolyCollection,template<typename> class Allocator>
341struct realloc_poly_collection_class;
342
343template<typename PolyCollection,template<typename> class Allocator>
344using realloc_poly_collection=
345 typename realloc_poly_collection_class<PolyCollection,Allocator>::type;
346
347template<
348 template<typename,typename> class PolyCollection,
349 typename T,typename OriginalAllocator,
350 template<typename> class Allocator
351>
352struct realloc_poly_collection_class<
353 PolyCollection<T,OriginalAllocator>,Allocator
354>
355{
356 using value_type=typename PolyCollection<T,OriginalAllocator>::value_type;
357 using type=PolyCollection<T,Allocator<value_type>>;
358};
359
360template<std::size_t N>
361struct layout_data
362{
363 std::array<const void*,N> datas;
364 std::array<std::size_t,N> sizes;
365
366 bool operator==(const layout_data& x)const
367 {
368 return datas==x.datas&&sizes==x.sizes;
369 }
370};
371
372template<typename... Types,typename PolyCollection>
373layout_data<sizeof...(Types)> get_layout_data(const PolyCollection& p)
374{
375 return{
376 {{(p.template is_registered<Types>()?
377 &*p.template begin<Types>():nullptr)...}},
378 {{(p.template is_registered<Types>()?
379 p.template size<Types>():0)...}}
380 };
381}
382
383} /* namespace test_utilities */
384
385#endif