blob: e48855a0eac506b06ec835879898b321a1e45c34 [file] [log] [blame]
// { dg-do run { target c++26 } }
#include <memory>
#include <scoped_allocator>
#include <utility>
#include <vector>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::propagating_allocator;
using __gnu_test::tracker_allocator;
using Counter = __gnu_test::tracker_allocator_counter;
template<bool Propagate>
void
test_ctor()
{
using PropAlloc = propagating_allocator<int, Propagate>;
using Vector = std::vector<int, PropAlloc>;
using ScopedAlloc = std::scoped_allocator_adaptor<
propagating_allocator<Vector, Propagate, tracker_allocator<Vector>>,
PropAlloc>;
using Indirect = std::indirect<Vector, ScopedAlloc>;
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<bool Propagate>
void
test_assign()
{
using PropAlloc = propagating_allocator<int, Propagate>;
using Vector = std::vector<int, PropAlloc>;
using ScopedAlloc = std::scoped_allocator_adaptor<
propagating_allocator<Vector, Propagate, tracker_allocator<Vector>>,
PropAlloc>;
using Indirect = std::indirect<Vector, ScopedAlloc>;
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<bool Propagate>
void
test_valueless()
{
using PropAlloc = propagating_allocator<int, Propagate>;
using Vector = std::vector<int, PropAlloc>;
using ScopedAlloc = std::scoped_allocator_adaptor<
propagating_allocator<Vector, Propagate, tracker_allocator<Vector>>,
PropAlloc>;
using Indirect = std::indirect<Vector, ScopedAlloc>;
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<bool Propagate>
constexpr void
test_all()
{
test_ctor<Propagate>();
test_assign<Propagate>();
test_valueless<Propagate>();
}
int main()
{
test_all<true>();
test_all<false>();
}