// { dg-do run { target c++26 } } #include #include #include #include #include #include using __gnu_test::propagating_allocator; using __gnu_test::tracker_allocator; using Counter = __gnu_test::tracker_allocator_counter; template void test_ctor() { using PropAlloc = propagating_allocator; using Vector = std::vector; using ScopedAlloc = std::scoped_allocator_adaptor< propagating_allocator>, PropAlloc>; using Indirect = std::indirect; const Indirect src(std::allocator_arg, ScopedAlloc{11, 22}, std::in_place, {1, 2, 3}); Counter::reset(); Indirect i1(src); VERIFY( *i1 == *src ); VERIFY( &*i1 != &*src ); if (Propagate) { VERIFY( i1->get_allocator().get_personality() == 22 ); VERIFY( i1.get_allocator().get_personality() == 11 ); } else { VERIFY( i1->get_allocator().get_personality() == 0 ); VERIFY( i1.get_allocator().get_personality() == 0 ); } VERIFY( Counter::get_allocation_count() == sizeof(Vector) ); VERIFY( Counter::get_deallocation_count() == 0 ); VERIFY( Counter::get_construct_count() == 1 ); VERIFY( Counter::get_destruct_count() == 0 ); Counter::reset(); Indirect i2(std::allocator_arg, ScopedAlloc{33, 44}, src); VERIFY( *i2 == *src ); VERIFY( &*i2 != &*src ); VERIFY( i2->get_allocator().get_personality() == 44 ); VERIFY( i2.get_allocator().get_personality() == 33 ); VERIFY( Counter::get_allocation_count() == sizeof(Vector) ); VERIFY( Counter::get_deallocation_count() == 0 ); VERIFY( Counter::get_construct_count() == 1 ); VERIFY( Counter::get_destruct_count() == 0 ); } template void test_assign() { using PropAlloc = propagating_allocator; using Vector = std::vector; using ScopedAlloc = std::scoped_allocator_adaptor< propagating_allocator>, PropAlloc>; using Indirect = std::indirect; const Indirect src(std::allocator_arg, ScopedAlloc{11, 22}, std::in_place, {1, 2, 3}); Indirect i1(std::allocator_arg, ScopedAlloc{11, 22}); Counter::reset(); i1 = src; VERIFY( *i1 == *src ); VERIFY( &*i1 != &*src ); VERIFY( i1->get_allocator().get_personality() == 22 ); VERIFY( i1.get_allocator().get_personality() == 11 ); VERIFY( Counter::get_allocation_count() == 0 ); VERIFY( Counter::get_deallocation_count() == 0 ); VERIFY( Counter::get_construct_count() == 0 ); VERIFY( Counter::get_destruct_count() == 0 ); Indirect i2(std::allocator_arg, ScopedAlloc{33, 44}); Counter::reset(); i2 = src; VERIFY( *i2 == *src ); VERIFY( &*i2 != &*src ); if (Propagate) { VERIFY( i2->get_allocator().get_personality() == 22 ); VERIFY( i2.get_allocator().get_personality() == 11 ); } else { VERIFY( i2->get_allocator().get_personality() == 44 ); VERIFY( i2.get_allocator().get_personality() == 33 ); } VERIFY( Counter::get_allocation_count() == sizeof(Vector) ); VERIFY( Counter::get_deallocation_count() == sizeof(Vector) ); VERIFY( Counter::get_construct_count() == 1 ); VERIFY( Counter::get_destruct_count() == 1 ); Indirect i3(std::allocator_arg, ScopedAlloc{11, 22}); auto(std::move(i3)); Counter::reset(); i3 = src; VERIFY( *i3 == *src ); VERIFY( &*i3 != &*src ); VERIFY( i3->get_allocator().get_personality() == 22 ); VERIFY( i3.get_allocator().get_personality() == 11 ); VERIFY( Counter::get_allocation_count() == sizeof(Vector) ); VERIFY( Counter::get_deallocation_count() == 0 ); VERIFY( Counter::get_construct_count() == 1 ); VERIFY( Counter::get_destruct_count() == 0 ); Indirect i4(std::allocator_arg, ScopedAlloc{33, 44}); auto(std::move(i4)); Counter::reset(); i4 = src; VERIFY( *i4 == *src ); VERIFY( &*i4 != &*src ); if (Propagate) { VERIFY( i4->get_allocator().get_personality() == 22 ); VERIFY( i4.get_allocator().get_personality() == 11 ); } else { VERIFY( i4->get_allocator().get_personality() == 44 ); VERIFY( i4.get_allocator().get_personality() == 33 ); } VERIFY( Counter::get_allocation_count() == sizeof(Vector) ); VERIFY( Counter::get_deallocation_count() == 0 ); VERIFY( Counter::get_construct_count() == 1 ); VERIFY( Counter::get_destruct_count() == 0 ); } template void test_valueless() { using PropAlloc = propagating_allocator; using Vector = std::vector; using ScopedAlloc = std::scoped_allocator_adaptor< propagating_allocator>, PropAlloc>; using Indirect = std::indirect; Indirect e(std::allocator_arg, ScopedAlloc{11, 22}); auto(std::move(e)); VERIFY( e.valueless_after_move() ); Counter::reset(); Indirect i1(e); VERIFY( i1.valueless_after_move() ); if (Propagate) VERIFY( i1.get_allocator().get_personality() == 11 ); else VERIFY( i1.get_allocator().get_personality() == 0 ); VERIFY( Counter::get_allocation_count() == 0 ); VERIFY( Counter::get_deallocation_count() == 0 ); VERIFY( Counter::get_construct_count() == 0 ); VERIFY( Counter::get_destruct_count() == 0 ); Counter::reset(); Indirect i2(std::allocator_arg, ScopedAlloc{33, 44}, e); VERIFY( i2.valueless_after_move() ); VERIFY( i2.get_allocator().get_personality() == 33 ); VERIFY( Counter::get_allocation_count() == 0 ); VERIFY( Counter::get_deallocation_count() == 0 ); VERIFY( Counter::get_construct_count() == 0 ); VERIFY( Counter::get_destruct_count() == 0 ); Indirect i3(std::allocator_arg, ScopedAlloc{33, 44}); Counter::reset(); i3 = e; VERIFY( i3.valueless_after_move() ); if (Propagate) VERIFY( i3.get_allocator().get_personality() == 11 ); else VERIFY( i3.get_allocator().get_personality() == 33 ); VERIFY( Counter::get_allocation_count() == 0 ); VERIFY( Counter::get_deallocation_count() == sizeof(Vector) ); VERIFY( Counter::get_construct_count() == 0 ); VERIFY( Counter::get_destruct_count() == 1 ); Counter::reset(); i2 = e; VERIFY( i2.valueless_after_move() ); if (Propagate) VERIFY( i2.get_allocator().get_personality() == 11 ); else VERIFY( i2.get_allocator().get_personality() == 33 ); VERIFY( Counter::get_allocation_count() == 0 ); VERIFY( Counter::get_deallocation_count() == 0 ); VERIFY( Counter::get_construct_count() == 0 ); VERIFY( Counter::get_destruct_count() == 0 ); } template constexpr void test_all() { test_ctor(); test_assign(); test_valueless(); } int main() { test_all(); test_all(); }