On 25/06/14 21:47 +0200, François Dumont wrote:
I would like to finally propose this patch before the one on
_Rb_tree, as a separate one.
I have adopted the same evolution on the tracker_allocator with
even a perfect forwarding constructor to allow its usage on top of
the uneq_allocator which take a personality parameter. Doing so I
realized that move_assign_neg.cc tests were not accurate enough as
they needed a non move propagating allocator and the uneq_allocator
were not explicitly non propagating.
Ah, that's good to improve them then.
Index: testsuite/util/testsuite_allocator.h
===================================================================
--- testsuite/util/testsuite_allocator.h (revision 211713)
+++ testsuite/util/testsuite_allocator.h (working copy)
@@ -87,103 +81,142 @@
static int destructCount_;
};
- // A simple basic allocator that just forwards to the
+ // Helper to detect inconsistency between type used to instantiate an
+ // allocator and the underlying allocator value_type.
+ template<typename T, typename Alloc,
+ typename = typename Alloc::value_type>
+ struct check_consistent_alloc_value_type;
+
+ template<typename T, typename Alloc>
+ struct check_consistent_alloc_value_type<T, Alloc, T>
+ { typedef T value_type; };
+
+ // An allocator facade that just intercepts some calls and forward them to
the
// tracker_allocator_counter to fulfill memory requests. This class
This comment is no longer true, tracker_allocator_counter does not
fulfil the memory requests.
// is templated on the target object type, but tracker isn't.
- template<class T>
- class tracker_allocator
- {
- private:
- typedef tracker_allocator_counter counter_type;
+ template<typename T, typename Alloc = std::allocator<T> >
+ class tracker_allocator : public Alloc
+ {
+ private:
+ typedef tracker_allocator_counter counter_type;
- public:
- typedef T value_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
+ typedef __gnu_cxx::__alloc_traits<Alloc> AllocTraits;
+
+ public:
+ typedef typename
+ check_consistent_alloc_value_type<T, Alloc>::value_type value_type;
+ typedef typename AllocTraits::pointer pointer;
+ typedef typename AllocTraits::size_type size_type;
Thanks for doing this - I think it makes the facade more useful if it
uses allocator_traits and so can be combined with SimpleAllocator and
CustomPointerAlloc.
- template<class U> struct rebind { typedef tracker_allocator<U> other; };
+ template<class U>
+ struct rebind
+ {
+ typedef tracker_allocator<U,
+ typename AllocTraits::template rebind<U>::other> other;
+ };
- pointer
- address(reference value) const _GLIBCXX_NOEXCEPT
- { return std::__addressof(value); }
+#if __cplusplus >= 201103L
+ tracker_allocator() = default;
+ tracker_allocator(const tracker_allocator&) = default;
+ tracker_allocator(tracker_allocator&&) = default;
- const_pointer
- address(const_reference value) const _GLIBCXX_NOEXCEPT
- { return std::__addressof(value); }
+ // Perfect forwarding constructor.
+ template<typename... _Args>
+ tracker_allocator(_Args&&... __args)
+ : Alloc(std::forward<_Args>(__args)...)
+ { }
+#else
+ tracker_allocator() _GLIBCXX_USE_NOEXCEPT
The _GLIBCXX_USE_NOEXCEPT macro expands to nothing in C++03 mode, so
you might as well omit it in the #else branch.
OK for trunk if you make the tracker_allocator comment correct.
Thanks!