/* Copyright 2016-2018 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/poly_collection for library home page. */ #ifndef BOOST_POLY_COLLECTION_TEST_TEST_UTILITIES_HPP #define BOOST_POLY_COLLECTION_TEST_TEST_UTILITIES_HPP #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include #include namespace test_utilities{ template void do_(Values...){} template void check_throw_case(F f) { try{ (void)f(); BOOST_TEST(false); } catch(const Exception&){} catch(...){BOOST_TEST(false);} } template void check_throw(Fs... f) { do_((check_throw_case(f),0)...); } template struct compose_class { F1 f1; F2 f2; compose_class(const F1& f1,const F2& f2):f1(f1),f2(f2){} template auto operator()(T&& x,Args&&... args) ->decltype(std::declval()(std::declval()( std::forward(x)),std::forward(args)...)) { return f2(f1(std::forward(x)),std::forward(args)...); } }; template compose_class compose(F1 f1,F2 f2) { return {f1,f2}; } template struct compose_all_class { F1 f1; F2 f2; compose_all_class(const F1& f1,const F2& f2):f1(f1),f2(f2){} template auto operator()(Args&&... args) ->decltype(std::declval()(std::declval()( std::forward(args))...)) { return f2(f1(std::forward(args))...); } }; template compose_all_class compose_all(F1 f1,F2 f2) { return {f1,f2}; } using std::is_default_constructible; using std::is_copy_constructible; template using is_not_copy_constructible=std::integral_constant< bool, !std::is_copy_constructible::value >; template using is_constructible_from_int=std::is_constructible; using std::is_copy_assignable; template using is_not_copy_assignable=std::integral_constant< bool, !std::is_copy_assignable::value >; template using is_equality_comparable=std::integral_constant< bool, boost::has_equal_to::value >; template using is_not_equality_comparable=std::integral_constant< bool, !is_equality_comparable::value >; template< typename T, typename std::enable_if::value>::type* =nullptr > typename std::remove_reference::type&& constref_if_copy_constructible(T&& x) { return std::move(x); } template< typename T, typename std::enable_if::value>::type* =nullptr > const T& constref_if_copy_constructible(T&& x) { return x; } template class... Traits> struct constraints; template<> struct constraints<> { template struct apply:std::true_type{}; }; template< template class Trait, template class... Traits > struct constraints { template struct apply:std::integral_constant< bool, Trait::value&&constraints::template apply::value >{}; }; templatestruct type_list{}; template< typename Constraints,template class Template, typename TypeList, typename... Ts > struct instantiate_with_class; template< typename Constraints,template class Template, typename... Us > struct instantiate_with_class> {using type=Template;}; template< typename Constraints,template class Template, typename... Us, typename T,typename... Ts > struct instantiate_with_class< Constraints,Template,type_list,T,Ts... >:instantiate_with_class< Constraints,Template, typename std::conditional< Constraints::template apply::value, type_list, type_list >::type, Ts... >{}; template< typename Constraints,template class Template, typename... Ts > using instantiate_with=typename instantiate_with_class< Constraints,Template,type_list<>,Ts... >::type; template< template class Template,typename... Ts > using only_eq_comparable=instantiate_with< constraints, Template, Ts... >; template struct identity{using type=T;}; template struct first_of_class{}; template struct first_of_class:std::conditional< Constraints::template apply::value, identity, first_of_class >::type{}; template using first_of=typename first_of_class::type; template< typename Constraints,typename... Ts, typename PolyCollection,typename ValueFactory > void fill(PolyCollection& p,ValueFactory& v,int n) { for(int i=0;i::value? (p.insert(v.template make()),0):0)...); } } template bool is_first( const PolyCollection& p,typename PolyCollection::const_iterator it) { return it==p.begin(); } template bool is_first(const PolyCollection& p,const std::type_info& info,Iterator it) { return &*it==&*p.begin(info); } template bool is_last(const PolyCollection& p,const std::type_info& info,Iterator it) { return &*it==&*(p.end(info)-1); } template bool is_first(const PolyCollection& p,Iterator it) { return &*it==&*p.template begin(); } template bool is_last(const PolyCollection& p,Iterator it) { return &*it==&*(p.template end()-1); } template struct external_iterator_class: public boost::iterator_adaptor,Iterator> { external_iterator_class(const Iterator& it): external_iterator_class::iterator_adaptor_{it}{} }; template external_iterator_class external_iterator(Iterator it) { return it; } template struct unwrap_iterator_class:public boost::iterator_adaptor< unwrap_iterator_class, Iterator, typename std::iterator_traits::value_type::type > { unwrap_iterator_class(const Iterator& it): unwrap_iterator_class::iterator_adaptor_{it}{} }; template unwrap_iterator_class unwrap_iterator(Iterator it) { return it; } struct auto_increment { template T make(){return T(n++);} int n=0; }; struct jammed_auto_increment { template T make(){return T(n++/7);} int n=0; }; template< typename T, typename Propagate=std::true_type,typename AlwaysEqual=std::true_type > struct rooted_allocator:std::allocator { using propagate_on_container_copy_assignment=Propagate; using propagate_on_container_move_assignment=Propagate; using propagate_on_container_swap=Propagate; using is_always_equal=AlwaysEqual; /* for C++17 forward compatibility */ template struct rebind{using other=rooted_allocator;}; rooted_allocator():root{nullptr}{} explicit rooted_allocator(int):root{this}{} template rooted_allocator(const rooted_allocator& x): root{x.root}{} template bool operator==(const rooted_allocator& x)const {return AlwaysEqual::value?true:root==x.root;} template bool operator!=(const rooted_allocator& x)const {return AlwaysEqual::value?false:root!=x.root;} template bool comes_from(const rooted_allocator& x)const {return root==&x;} private: template friend struct rooted_allocator; const void* root; }; template< typename PolyCollection, template class Allocator,typename... Args > struct realloc_poly_collection_class; template< typename PolyCollection, template class Allocator,typename... Args > using realloc_poly_collection=typename realloc_poly_collection_class< PolyCollection,Allocator,Args...>::type; template< template class PolyCollection, typename T,typename OriginalAllocator, template class Allocator,typename... Args > struct realloc_poly_collection_class< PolyCollection,Allocator,Args... > { using value_type=typename PolyCollection::value_type; using type=PolyCollection>; }; template struct layout_data { std::array datas; std::array sizes; bool operator==(const layout_data& x)const { return datas==x.datas&&sizes==x.sizes; } }; template layout_data get_layout_data(const PolyCollection& p) { return{ {{(p.template is_registered()? &*p.template begin():nullptr)...}}, {{(p.template is_registered()? p.template size():0)...}} }; } } /* namespace test_utilities */ #endif