This is the mail archive of the mailing list for the libstdc++ project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [GSoC] Patches for shared_ptr array and polymorphic_allocator

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 []
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:


In that test you could use static_assert to test the values are correct,
instead of a runtime VERIFY.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]