blob: 22d3eecf9499378a26e098cbcc4e0daa9abbe0df [file] [log] [blame]
// { dg-do run { target c++14 } }
// { dg-require-atomic-builtins "" }
// Copyright (C) 2015-2021 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
// <http://www.gnu.org/licenses/>.
#include <experimental/memory_resource>
#include <vector>
#include <cstdlib>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
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::experimental::pmr::set_default_resource;
struct A
{
A() { ++ctor_count; }
~A() { ++dtor_count; }
static int ctor_count;
static int dtor_count;
};
int A::ctor_count = 0;
int A::dtor_count = 0;
struct CountedResource : public memory_resource
{
public:
CountedResource() = default;
~CountedResource() = default;
static size_t get_alloc_count() { return alloc_count; }
static size_t get_dalloc_count() { return dalloc_count; }
static size_t alloc_count;
static size_t dalloc_count;
protected:
void* do_allocate(size_t bytes, size_t alignment)
{
alloc_count += bytes;
if (auto ptr = std::malloc(bytes))
return ptr;
throw std::bad_alloc();
}
void do_deallocate(void *p, size_t bytes, size_t alignment)
{
dalloc_count += bytes;
std::free(p);
}
bool do_is_equal(const memory_resource& __other) const noexcept
{ return this == &__other; }
};
size_t CountedResource::alloc_count = 0;
size_t CountedResource::dalloc_count = 0;
void clear()
{
CountedResource::alloc_count = 0;
CountedResource::dalloc_count = 0;
A::ctor_count = 0;
A::dtor_count = 0;
}
// memory resource
void
test01()
{
memory_resource* r = new_delete_resource();
VERIFY(get_default_resource() == r);
void *p = get_default_resource()->allocate(5);
VERIFY(p);
get_default_resource()->deallocate(p, 5);
clear();
CountedResource* cr = new CountedResource();
set_default_resource(cr);
VERIFY(get_default_resource() == cr);
void *pc = get_default_resource()->allocate(5);
VERIFY(pc);
get_default_resource()->deallocate(pc, 5);
VERIFY(CountedResource::get_alloc_count() == 5);
VERIFY(CountedResource::get_dalloc_count() == 5);
}
// polymorphic_allocator
void
test02()
{
clear();
{
CountedResource cr;
polymorphic_allocator<A> pa(&cr);
std::vector<A, polymorphic_allocator<A>> v(5, A(), pa);
}
VERIFY(A::ctor_count == 1);
VERIFY(A::dtor_count == 6);
VERIFY(CountedResource::get_alloc_count() == 5);
VERIFY(CountedResource::get_dalloc_count() == 5);
}
void
test03()
{
clear();
CountedResource cr;
polymorphic_allocator<A> pa(&cr);
A* p = pa.allocate(1);
pa.construct(p);
pa.destroy(p);
pa.deallocate(p, 1);
VERIFY(A::ctor_count == 1);
VERIFY(A::dtor_count == 1);
VERIFY(CountedResource::get_alloc_count() == 1);
VERIFY(CountedResource::get_dalloc_count() == 1);
}
void
test04()
{
polymorphic_allocator<A> pa1(get_default_resource());
polymorphic_allocator<A> pa2(get_default_resource());
VERIFY(pa1 == pa2);
polymorphic_allocator<A> pa3 = pa2.select_on_container_copy_construction();
VERIFY(pa1 == pa3);
}
int main()
{
test01();
test02();
test03();
test04();
}