/* Copyright 2016-2024 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. */ #include "test_insertion.hpp" #include #include #include #include #include #include "any_types.hpp" #include "base_types.hpp" #include "function_types.hpp" #include "variant_types.hpp" #include "test_utilities.hpp" #if !defined(BOOST_NO_CXX17_HDR_VARIANT) #include #endif using namespace test_utilities; template< typename PolyCollection,typename ValueFactory,typename... Types, typename std::enable_if< !is_closed_collection::value>::type* =nullptr > void test_insertion_throw() { { using unregistered_type=boost::poly_collection::unregistered_type; using type=first_of,Types...>; PolyCollection p,p2; ValueFactory v; p2.insert(v.template make()); check_throw( [&]{p.insert(*p2.begin());}, [&]{p.insert(p.end(),*p2.begin());}, [&]{p.insert(p.cend(),*p2.begin());}, [&]{p.insert( external_iterator(p2.begin()),external_iterator(p2.end()));}, [&]{p.insert( p.end(), external_iterator(p2.begin()),external_iterator(p2.end()));}, [&]{p.insert( p.cend(), external_iterator(p2.begin()),external_iterator(p2.end()));}); } { using not_copy_constructible= boost::poly_collection::not_copy_constructible; using type=first_of,Types...>; PolyCollection p,p2; ValueFactory v; register_types(p); p2.insert(v.template make()); auto p2b=external_iterator(p2.begin()), p2e=external_iterator(p2.end()); auto p2lb=external_iterator(p2.template begin()), p2le=external_iterator(p2.template end()); check_throw( [&]{p.insert(*p2.begin());}, [&]{p.insert(p.end(),*p2.begin());}, [&]{p.insert(p.cend(),*p2.cbegin());}, [&]{p.insert(p.end(typeid_(p)),*p2.begin());}, [&]{p.insert(p.cend(typeid_(p)),*p2.begin());}, [&]{p.insert(p.template end(),*p2.begin());}, [&]{p.insert(p.template cend(),*p2.begin());}, [&]{p.insert(p2b,p2e);}, [&]{p.insert(p2lb,p2le);}, [&]{p.insert(p2.begin(),p2.end());}, [&]{p.insert(p2.begin(typeid_(p)),p2.end(typeid_(p)));}, [&]{p.insert(p2.template begin(),p2.template end());}, [&]{p.insert(p.end(),p2b,p2e);}, [&]{p.insert(p.end(),p2lb,p2le);}, [&]{p.insert(p.end(),p2.begin(),p2.end());}, [&]{p.insert( p.end(),p2.begin(typeid_(p)),p2.end(typeid_(p)));}, [&]{p.insert( p.end(),p2.template begin(),p2.template end());}, [&]{p.insert(p.cend(),p2b,p2e);}, [&]{p.insert(p.cend(),p2lb,p2le);}, [&]{p.insert(p.cend(),p2.begin(),p2.end());}, [&]{p.insert( p.cend(),p2.begin(typeid_(p)),p2.end(typeid_(p)));}, [&]{p.insert( p.cend(),p2.template begin(),p2.template end());}, [&]{p.insert(p.end(typeid_(p)),p2b,p2e);}, [&]{p.insert(p.cend(typeid_(p)),p2b,p2e);}, [&]{p.insert(p.template end(),p2b,p2e);}, [&]{p.insert(p.template cend(),p2b,p2e);}); } } template< typename PolyCollection,typename ValueFactory,typename... Types, typename std::enable_if< is_closed_collection::value>::type* =nullptr > void test_insertion_throw() { } template void test_insertion() { test_insertion_throw(); { PolyCollection p; ValueFactory v; fill,Types...>(p,v,2); do_((BOOST_TEST( is_last( p,typeid_(p), p.insert(constref_if_copy_constructible(v.template make()))) ),0)...); } { PolyCollection p; ValueFactory v; fill,Types...>(p,v,2); auto& info=p.segment_traversal().begin()->type_info(); do_((BOOST_TEST( info==typeid_(p)? is_first( p,typeid_(p), p.insert( p.cbegin(), constref_if_copy_constructible(v.template make()))): is_last( p,typeid_(p), p.insert( p.cbegin(), constref_if_copy_constructible(v.template make()))) ),0)...); do_((BOOST_TEST( is_first( p,typeid_(p), p.insert( p.cbegin(typeid_(p)), constref_if_copy_constructible(v.template make()))) ),0)...); do_((BOOST_TEST( is_first( p, p.insert( p.template cbegin(), constref_if_copy_constructible(v.template make()))) ),0)...); } { PolyCollection p,p2; ValueFactory v; register_types(p); register_types(p2); fill< constraints, Types... >(p2,v,2); p.insert(external_iterator(p2.begin()),external_iterator(p2.end())); BOOST_TEST(p==p2); p.clear(); p.insert(p2.begin(),p2.end()); BOOST_TEST(p==p2); p.clear(); p.insert(p2.cbegin(),p2.cend()); BOOST_TEST(p==p2); p.clear(); for(auto s:p2.segment_traversal()){ p.insert(s.begin(),s.end()); BOOST_TEST(p.size()==p2.size(s.type_info())); p.clear(); p.insert(s.cbegin(),s.cend()); BOOST_TEST(p.size()==p2.size(s.type_info())); p.clear(); } do_(( p.insert( external_iterator(p2.template begin()), external_iterator(p2.template end())), BOOST_TEST(p.size()==p2.template size()), p.clear() ,0)...); do_(( p.insert(p2.template begin(),p2.template end()), BOOST_TEST(p.size()==p2.template size()), p.clear() ,0)...); do_(( p.insert(p2.template cbegin(),p2.template cend()), BOOST_TEST(p.size()==p2.template size()), p.clear() ,0)...); } { PolyCollection p,p1,p2; ValueFactory v; register_types(p2); fill< constraints, Types... >(p1,v,2); fill< constraints, Types... >(p2,v,2); auto remove_original=[](PolyCollection& p) { bool first=true; for(auto s:p.segment_traversal()){ if(s.begin()!=s.end()){ if(first)p.erase(s.end()-2,s.end()),first=false; else p.erase(s.begin(),s.begin()+2); } } }; p=p1; p.insert( p.begin(),external_iterator(p2.begin()),external_iterator(p2.end())); remove_original(p); BOOST_TEST(p==p2); p=p1; p.insert(p.begin(),p2.begin(),p2.end()); remove_original(p); BOOST_TEST(p==p2); p=p1; p.insert(p.begin(),p2.cbegin(),p2.cend()); remove_original(p); BOOST_TEST(p==p2); p=p1; for(auto s:p2.segment_traversal())p.insert(p.begin(),s.begin(),s.end()); remove_original(p); BOOST_TEST(p==p2); p=p1; for(auto s:p2.segment_traversal())p.insert(p.begin(),s.cbegin(),s.cend()); remove_original(p); BOOST_TEST(p==p2); p=p1; do_((p.insert( p.begin(), external_iterator(p2.template begin()), external_iterator(p2.template end())),0)...); remove_original(p); BOOST_TEST(p==p2); p=p1; do_((p.insert( p.begin(),p2.template begin(),p2.template end()),0)...); remove_original(p); BOOST_TEST(p==p2); p=p1; do_((p.insert( p.begin(),p2.template cbegin(),p2.template cend()),0)...); remove_original(p); BOOST_TEST(p==p2); } { using type=first_of< constraints, Types... >; PolyCollection p,p1,p2; ValueFactory v; fill,type>(p1,v,2); fill,type>(p2,v,2); auto remove_original=[](PolyCollection& p) { auto it=p.segment_traversal().begin()->end(); p.erase(it-2,it); }; p=p1; BOOST_TEST(is_first( p,typeid_(p), p.insert( p.begin(typeid_(p)), external_iterator(p2.begin()),external_iterator(p2.end())))); remove_original(p); BOOST_TEST(p==p2); p=p1; BOOST_TEST(is_first( p,typeid_(p), p.insert( p.cbegin(typeid_(p)), external_iterator(p2.begin()),external_iterator(p2.end())))); remove_original(p); BOOST_TEST(p==p2); p=p1; BOOST_TEST(is_first( p, p.insert( p.template begin(), external_iterator(p2.begin()),external_iterator(p2.end())))); remove_original(p); BOOST_TEST(p==p2); p=p1; BOOST_TEST(is_first( p, p.insert( p.template cbegin(), external_iterator(p2.begin()),external_iterator(p2.end())))); remove_original(p); BOOST_TEST(p==p2); } { using type=first_of< constraints< is_constructible_from_int,is_not_copy_constructible, is_equality_comparable >, Types... >; PolyCollection p; std::vector s(10); ValueFactory v; fill,type>(p,v,2); std::iota(s.begin(),s.end(),0); BOOST_TEST(is_first( p, p.insert(p.template begin(),s.begin(),s.end()))); BOOST_TEST( std::equal(s.begin(),s.end(),p.template begin(), [](int x,const type& y){return type{x}==y;}) ); } } void test_variant_insertion() { struct move_track { move_track(int n_):n{n_}{} move_track(move_track&& x)noexcept:n{x.n}{x.n=0;} int n; }; boost::variant_collection< boost::mp11::mp_list> c1; c1.insert(1); c1.insert('a'); c1.insert(3.1416); auto c2=c1; c1.insert(*c2.begin()); BOOST_TEST_EQ(c1.size(),2); boost::variant2::variant v1('a'); c1.insert(v1); BOOST_TEST_EQ(c1.size(),2); v1.emplace(1); c1.insert(std::move(v1)); BOOST_TEST_EQ(c1.size(),1); BOOST_TEST(boost::variant2::get(v1).n==0); #if !defined(BOOST_NO_CXX17_HDR_VARIANT) std::variant v2(3.1416); c1.insert(v2); BOOST_TEST_EQ(c1.size(),2); v2.emplace(1); c1.insert(std::move(v2)); BOOST_TEST_EQ(c1.size(),2); BOOST_TEST(std::get(v2).n==0); #endif } void test_insertion() { test_insertion< any_types::collection,auto_increment, any_types::t1,any_types::t2,any_types::t3, any_types::t4,any_types::t5>(); test_insertion< base_types::collection,auto_increment, base_types::t1,base_types::t2,base_types::t3, base_types::t4,base_types::t5>(); test_insertion< function_types::collection,auto_increment, function_types::t1,function_types::t2,function_types::t3, function_types::t4,function_types::t5>(); test_insertion< variant_types::collection,auto_increment, variant_types::t1,variant_types::t2,variant_types::t3, variant_types::t4,variant_types::t5>(); test_variant_insertion(); }