1 // { dg-do compile { target c++11 } } 2 3 // Copyright (C) 2011-2021 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // You should have received a copy of the GNU General Public License along 17 // with this library; see the file COPYING3. If not see 18 // <http://www.gnu.org/licenses/>. 19 20 // test that propagate_on_container_xxx is true iff it is true for 21 // any of the outer or inner allocators 22 23 #include <scoped_allocator> 24 25 using std::scoped_allocator_adaptor; 26 27 typedef short test_type; 28 29 template<typename T> 30 struct minimal_allocator 31 { 32 typedef T value_type; 33 minimal_allocator(); 34 template <typename U> 35 minimal_allocator(const minimal_allocator<U>&); 36 T* allocate(std::size_t); 37 void deallocate(T*, std::size_t); 38 }; 39 40 template<typename T, bool copy, bool move, bool swap> 41 struct test_allocator : minimal_allocator<T> 42 { 43 template<typename U> 44 struct rebind 45 { using other = test_allocator<U, copy, move, swap>; }; 46 47 struct propagate_on_container_copy_assignment 48 : std::integral_constant<bool, copy> { }; 49 50 struct propagate_on_container_move_assignment 51 : std::integral_constant<bool, move> { }; 52 53 struct propagate_on_container_swap 54 : std::integral_constant<bool, swap> { }; 55 }; 56 57 template<typename A> prop_on_copy()58 constexpr bool prop_on_copy() 59 { 60 typedef typename A::propagate_on_container_copy_assignment type; 61 return type::value; 62 } 63 64 template<typename A> prop_on_move()65 constexpr bool prop_on_move() 66 { 67 typedef typename A::propagate_on_container_move_assignment type; 68 return type::value; 69 } 70 71 template<typename A> prop_on_swap()72 constexpr bool prop_on_swap() 73 { 74 typedef typename A::propagate_on_container_swap type; 75 return type::value; 76 } 77 78 template<typename A, bool C, bool M, bool S> test1()79 constexpr bool test1() 80 { 81 static_assert( prop_on_copy<A>() == C, "copy" ); 82 static_assert( prop_on_move<A>() == M, "move" ); 83 static_assert( prop_on_swap<A>() == S, "swap" ); 84 return true; 85 } 86 87 template<bool C, bool M, bool S> test2()88 constexpr bool test2() 89 { 90 typedef minimal_allocator<test_type> base_alloc; 91 typedef test_allocator<test_type, C, M, S> test_alloc; 92 typedef scoped_allocator_adaptor<base_alloc, test_alloc> scoped1; 93 typedef scoped_allocator_adaptor<test_alloc, base_alloc> scoped2; 94 typedef scoped_allocator_adaptor<test_alloc, test_alloc> scoped3; 95 return test1<scoped1, C, M, S>() 96 && test1<scoped2, C, M, S>() 97 && test1<scoped3, C, M, S>(); 98 } 99 100 static_assert( test2<false, false, false>(), "never propagate" ); 101 static_assert( test2<true, false, false>(), "propagate on copy" ); 102 static_assert( test2<false, true, false>(), "propagate on move" ); 103 static_assert( test2<false, false, true>(), "propagate on swap" ); 104 static_assert( test2<true, true, false>(), "propagate on copy & move" ); 105 static_assert( test2<true, false, true>(), "propagate on copy & swap" ); 106 static_assert( test2<false, true, true>(), "propagate on move & swap" ); 107 static_assert( test2<true, true, true>(), "always propagate" ); 108 109