mirror of git://gcc.gnu.org/git/gcc.git
libstdc++/70940 Start fixing polymorphic memory resources
PR libstdc++/70940 * include/experimental/memory_resource (__resource_adaptor_imp::do_allocate): Do not default-construct rebound allocator. (__resource_adaptor_imp::do_deallocate): Likewise. Use allocator_traits to get pointer type. (__null_memory_resource::do_allocate): Remove unused parameters. (__null_memory_resource::do_deallocate): Likewise. (__null_memory_resource::do_is_equal): Likewise. Add return statement. * testsuite/experimental/type_erased_allocator/1.cc: Combine with ... * testsuite/experimental/type_erased_allocator/1_neg.cc: This, and move to ... * testsuite/experimental/memory_resource/1.cc: Here. * testsuite/experimental/memory_resource/null_memory_resource.cc: New. * testsuite/experimental/memory_resource/resource_adaptor.cc: New. From-SVN: r235868
This commit is contained in:
parent
da5b1ec120
commit
d9cb3e7598
|
|
@ -1,3 +1,21 @@
|
||||||
|
2016-05-04 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
PR libstdc++/70940
|
||||||
|
* include/experimental/memory_resource
|
||||||
|
(__resource_adaptor_imp::do_allocate): Do not default-construct
|
||||||
|
rebound allocator.
|
||||||
|
(__resource_adaptor_imp::do_deallocate): Likewise. Use
|
||||||
|
allocator_traits to get pointer type.
|
||||||
|
(__null_memory_resource::do_allocate): Remove unused parameters.
|
||||||
|
(__null_memory_resource::do_deallocate): Likewise.
|
||||||
|
(__null_memory_resource::do_is_equal): Likewise. Add return statement.
|
||||||
|
* testsuite/experimental/type_erased_allocator/1.cc: Combine with ...
|
||||||
|
* testsuite/experimental/type_erased_allocator/1_neg.cc: This, and
|
||||||
|
move to ...
|
||||||
|
* testsuite/experimental/memory_resource/1.cc: Here.
|
||||||
|
* testsuite/experimental/memory_resource/null_memory_resource.cc: New.
|
||||||
|
* testsuite/experimental/memory_resource/resource_adaptor.cc: New.
|
||||||
|
|
||||||
2016-04-29 Chris Gregory <czipperz@gmail.com>
|
2016-04-29 Chris Gregory <czipperz@gmail.com>
|
||||||
|
|
||||||
* config/*: Remove trailing whitespace.
|
* config/*: Remove trailing whitespace.
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
size_t __new_size = _S_aligned_size(__bytes,
|
size_t __new_size = _S_aligned_size(__bytes,
|
||||||
_S_supported(__alignment) ?
|
_S_supported(__alignment) ?
|
||||||
__alignment : _S_max_align);
|
__alignment : _S_max_align);
|
||||||
return _Aligned_alloc().allocate(__new_size);
|
return _Aligned_alloc(_M_alloc).allocate(__new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
|
|
@ -292,9 +292,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
size_t __new_size = _S_aligned_size(__bytes,
|
size_t __new_size = _S_aligned_size(__bytes,
|
||||||
_S_supported(__alignment) ?
|
_S_supported(__alignment) ?
|
||||||
__alignment : _S_max_align);
|
__alignment : _S_max_align);
|
||||||
_Aligned_alloc().deallocate(static_cast<typename
|
using _Ptr = typename allocator_traits<_Aligned_alloc>::pointer;
|
||||||
_Aligned_alloc::pointer>(__p),
|
_Aligned_alloc(_M_alloc).deallocate(static_cast<_Ptr>(__p),
|
||||||
__new_size);
|
__new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
|
|
@ -306,8 +306,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Calculate Aligned Size
|
// Calculate Aligned Size
|
||||||
// Returns a size that is larger than or equal to __size and divided by
|
// Returns a size that is larger than or equal to __size and divisible
|
||||||
// __alignment, where __alignment is required to be the power of 2.
|
// by __alignment, where __alignment is required to be the power of 2.
|
||||||
static size_t
|
static size_t
|
||||||
_S_aligned_size(size_t __size, size_t __alignment)
|
_S_aligned_size(size_t __size, size_t __alignment)
|
||||||
{ return ((__size - 1)|(__alignment - 1)) + 1; }
|
{ return ((__size - 1)|(__alignment - 1)) + 1; }
|
||||||
|
|
@ -342,16 +342,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void*
|
void*
|
||||||
do_allocate(size_t __bytes, size_t __alignment)
|
do_allocate(size_t, size_t)
|
||||||
{ std::__throw_bad_alloc(); }
|
{ std::__throw_bad_alloc(); }
|
||||||
|
|
||||||
void
|
void
|
||||||
do_deallocate(void* __p, size_t __bytes, size_t __alignment)
|
do_deallocate(void*, size_t, size_t) noexcept
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool
|
bool
|
||||||
do_is_equal(const memory_resource& __other) const noexcept
|
do_is_equal(const memory_resource& __other) const noexcept
|
||||||
{ }
|
{ return this == &__other; }
|
||||||
|
|
||||||
friend memory_resource* null_memory_resource() noexcept;
|
friend memory_resource* null_memory_resource() noexcept;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@
|
||||||
// with this library; see the file COPYING3. If not see
|
// with this library; see the file COPYING3. If not see
|
||||||
// <http://www.gnu.org/licenses/>.
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <experimental/memory_resource>
|
#include <experimental/memory_resource>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cstdlib>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
#include <testsuite_allocator.h>
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
|
@ -36,6 +36,7 @@ struct A
|
||||||
static int ctor_count;
|
static int ctor_count;
|
||||||
static int dtor_count;
|
static int dtor_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
int A::ctor_count = 0;
|
int A::ctor_count = 0;
|
||||||
int A::dtor_count = 0;
|
int A::dtor_count = 0;
|
||||||
|
|
||||||
|
|
@ -43,7 +44,7 @@ struct CountedResource : public memory_resource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CountedResource() = default;
|
CountedResource() = default;
|
||||||
~ CountedResource() = default;
|
~CountedResource() = default;
|
||||||
|
|
||||||
static size_t get_alloc_count() { return alloc_count; }
|
static size_t get_alloc_count() { return alloc_count; }
|
||||||
static size_t get_dalloc_count() { return dalloc_count; }
|
static size_t get_dalloc_count() { return dalloc_count; }
|
||||||
|
|
@ -54,23 +55,23 @@ protected:
|
||||||
void* do_allocate(size_t bytes, size_t alignment)
|
void* do_allocate(size_t bytes, size_t alignment)
|
||||||
{
|
{
|
||||||
alloc_count += bytes;
|
alloc_count += bytes;
|
||||||
if (auto ptr = std::malloc(bytes)) {
|
if (auto ptr = std::malloc(bytes))
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
|
||||||
throw std::bad_alloc();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_deallocate(void *p, size_t bytes, size_t alignment)
|
void do_deallocate(void *p, size_t bytes, size_t alignment)
|
||||||
{
|
{
|
||||||
dalloc_count += bytes;
|
dalloc_count += bytes;
|
||||||
free(p);
|
std::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool do_is_equal(const memory_resource& __other) const noexcept
|
bool do_is_equal(const memory_resource& __other) const noexcept
|
||||||
{ return this == &__other; }
|
{ return this == &__other; }
|
||||||
};
|
};
|
||||||
size_t CountedResource::alloc_count = 0;
|
|
||||||
size_t CountedResource::dalloc_count = 0;
|
size_t CountedResource::alloc_count = 0;
|
||||||
|
size_t CountedResource::dalloc_count = 0;
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
|
|
@ -81,8 +82,11 @@ void clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// memory resource
|
// memory resource
|
||||||
void test01()
|
void
|
||||||
|
test01()
|
||||||
{
|
{
|
||||||
|
bool test __attribute((unused)) = false;
|
||||||
|
|
||||||
memory_resource* r = new_delete_resource();
|
memory_resource* r = new_delete_resource();
|
||||||
VERIFY(get_default_resource() == r);
|
VERIFY(get_default_resource() == r);
|
||||||
void *p = get_default_resource()->allocate(5);
|
void *p = get_default_resource()->allocate(5);
|
||||||
|
|
@ -101,8 +105,11 @@ void test01()
|
||||||
}
|
}
|
||||||
|
|
||||||
// polymorphic_allocator
|
// polymorphic_allocator
|
||||||
void test02()
|
void
|
||||||
|
test02()
|
||||||
{
|
{
|
||||||
|
bool test __attribute((unused)) = false;
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
{
|
{
|
||||||
CountedResource cr;
|
CountedResource cr;
|
||||||
|
|
@ -115,7 +122,11 @@ void test02()
|
||||||
VERIFY(CountedResource::get_dalloc_count() == 5);
|
VERIFY(CountedResource::get_dalloc_count() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test03() {
|
void
|
||||||
|
test03()
|
||||||
|
{
|
||||||
|
bool test __attribute((unused)) = false;
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
CountedResource cr;
|
CountedResource cr;
|
||||||
polymorphic_allocator<A> pa(&cr);
|
polymorphic_allocator<A> pa(&cr);
|
||||||
|
|
@ -129,7 +140,11 @@ void test03() {
|
||||||
VERIFY(CountedResource::get_dalloc_count() == 1);
|
VERIFY(CountedResource::get_dalloc_count() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test04() {
|
void
|
||||||
|
test04()
|
||||||
|
{
|
||||||
|
bool test __attribute((unused)) = false;
|
||||||
|
|
||||||
polymorphic_allocator<A> pa1(get_default_resource());
|
polymorphic_allocator<A> pa1(get_default_resource());
|
||||||
polymorphic_allocator<A> pa2(get_default_resource());
|
polymorphic_allocator<A> pa2(get_default_resource());
|
||||||
VERIFY(pa1 == pa2);
|
VERIFY(pa1 == pa2);
|
||||||
|
|
@ -137,10 +152,10 @@ void test04() {
|
||||||
VERIFY(pa1 == pa3);
|
VERIFY(pa1 == pa3);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
test01();
|
test01();
|
||||||
test02();
|
test02();
|
||||||
test03();
|
test03();
|
||||||
test04();
|
test04();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// { dg-do run { xfail *-*-* } }
|
|
||||||
// { dg-options "-std=gnu++14" }
|
// { dg-options "-std=gnu++14" }
|
||||||
|
|
||||||
// Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
// Copyright (C) 2016 Free Software Foundation, Inc.
|
||||||
//
|
//
|
||||||
// This file is part of the GNU ISO C++ Library. This library is free
|
// 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
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
|
@ -20,17 +19,34 @@
|
||||||
|
|
||||||
#include <experimental/memory_resource>
|
#include <experimental/memory_resource>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
#include <testsuite_allocator.h>
|
|
||||||
|
|
||||||
using std::experimental::pmr::polymorphic_allocator;
|
|
||||||
using std::experimental::pmr::null_memory_resource;
|
|
||||||
using std::experimental::pmr::memory_resource;
|
using std::experimental::pmr::memory_resource;
|
||||||
|
using std::experimental::pmr::null_memory_resource;
|
||||||
|
using std::experimental::pmr::new_delete_resource;
|
||||||
|
|
||||||
|
// null_memory_resource
|
||||||
|
void
|
||||||
|
test06()
|
||||||
|
{
|
||||||
|
bool test __attribute((unused)) = false;
|
||||||
|
|
||||||
void test01() {
|
|
||||||
memory_resource* r = null_memory_resource();
|
memory_resource* r = null_memory_resource();
|
||||||
auto p = r->allocate(1);
|
bool caught = false;
|
||||||
|
|
||||||
|
void* p = nullptr;
|
||||||
|
try {
|
||||||
|
p = r->allocate(1);
|
||||||
|
} catch (const std::bad_alloc&) {
|
||||||
|
caught = true;
|
||||||
|
}
|
||||||
|
VERIFY( caught );
|
||||||
|
|
||||||
|
VERIFY( *r == *r );
|
||||||
|
VERIFY( r->is_equal(*r) );
|
||||||
|
VERIFY( !r->is_equal(*new_delete_resource()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
test01();
|
{
|
||||||
|
test06();
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
// { dg-options "-std=gnu++14" }
|
||||||
|
|
||||||
|
// Copyright (C) 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
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <experimental/memory_resource>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
using std::experimental::pmr::memory_resource;
|
||||||
|
using std::experimental::pmr::resource_adaptor;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Allocator : __gnu_test::SimpleAllocator<T>
|
||||||
|
{
|
||||||
|
Allocator(int) { } // not default constructible
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
Allocator(const Allocator<U>&) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool aligned(void* p)
|
||||||
|
{
|
||||||
|
return (reinterpret_cast<std::uintptr_t>(p) % alignof(T)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// resource_adaptor
|
||||||
|
void
|
||||||
|
test05()
|
||||||
|
{
|
||||||
|
bool test __attribute((unused)) = false;
|
||||||
|
using std::max_align_t;
|
||||||
|
using std::uintptr_t;
|
||||||
|
void* p = nullptr;
|
||||||
|
|
||||||
|
Allocator<int> a1(1), a2(2); // minimal interface allocators
|
||||||
|
resource_adaptor<decltype(a1)> r1(a1), r2(a2);
|
||||||
|
VERIFY( r1 == r1 );
|
||||||
|
VERIFY( r1 == r2 );
|
||||||
|
p = r1.allocate(1);
|
||||||
|
VERIFY( aligned<max_align_t>(p) );
|
||||||
|
r1.deallocate(p, 1);
|
||||||
|
p = r1.allocate(1, alignof(short));
|
||||||
|
VERIFY( aligned<short>(p) );
|
||||||
|
r1.deallocate(p, 1, alignof(short));
|
||||||
|
p = r1.allocate(1, alignof(long));
|
||||||
|
VERIFY( aligned<long>(p) );
|
||||||
|
r1.deallocate(p, 1, alignof(long));
|
||||||
|
|
||||||
|
__gnu_test::uneq_allocator<double> a3(3), a4(4); // non-equal allocators
|
||||||
|
resource_adaptor<decltype(a3)> r3(a3), r4(a4);
|
||||||
|
VERIFY( r3 == r3 );
|
||||||
|
VERIFY( r4 == r4 );
|
||||||
|
VERIFY( r3 != r4 );
|
||||||
|
p = r3.allocate(1);
|
||||||
|
VERIFY( aligned<max_align_t>(p) );
|
||||||
|
r3.deallocate(p, 1);
|
||||||
|
p = r3.allocate(1, alignof(short));
|
||||||
|
VERIFY( aligned<short>(p) );
|
||||||
|
r3.deallocate(p, 1, alignof(short));
|
||||||
|
p = r3.allocate(1, alignof(long));
|
||||||
|
VERIFY( aligned<long>(p) );
|
||||||
|
r3.deallocate(p, 1, alignof(long));
|
||||||
|
|
||||||
|
// TODO test with an allocator that doesn't use new or malloc, so
|
||||||
|
// returns pointers that are not suitably aligned for any type.
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test05();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue