[GSoC] Patches for shared_ptr array and polymorphic_allocator
Jonathan Wakely
jwakely@redhat.com
Tue Jul 28 11:57:00 GMT 2015
On 28/07/15 02:55 +0000, Fan You wrote:
>Thanks for the review, they helped a lot.
>
>
>When I writing test for polymorphic_allocator, I found [2.1.1] has not been
>implemented which made use-allocator construction test for memory_resource*
>impossible. So, I implemented it and the patch is attached, am I allowed to
>do modification on place outside std::experimental?
It's definitely not OK to #include <experimental/utility> in the
non-experimental standard headers.
I think we can adapt the existing one to work for PMRs in a safe and
extensible way.
If you declare std::__erased_type as an empty struct and extend
uses_allocator to check for it, then we don't pollute the namespace
with the names "experimental" or "erased_type".
Then in <experimental/utility> you can declare
std::experimental::erased_type as a typedef for std::__erased_type.
+ template<typename _Alloc, typename _Tp>
+ struct __erased_type_helper
+ { using type = typename is_convertible<_Alloc, _Tp>::type; };
+
+ template<typename _Alloc>
+ struct __erased_type_helper<_Alloc, std::experimental::erased_type>
+ { using type = true_type; };
This can be simplified using inheritance:
template<typename _Alloc, typename _Tp>
struct __erased_type_helper
: is_convertible<_Alloc, _Tp>
{ };
template<typename _Alloc>
struct __erased_type_helper<_Alloc, __erased_type>
: true_type
{ };
(I'm concerned that the edits to [allocator.uses.construction]
specified by [mods.allocator.uses] break some uses of std::tuple, but
I don't have the bandwidth to implement the changes in my head and
figure out the issues right now, so I'm going to ignore them.)
>Also, while testing polymorphic_allocator's construct method, how can I
>verify it did construct the right thing? I see some test, e.g.
>scoped_allocator uses "personality" in testsuite_allocator.h, it maps
>pointers to int, but I cannot understand the point of doing this, can you
>give me some hint on this?
That ensures that memory is deallocated by the same allocator that
allocated it (or one that compares equal to it, because equal
allocators can deallocate each other's memory).
What exactly do you want to test? If you just want to test that the
right constructor is called then make the constructor set some member
variable (or global variable) saying which constructor was called,
then you can test that e.g.
enum CtorType { Default, Copy, Move, Other };
// type that takes a memory_resource after other ctor args
struct A
{
using allocator_type = erased_type;
CtorType type;
pmr::memory_resource* alloc = nullptr;
A() : type(Default) { }
A(pmr::memory_resource* a) : type(Default), alloc(a) { }
A(const A&) : type(Copy) { }
A(const A&, pmr::memory_resource* a) : type(Copy), alloc(a) { }
A(A&&) : type (Move) { }
A(A&&, pmr::memory_resource* a) : type(Move), alloc(a) { }
A(int) : type(Other) { }
A(int, pmr::memory_resource* a) : type(Other), alloc(a) { }
};
// type that takes a memory_resource before other ctor args
struct B
{
using allocator_type = erased_type;
CtorType type;
pmr::memory_resource* alloc = nullptr;
B() : type(Default) { }
B(allocator_arg_t, pmr::memory_resource* a) : type(Default), alloc(a) { }
B(const B&) : type(Copy) { }
B(allocator_arg_t, pmr::memory_resource* a, const B&) : type(Copy), alloc(a) { }
B(B&&) : type (Move) { }
B(allocator_arg_t, pmr::memory_resource* a, B&&) : type(Move), alloc(a) { }
B(int) : type(Other) { }
B(allocator_arg_t, pmr::memory_resource* a, int) : type(Other), alloc(a) { }
};
// type that takes no memory_resource
struct C
{
CtorType type;
C() : type(Default) { }
C(const C&) : type(Copy) { }
C(C&&) : type (Move) { }
C(int) : type(Other) { }
};
Then you can try constructing objects of these types with various
arguments and verify that the expected constructor is called and that
the correct memory_resource is passed when expected.
Your test name has a typo in it:
libstdc++-v3/testsuite/experimental/type_erased_allocator/uses_alloctor.cc
In that test you could use static_assert to test the values are correct,
instead of a runtime VERIFY.
More information about the Libstdc++
mailing list