test_utilities.hpp 9.5 KB

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