// { dg-options "-std=gnu++14" } // Copyright (C) 2015-2016 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . #include #include #include #include #include using std::experimental::pmr::polymorphic_allocator; using std::experimental::pmr::memory_resource; using std::experimental::pmr::new_delete_resource; using std::experimental::pmr::get_default_resource; using std::allocator_arg_t; enum CtorType { Default, Copy, Move, Other, Tuple, Piecewise_Default, Piecewise_Copy}; // type that takes a memory_resource before other ctor args struct A { using allocator_type = std::experimental::erased_type; CtorType type; memory_resource* alloc = nullptr; A() : type(Default) { } A(allocator_arg_t, memory_resource* a) : type(Default), alloc(a) { } A(const A&) : type(Copy) { } A(allocator_arg_t, memory_resource* a, const A&) : type(Copy), alloc(a) { } A(A&&) : type (Move) { } A(allocator_arg_t, memory_resource* a, A&&) : type (Move), alloc(a) { } A(int) : type(Other) { } A(allocator_arg_t, memory_resource* a, int) : type(Other), alloc(a) { } }; // type that takes a memory_resource after other ctor args struct B { using allocator_type = std::experimental::erased_type; CtorType type; memory_resource* alloc = nullptr; B() : type(Default) { } B(memory_resource* a) : type(Default), alloc(a) { } B(const B&) : type(Copy) { } B(const B&, memory_resource* a) : type(Copy), alloc(a) { } B(B&&) : type (Move) { } B(B&&, memory_resource* a) : type(Move), alloc(a) { } B(int) : type(Other) { } B(int, memory_resource* a) : type(Other), alloc(a) { } }; // type that takes no memory_resource struct C { CtorType type; C() : type(Default) { } C(const C&) : type(Copy) { } C(C&&) : type(Move) { } C(int) : type(Other) { } }; // test construct for type that // uses memory_resource* as allocator template void test_uses_alloc() { polymorphic_allocator pa; A* p = pa.allocate(1); A a; pa.construct(p); VERIFY(p->alloc == get_default_resource()); VERIFY(p->type == Default); pa.destroy(p); pa.construct(p, a); VERIFY(p->type == Copy); pa.destroy(p); pa.construct(p, A()); VERIFY(p->type == Move); pa.destroy(p); pa.construct(p, 1); VERIFY(p->type == Other); pa.destroy(p); pa.deallocate(p, 1); } // test construct for type that not using allocator template void test_non_alloc() { polymorphic_allocator pa; C* p = pa.allocate(1); C b; pa.construct(p); VERIFY(p->type == Default); pa.destroy(p); pa.construct(p, b); VERIFY(p->type == Copy); pa.destroy(p); pa.construct(p, C()); VERIFY(p->type == Move); pa.destroy(p); pa.construct(p, 1); VERIFY(p->type == Other); pa.destroy(p); pa.deallocate(p, 1); } // test piecewise_construct template void test_pair() { polymorphic_allocator> pa; std::pair* p = pa.allocate(1); std::tuple<> t; // construct(pair* p, piecewise_construct_t, tuple<...>, tuple<...>) pa.construct(p, std::piecewise_construct, t, t); VERIFY(p->first.type == Default); VERIFY(p->second.type == Default); pa.destroy(p); // construct(pair* __p) pa.construct(p); VERIFY(p->first.type == Default); VERIFY(p->second.type == Default); pa.destroy(p); // construct(pair* p, U&& x, V&& y) A a; B b; pa.construct(p, a, b); VERIFY(p->first.type == Copy); VERIFY(p->second.type == Copy); pa.destroy(p); pa.construct(p, A(), B()); VERIFY(p->first.type == Move); VERIFY(p->second.type == Move); auto pp = *p; pa.destroy(p); // construct(pair* p, const pair& x) pa.construct(p, pp); VERIFY(p->first.type == Copy); VERIFY(p->second.type == Copy); pa.destroy(p); // construct(pair* p, pair&& x) pa.construct(p, std::move(pp)); VERIFY(p->first.type == Move); VERIFY(p->second.type == Move); pa.destroy(p); pa.deallocate(p, 1); } void test01() { test_uses_alloc(); test_uses_alloc(); test_non_alloc(); } void test02() { test_pair(); test_pair(); test_pair(); test_pair(); test_pair(); test_pair(); test_pair(); } int main() { test01(); test02(); }