diff options
author | fdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-06-26 18:42:41 +0000 |
---|---|---|
committer | fdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-06-26 18:42:41 +0000 |
commit | 38176e2caf17cc187b79530da7731d971af64c90 (patch) | |
tree | 8168a48a528e2e275de5f5d7a16a2ea0c08f95fd /libstdc++-v3/testsuite | |
parent | 9eb33c8f31de3eafad39c9917cf177320e958807 (diff) | |
download | gcc-38176e2caf17cc187b79530da7731d971af64c90.tar.gz |
2014-06-26 François Dumont <fdumont@gcc.gnu.org>
* testsuite/util/testsuite_allocator.h
(tracker_allocator_counter::allocate): Remove new invocation, only
collect information.
(tracker_allocator_counter::deallocate): Remove delete invocation, only
collect information.
(check_inconsistent_alloc_value_type): New.
(tracker_allocator): Transform as a facade for any allocator type.
(uneq_allocator): Likewise.
(propagating_allocator): Likewise.
* testsuite/23_containers/forward_list/debug/move_assign_neg.cc: Use an
explicitly non propagating allocator.
* testsuite/23_containers/map/debug/move_assign_neg.cc: Likewise.
* testsuite/23_containers/multimap/debug/move_assign_neg.cc: likewise.
* testsuite/23_containers/multiset/debug/move_assign_neg.cc: Likewise.
* testsuite/23_containers/set/debug/move_assign_neg.cc: Likewise.
* testsuite/23_containers/unordered_map/debug/move_assign_neg.cc:
Likewise.
* testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc:
Likewise.
* testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc:
Likewise.
* testsuite/23_containers/unordered_set/debug/move_assign_neg.cc:
Likewise.
* testsuite/23_containers/vector/debug/move_assign_neg.cc: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212046 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/testsuite')
11 files changed, 195 insertions, 164 deletions
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc index 91e459fd3c3..934afbedd6b 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc @@ -25,7 +25,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator<int> alloc_type; + typedef __gnu_test::propagating_allocator<int, false> alloc_type; typedef __gnu_debug::forward_list<int, alloc_type> test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc index 0d63fe944bf..3f2a7ca532b 100644 --- a/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc @@ -25,7 +25,8 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type; + typedef __gnu_test::propagating_allocator<std::pair<const int, int>, + false> alloc_type; typedef __gnu_debug::map<int, int, std::less<int>, alloc_type> test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc index e514a28dbed..da2950fe458 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc @@ -25,7 +25,8 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type; + typedef __gnu_test::propagating_allocator<std::pair<const int, int>, + false> alloc_type; typedef __gnu_debug::multimap<int, int, std::less<int>, alloc_type> test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc index af879d94dad..6f5f5b430cc 100644 --- a/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc @@ -25,7 +25,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator<int> alloc_type; + typedef __gnu_test::propagating_allocator<int, false> alloc_type; typedef __gnu_debug::multiset<int, std::less<int>, alloc_type> test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc index b7f51efd393..b491a03276d 100644 --- a/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc @@ -25,7 +25,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator<int> alloc_type; + typedef __gnu_test::propagating_allocator<int, false> alloc_type; typedef __gnu_debug::set<int, std::less<int>, alloc_type> test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc index ef5db1165f3..3670f73b0d3 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc @@ -25,7 +25,8 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type; + typedef __gnu_test::propagating_allocator<std::pair<const int, int>, + false> alloc_type; typedef __gnu_debug::unordered_map<int, int, std::hash<int>, std::equal_to<int>, alloc_type> test_type; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc index b6de1eef581..7a8fa77c4d8 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc @@ -25,7 +25,8 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator<std::pair<const int, int>> alloc_type; + typedef __gnu_test::propagating_allocator<std::pair<const int, int>, + false> alloc_type; typedef __gnu_debug::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, alloc_type> test_type; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc index 52a8df2a9f2..9fe72e1f254 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc @@ -25,7 +25,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator<int> alloc_type; + typedef __gnu_test::propagating_allocator<int, false> alloc_type; typedef __gnu_debug::unordered_multiset<int, std::hash<int>, std::equal_to<int>, alloc_type> test_type; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc index 9d2a8abc425..b1b71e118ff 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc @@ -25,7 +25,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator<int> alloc_type; + typedef __gnu_test::propagating_allocator<int, false> alloc_type; typedef __gnu_debug::unordered_set<int, std::hash<int>, std::equal_to<int>, alloc_type> test_type; diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/move_assign_neg.cc index eb2233b35fe..3de0723195e 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/move_assign_neg.cc @@ -27,7 +27,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator<int> alloc_type; + typedef __gnu_test::propagating_allocator<int, false> alloc_type; typedef __gnu_debug::vector<int, alloc_type> test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h index 822a025f4fa..8aae8c21514 100644 --- a/libstdc++-v3/testsuite/util/testsuite_allocator.h +++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h @@ -29,6 +29,7 @@ #include <tr1/unordered_map> #include <bits/move.h> #include <ext/pointer.h> +#include <ext/alloc_traits.h> #include <testsuite_hooks.h> namespace __gnu_test @@ -38,26 +39,19 @@ namespace __gnu_test public: typedef std::size_t size_type; - static void* + static void allocate(size_type blocksize) - { - void* p = ::operator new(blocksize); - allocationCount_ += blocksize; - return p; - } + { allocationCount_ += blocksize; } static void - construct() { constructCount_++; } + construct() { ++constructCount_; } static void - destroy() { destructCount_++; } + destroy() { ++destructCount_; } static void - deallocate(void* p, size_type blocksize) - { - ::operator delete(p); - deallocationCount_ += blocksize; - } + deallocate(size_type blocksize) + { deallocationCount_ += blocksize; } static size_type get_allocation_count() { return allocationCount_; } @@ -87,103 +81,142 @@ namespace __gnu_test static int destructCount_; }; - // A simple basic allocator that just forwards to the - // tracker_allocator_counter to fulfill memory requests. This class - // is templated on the target object type, but tracker isn't. - template<class T> - class tracker_allocator - { - private: - typedef tracker_allocator_counter counter_type; + // 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 intercepts allocate/deallocate/construct/detroy + // calls and track them through the tracker_allocator_counter class. This + // class is templated on the target object type, but tracker isn't. + 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; - 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); } - - const_pointer - address(const_reference value) const _GLIBCXX_NOEXCEPT - { return std::__addressof(value); } - - tracker_allocator() _GLIBCXX_USE_NOEXCEPT - { } - - tracker_allocator(const tracker_allocator&) _GLIBCXX_USE_NOEXCEPT - { } +#if __cplusplus >= 201103L + tracker_allocator() = default; + tracker_allocator(const tracker_allocator&) = default; + tracker_allocator(tracker_allocator&&) = default; + + // Perfect forwarding constructor. + template<typename... _Args> + tracker_allocator(_Args&&... __args) + : Alloc(std::forward<_Args>(__args)...) + { } +#else + tracker_allocator() + { } - template<class U> - tracker_allocator(const tracker_allocator<U>&) _GLIBCXX_USE_NOEXCEPT + tracker_allocator(const tracker_allocator&) { } - ~tracker_allocator() _GLIBCXX_USE_NOEXCEPT - { } + ~tracker_allocator() + { } +#endif - size_type - max_size() const _GLIBCXX_USE_NOEXCEPT - { return size_type(-1) / sizeof(T); } + template<class U> + tracker_allocator(const tracker_allocator<U, + typename AllocTraits::template rebind<U>::other>& alloc) + _GLIBCXX_USE_NOEXCEPT + : Alloc(alloc) + { } - pointer - allocate(size_type n, const void* = 0) - { return static_cast<pointer>(counter_type::allocate(n * sizeof(T))); } + pointer + allocate(size_type n, const void* = 0) + { + pointer p = AllocTraits::allocate(*this, n); + counter_type::allocate(n * sizeof(T)); + return p; + } #if __cplusplus >= 201103L - template<typename U, typename... Args> + template<typename U, typename... Args> + void + construct(U* p, Args&&... args) + { + AllocTraits::construct(*this, p, std::forward<Args>(args)...); + counter_type::construct(); + } + + template<typename U> + void + destroy(U* p) + { + AllocTraits::destroy(*this, p); + counter_type::destroy(); + } +#else void - construct(U* p, Args&&... args) + construct(pointer p, const T& value) { - ::new((void *)p) U(std::forward<Args>(args)...); + AllocTraits::construct(*this, p, value); counter_type::construct(); } - template<typename U> void - destroy(U* p) + destroy(pointer p) { - p->~U(); + AllocTraits::destroy(*this, p); counter_type::destroy(); } -#else - void - construct(pointer p, const T& value) - { - ::new ((void *)p) T(value); - counter_type::construct(); - } - - void - destroy(pointer p) - { - p->~T(); - counter_type::destroy(); - } #endif - void - deallocate(pointer p, size_type num) - { counter_type::deallocate(p, num * sizeof(T)); } - }; + void + deallocate(pointer p, size_type num) + { + counter_type::deallocate(num * sizeof(T)); + AllocTraits::deallocate(*this, p, num); + } + + // Implement swap for underlying allocators that might need it. + friend inline void + swap(tracker_allocator& a, tracker_allocator& b) + { + using std::swap; + + Alloc& aa = a; + Alloc& ab = b; + swap(aa, ab); + } + }; - template<class T1, class T2> + template<class T1, class Alloc1, class T2, class Alloc2> bool - operator==(const tracker_allocator<T1>&, - const tracker_allocator<T2>&) throw() - { return true; } + operator==(const tracker_allocator<T1, Alloc1>& lhs, + const tracker_allocator<T2, Alloc2>& rhs) throw() + { + const Alloc1& alloc1 = lhs; + const Alloc2& alloc2 = rhs; + return lhs == rhs; + } - template<class T1, class T2> + template<class T1, class Alloc1, class T2, class Alloc2> bool - operator!=(const tracker_allocator<T1>&, - const tracker_allocator<T2>&) throw() - { return false; } + operator!=(const tracker_allocator<T1, Alloc1>& lhs, + const tracker_allocator<T2, Alloc2>& rhs) throw() + { return !(lhs == rhs); } bool check_construct_destroy(const char* tag, int expected_c, int expected_d); @@ -193,7 +226,7 @@ namespace __gnu_test check_deallocate_null() { // Let's not core here... - Alloc a; + Alloc a; a.deallocate(0, 1); a.deallocate(0, 10); return true; @@ -219,7 +252,6 @@ namespace __gnu_test throw; } - // A simple allocator which can be constructed endowed of a given // "personality" (an integer), queried in operator== to simulate the // behavior of realworld "unequal" allocators (i.e., not exploiting @@ -227,7 +259,7 @@ namespace __gnu_test // filled at allocation time with (pointer, personality) pairs, is // then consulted to enforce the requirements in Table 32 about // deallocation vs allocator equality. Note that this allocator is - // swappable, not assignable, consistently with Option 3 of DR 431 + // swappable, not copy assignable, consistently with Option 3 of DR 431 // (see N1599). struct uneq_allocator_base { @@ -244,26 +276,33 @@ namespace __gnu_test } }; - template<typename Tp> + template<typename Tp, typename Alloc = std::allocator<Tp> > class uneq_allocator - : private uneq_allocator_base + : private uneq_allocator_base, + public Alloc { + typedef __gnu_cxx::__alloc_traits<Alloc> AllocTraits; + + Alloc& base() { return *this; } + const Alloc& base() const { return *this; } + void swap_base(Alloc& b) { swap(b, this->base()); } + public: - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef Tp* pointer; - typedef const Tp* const_pointer; - typedef Tp& reference; - typedef const Tp& const_reference; - typedef Tp value_type; + typedef typename check_consistent_alloc_value_type<Tp, Alloc>::value_type + value_type; + typedef typename AllocTraits::size_type size_type; + typedef typename AllocTraits::pointer pointer; #if __cplusplus >= 201103L - typedef std::true_type propagate_on_container_swap; + typedef std::true_type propagate_on_container_swap; #endif template<typename Tp1> - struct rebind - { typedef uneq_allocator<Tp1> other; }; + struct rebind + { + typedef uneq_allocator<Tp1, + typename AllocTraits::template rebind<Tp1>::other> other; + }; uneq_allocator() _GLIBCXX_USE_NOEXCEPT : personality(0) { } @@ -272,7 +311,9 @@ namespace __gnu_test : personality(person) { } template<typename Tp1> - uneq_allocator(const uneq_allocator<Tp1>& b) _GLIBCXX_USE_NOEXCEPT + uneq_allocator(const uneq_allocator<Tp1, + typename AllocTraits::template rebind<Tp1>::other>& b) + _GLIBCXX_USE_NOEXCEPT : personality(b.get_personality()) { } ~uneq_allocator() _GLIBCXX_USE_NOEXCEPT @@ -281,20 +322,9 @@ namespace __gnu_test int get_personality() const { return personality; } pointer - address(reference x) const _GLIBCXX_NOEXCEPT - { return std::__addressof(x); } - - const_pointer - address(const_reference x) const _GLIBCXX_NOEXCEPT - { return std::__addressof(x); } - - pointer - allocate(size_type n, const void* = 0) + allocate(size_type n, const void* hint = 0) { - if (__builtin_expect(n > this->max_size(), false)) - std::__throw_bad_alloc(); - - pointer p = static_cast<Tp*>(::operator new(n * sizeof(Tp))); + pointer p = AllocTraits::allocate(*this, n); try { get_map().insert(map_type::value_type(reinterpret_cast<void*>(p), @@ -302,14 +332,14 @@ namespace __gnu_test } catch(...) { - ::operator delete(p); + AllocTraits::deallocate(*this, p, n); __throw_exception_again; } return p; } void - deallocate(pointer p, size_type) + deallocate(pointer p, size_type n) { bool test __attribute__((unused)) = true; @@ -323,34 +353,18 @@ namespace __gnu_test VERIFY( it->second == personality ); get_map().erase(it); - ::operator delete(p); + AllocTraits::deallocate(*this, p, n); } - size_type - max_size() const _GLIBCXX_USE_NOEXCEPT - { return size_type(-1) / sizeof(Tp); } - #if __cplusplus >= 201103L - template<typename U, typename... Args> - void - construct(U* p, Args&&... args) - { ::new((void *)p) U(std::forward<Args>(args)...); } - - template<typename U> - void - destroy(U* p) { p->~U(); } - // Not copy assignable... uneq_allocator& operator=(const uneq_allocator&) = delete; -#else - void - construct(pointer p, const Tp& val) - { ::new((void *)p) Tp(val); } - - void - destroy(pointer p) { p->~Tp(); } + // ... but still moveable if base allocator is. + uneq_allocator& + operator=(uneq_allocator&&) = default; +#else private: // Not assignable... uneq_allocator& @@ -358,31 +372,39 @@ namespace __gnu_test #endif private: - // ... yet swappable! friend inline void swap(uneq_allocator& a, uneq_allocator& b) - { std::swap(a.personality, b.personality); } - + { + std::swap(a.personality, b.personality); + a.swap_base(b); + } + template<typename Tp1> - friend inline bool - operator==(const uneq_allocator& a, const uneq_allocator<Tp1>& b) - { return a.personality == b.personality; } + friend inline bool + operator==(const uneq_allocator& a, + const uneq_allocator<Tp1, + typename AllocTraits::template rebind<Tp1>::other>& b) + { return a.personality == b.personality; } template<typename Tp1> - friend inline bool - operator!=(const uneq_allocator& a, const uneq_allocator<Tp1>& b) - { return !(a == b); } + friend inline bool + operator!=(const uneq_allocator& a, + const uneq_allocator<Tp1, + typename AllocTraits::template rebind<Tp1>::other>& b) + { return !(a == b); } int personality; }; #if __cplusplus >= 201103L // An uneq_allocator which can be used to test allocator propagation. - template<typename Tp, bool Propagate> - class propagating_allocator : public uneq_allocator<Tp> + template<typename Tp, bool Propagate, typename Alloc = std::allocator<Tp>> + class propagating_allocator : public uneq_allocator<Tp, Alloc> { - typedef uneq_allocator<Tp> base_alloc; + typedef __gnu_cxx::__alloc_traits<Alloc> AllocTraits; + + typedef uneq_allocator<Tp, Alloc> base_alloc; base_alloc& base() { return *this; } const base_alloc& base() const { return *this; } void swap_base(base_alloc& b) { swap(b, this->base()); } @@ -393,15 +415,20 @@ namespace __gnu_test // default allocator_traits::rebind_alloc would select // uneq_allocator::rebind so we must define rebind here template<typename Up> - struct rebind { typedef propagating_allocator<Up, Propagate> other; }; + struct rebind + { + typedef propagating_allocator<Up, Propagate, + typename AllocTraits::template rebind<Up>::other> other; + }; propagating_allocator(int i) noexcept : base_alloc(i) { } template<typename Up> - propagating_allocator(const propagating_allocator<Up, Propagate>& a) - noexcept + propagating_allocator(const propagating_allocator<Up, Propagate, + typename AllocTraits::template rebind<Up>::other>& a) + noexcept : base_alloc(a) { } @@ -418,8 +445,8 @@ namespace __gnu_test } template<bool P2> - propagating_allocator& - operator=(const propagating_allocator<Tp, P2>& a) noexcept + propagating_allocator& + operator=(const propagating_allocator<Tp, P2, Alloc>& a) noexcept { static_assert(P2, "assigning propagating_allocator<T, true>"); propagating_allocator(a).swap_base(*this); |