/* Copyright 2016-2017 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_construction.hpp" #include #include #include #include #include #include #include #include #include #include "any_types.hpp" #include "base_types.hpp" #include "function_types.hpp" #include "test_utilities.hpp" using namespace test_utilities; template void test_construction() { { PolyCollection p; const PolyCollection& cp=p; ValueFactory v; fill< constraints, Types... >(p,v,2); { PolyCollection p2{cp}; BOOST_TEST(p2==p); } { PolyCollection p2; p2=cp; BOOST_TEST(p2==p); } { PolyCollection p2{cp}; auto d2=get_layout_data(p2); PolyCollection p3{std::move(p2)}; auto d3=get_layout_data(p3); BOOST_TEST(d2==d3); BOOST_TEST(p2.empty()); do_((BOOST_TEST(!p2.template is_registered()),0)...); } { PolyCollection p2{cp}; auto d2=get_layout_data(p2); PolyCollection p3; p3={std::move(p2)}; auto d3=get_layout_data(p3); BOOST_TEST(d2==d3); BOOST_TEST(p2.empty()); do_((BOOST_TEST(!p2.template is_registered()),0)...); } { PolyCollection p2{cp.begin(),cp.end()}; BOOST_TEST(p2==p); } { using type=first_of< constraints, Types...>; PolyCollection p2{cp.template begin(),cp.template end()}; BOOST_TEST( p2.size()==cp.template size()&& std::equal( p2.template begin(),p2.template end(), cp.template begin())); } } { using rooted_poly_collection= realloc_poly_collection; using allocator_type=typename rooted_poly_collection::allocator_type; allocator_type root1{0},root2{0}; rooted_poly_collection p{root1}; const rooted_poly_collection& cp=p; ValueFactory v; fill< constraints, Types... >(p,v,2); { rooted_poly_collection p2{cp,root2}; BOOST_TEST(p2==p); BOOST_TEST(p2.get_allocator()==root2); } { rooted_poly_collection p2{root2}; p2=cp; BOOST_TEST(p2==p); BOOST_TEST(p2.get_allocator().root==&root2); } #if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40900) /* Limitations from libstdc++-v3 make move construction with allocator * decay to copy construction with allocator. */ #else { rooted_poly_collection p2{cp}; auto d2=get_layout_data(p2); rooted_poly_collection p3{std::move(p2),root2}; auto d3=get_layout_data(p3); BOOST_TEST(d2==d3); BOOST_TEST(p2.empty()); do_((BOOST_TEST(!p2.template is_registered()),0)...); BOOST_TEST(p3.get_allocator().root==&root2); } #endif { rooted_poly_collection p2{cp}; auto d2=get_layout_data(p2); rooted_poly_collection p3{root2}; p3=std::move(p2); auto d3=get_layout_data(p3); BOOST_TEST(d2==d3); BOOST_TEST(p2.empty()); do_((BOOST_TEST(!p2.template is_registered()),0)...); #if BOOST_WORKAROUND(BOOST_MSVC,<=1900)||\ BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40900) #else BOOST_TEST(p3.get_allocator().root==&root1); #endif } } { using not_copy_constructible= boost::poly_collection::not_copy_constructible; PolyCollection p; const PolyCollection& cp=p; ValueFactory v; fill< constraints, Types... >(p,v,2); #if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40900) /* std::unordered_map copy construction and assigment crash when elements * throw on copy construction. */ static_assert( sizeof(not_copy_constructible)>0,""); /* Wunused-local-typedefs */ (void)cp; /* Wunused-variable */ #else check_throw([&]{ PolyCollection p2{cp}; (void)p2; }); check_throw([&]{ PolyCollection p2; p2=cp; }); #endif { PolyCollection p2{std::move(p)}; BOOST_TEST(!p2.empty()); BOOST_TEST(p.empty()); do_((BOOST_TEST(!p.template is_registered()),0)...); p={std::move(p2)}; BOOST_TEST(!p.empty()); BOOST_TEST(p2.empty()); do_((BOOST_TEST(!p2.template is_registered()),0)...); } } { PolyCollection p1,p2; ValueFactory v; fill,Types...>(p1,v,2); auto d1=get_layout_data(p1), d2=get_layout_data(p2); p1.swap(p2); auto e1=get_layout_data(p1), e2=get_layout_data(p2); BOOST_TEST(d1==e2); BOOST_TEST(d2==e1); do_((BOOST_TEST(!p1.template is_registered()),0)...); using std::swap; swap(p1,p2); auto f1=get_layout_data(p1), f2=get_layout_data(p2); BOOST_TEST(e1==f2); BOOST_TEST(e2==f1); do_((BOOST_TEST(!p2.template is_registered()),0)...); } } void test_scoped_allocator() { using vector_allocator=rooted_allocator; using vector=std::vector; using concept_=boost::type_erasure::relaxed; using element_allocator=rooted_allocator< boost::poly_collection::any_collection_value_type >; using collection_allocator=std::scoped_allocator_adaptor< element_allocator, vector_allocator >; using poly_collection= boost::any_collection; element_allocator roote{0}; vector_allocator rootv{0}; collection_allocator al{roote,rootv}; poly_collection p{al}; p.emplace(); auto& s=boost::type_erasure::any_cast(*p.begin()); BOOST_TEST(p.get_allocator().root==&roote); #if BOOST_WORKAROUND(BOOST_MSVC,>=1910) /* https://connect.microsoft.com/VisualStudio/feedback/details/3136309 */ #else BOOST_TEST(s.get_allocator().root==&rootv); #endif } void test_construction() { test_construction< any_types::collection,auto_increment, any_types::t1,any_types::t2,any_types::t3, any_types::t4,any_types::t5>(); test_construction< base_types::collection,auto_increment, base_types::t1,base_types::t2,base_types::t3, base_types::t4,base_types::t5>(); test_construction< function_types::collection,auto_increment, function_types::t1,function_types::t2,function_types::t3, function_types::t4,function_types::t5>(); test_scoped_allocator(); }