aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-05-14 12:17:23 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2019-05-14 12:17:23 +0100
commit066f9ea27960c21b73be820f2bcd62d0c2f3d6b8 (patch)
tree9f674a88bead34cd63d66f7cec0486bfe3f6a4ed
parente25f488d603a6bd7570c1ffdfd9572e4b8a645de (diff)
downloadgcc-066f9ea27960c21b73be820f2bcd62d0c2f3d6b8.zip
gcc-066f9ea27960c21b73be820f2bcd62d0c2f3d6b8.tar.gz
gcc-066f9ea27960c21b73be820f2bcd62d0c2f3d6b8.tar.bz2
Add __gnu_test::NullablePointer utility to testsuite
* testsuite/20_util/allocator_traits/members/allocate_hint_nonpod.cc: Use operator-> to access raw pointer member. * testsuite/23_containers/vector/59829.cc: Likewise. * testsuite/23_containers/vector/bool/80893.cc: Likewise. * testsuite/libstdc++-prettyprinters/cxx11.cc: Use NullablePointer. * testsuite/util/testsuite_allocator.h (NullablePointer): New utility for tests. (PointerBase, PointerBase_void): Derive from NullablePointer and use its constructors and equality operators. Change converting constructors to use operator-> to access private member of the other pointer type. (PointerBase_void::operator->()): Add, for access to private member. (operator-(PointerBase, PointerBase)): Change to hidden friend. (operator==(PointerBase, PointerBase)): Remove. (operator!=(PointerBase, PointerBase)): Remove. From-SVN: r271160
-rw-r--r--libstdc++-v3/ChangeLog16
-rw-r--r--libstdc++-v3/testsuite/20_util/allocator_traits/members/allocate_hint_nonpod.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/59829.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/bool/80893.cc2
-rw-r--r--libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc25
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_allocator.h120
6 files changed, 111 insertions, 56 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index b6061f4..6578a33 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,21 @@
2019-05-14 Jonathan Wakely <jwakely@redhat.com>
+ * testsuite/20_util/allocator_traits/members/allocate_hint_nonpod.cc:
+ Use operator-> to access raw pointer member.
+ * testsuite/23_containers/vector/59829.cc: Likewise.
+ * testsuite/23_containers/vector/bool/80893.cc: Likewise.
+ * testsuite/libstdc++-prettyprinters/cxx11.cc: Use NullablePointer.
+ * testsuite/util/testsuite_allocator.h (NullablePointer): New utility
+ for tests.
+ (PointerBase, PointerBase_void): Derive from NullablePointer and use
+ its constructors and equality operators. Change converting
+ constructors to use operator-> to access private member of the other
+ pointer type.
+ (PointerBase_void::operator->()): Add, for access to private member.
+ (operator-(PointerBase, PointerBase)): Change to hidden friend.
+ (operator==(PointerBase, PointerBase)): Remove.
+ (operator!=(PointerBase, PointerBase)): Remove.
+
* python/libstdcxx/v6/printers.py (UniquePointerPrinter.__init__): Do
not assume field called _M_head_impl is the first tuple element.
* testsuite/libstdc++-prettyprinters/compat.cc: Make tuple
diff --git a/libstdc++-v3/testsuite/20_util/allocator_traits/members/allocate_hint_nonpod.cc b/libstdc++-v3/testsuite/20_util/allocator_traits/members/allocate_hint_nonpod.cc
index a5e2a26..f9193e8 100644
--- a/libstdc++-v3/testsuite/20_util/allocator_traits/members/allocate_hint_nonpod.cc
+++ b/libstdc++-v3/testsuite/20_util/allocator_traits/members/allocate_hint_nonpod.cc
@@ -45,7 +45,7 @@ struct Alloc
{ return pointer(std::allocator<T>().allocate(n)); }
void deallocate(pointer p, std::size_t n)
- { std::allocator<T>().deallocate(p.value, n); }
+ { std::allocator<T>().deallocate(p.operator->(), n); }
};
template<typename T>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/59829.cc b/libstdc++-v3/testsuite/23_containers/vector/59829.cc
index 0e053fa..892b905 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/59829.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/59829.cc
@@ -51,7 +51,7 @@ struct Alloc
{ return pointer(std::allocator<T>().allocate(n)); }
void deallocate(pointer p, std::size_t n)
- { std::allocator<T>().deallocate(p.value, n); }
+ { std::allocator<T>().deallocate(p.operator->(), n); }
};
template<typename T>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/80893.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/80893.cc
index f44cdc4..08b15c8 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/bool/80893.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/80893.cc
@@ -59,7 +59,7 @@ struct Alloc
void deallocate(pointer p, std::size_t n)
{
if (n)
- std::allocator<T>().deallocate(p.value, n);
+ std::allocator<T>().deallocate(p.operator->(), n);
}
};
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
index cc58812..c87c803 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
@@ -24,6 +24,7 @@
#include <string>
#include <memory>
#include <iostream>
+#include "../util/testsuite_allocator.h" // NullablePointer
typedef std::tuple<int, int> ExTuple;
@@ -59,21 +60,6 @@ struct datum
std::unique_ptr<datum> global;
-struct Deleter
-{
- // Deleter is not an empty class:
- int deleter_member = -1;
- // But pointer is an empty class:
- struct pointer
- {
- pointer(const void* = nullptr) { }
- explicit operator bool() const noexcept { return false; }
- friend bool operator==(pointer, pointer) noexcept { return true; }
- friend bool operator!=(pointer, pointer) noexcept { return false; }
- };
- void operator()(pointer) const noexcept { }
-};
-
int
main()
{
@@ -151,6 +137,15 @@ main()
std::unique_ptr<data>& rarrptr = arrptr;
// { dg-final { regexp-test rarrptr {std::unique_ptr.datum \[\]. = {get\(\) = 0x.*}} } }
+ struct Deleter
+ {
+ int deleter_member = -1;
+ using pointer = __gnu_test::NullablePointer<void>;
+ void operator()(pointer) const noexcept { }
+ };
+ static_assert( !std::is_empty<Deleter>(), "Deleter is not empty" );
+ static_assert( std::is_empty<Deleter::pointer>(), "but pointer is empty" );
+
std::unique_ptr<int, Deleter> empty_ptr;
// { dg-final { note-test empty_ptr {std::unique_ptr<int> = {get() = {<No data fields>}}} } }
std::unique_ptr<int, Deleter>& rempty_ptr = empty_ptr;
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index 0392421..428c082 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -589,9 +589,54 @@ namespace __gnu_test
{ std::allocator<Tp>::deallocate(std::addressof(*p), n); }
};
+ // A class type meeting *only* the Cpp17NullablePointer requirements.
+ // Can be used as a base class for fancy pointers (like PointerBase, below)
+ // or to wrap a built-in pointer type to remove operations not required
+ // by the Cpp17NullablePointer requirements (dereference, increment etc.)
+ template<typename Ptr>
+ struct NullablePointer
+ {
+ // N.B. default constructor does not initialize value
+ NullablePointer() = default;
+ NullablePointer(std::nullptr_t) noexcept : value() { }
+
+ explicit operator bool() const noexcept { return value == nullptr; }
+
+ friend inline bool
+ operator==(NullablePointer lhs, NullablePointer rhs) noexcept
+ { return lhs.value == rhs.value; }
+
+ friend inline bool
+ operator!=(NullablePointer lhs, NullablePointer rhs) noexcept
+ { return lhs.value != rhs.value; }
+
+ protected:
+ explicit NullablePointer(Ptr p) noexcept : value(p) { }
+ Ptr value;
+ };
+
+ // NullablePointer<void> is an empty type that models Cpp17NullablePointer.
+ template<>
+ struct NullablePointer<void>
+ {
+ NullablePointer() = default;
+ NullablePointer(std::nullptr_t) noexcept { }
+ explicit NullablePointer(const volatile void*) noexcept { }
+
+ explicit operator bool() const noexcept { return false; }
+
+ friend inline bool
+ operator==(NullablePointer, NullablePointer) noexcept
+ { return true; }
+
+ friend inline bool
+ operator!=(NullablePointer, NullablePointer) noexcept
+ { return false; }
+ };
+
// Utility for use as CRTP base class of custom pointer types
template<typename Derived, typename T>
- struct PointerBase
+ struct PointerBase : NullablePointer<T*>
{
typedef T element_type;
@@ -602,29 +647,38 @@ namespace __gnu_test
typedef Derived pointer;
typedef T& reference;
- T* value;
+ using NullablePointer<T*>::NullablePointer;
- explicit PointerBase(T* p = nullptr) : value(p) { }
-
- PointerBase(std::nullptr_t) : value(nullptr) { }
+ // Public (but explicit) constructor from raw pointer:
+ explicit PointerBase(T* p) noexcept : NullablePointer<T*>(p) { }
template<typename D, typename U,
typename = decltype(static_cast<T*>(std::declval<U*>()))>
- PointerBase(const PointerBase<D, U>& p) : value(p.value) { }
+ PointerBase(const PointerBase<D, U>& p)
+ : NullablePointer<T*>(p.operator->()) { }
+
+ T& operator*() const { return *this->value; }
+ T* operator->() const { return this->value; }
+ T& operator[](difference_type n) const { return this->value[n]; }
- T& operator*() const { return *value; }
- T* operator->() const { return value; }
- T& operator[](difference_type n) const { return value[n]; }
+ Derived& operator++() { ++this->value; return derived(); }
+ Derived& operator--() { --this->value; return derived(); }
- Derived& operator++() { ++value; return derived(); }
- Derived operator++(int) { Derived tmp(derived()); ++value; return tmp; }
- Derived& operator--() { --value; return derived(); }
- Derived operator--(int) { Derived tmp(derived()); --value; return tmp; }
+ Derived operator++(int) { return Derived(this->value++); }
- Derived& operator+=(difference_type n) { value += n; return derived(); }
- Derived& operator-=(difference_type n) { value -= n; return derived(); }
+ Derived operator--(int) { return Derived(this->value--); }
- explicit operator bool() const { return value != nullptr; }
+ Derived& operator+=(difference_type n)
+ {
+ this->value += n;
+ return derived();
+ }
+
+ Derived& operator-=(difference_type n)
+ {
+ this->value -= n;
+ return derived();
+ }
Derived
operator+(difference_type n) const
@@ -641,6 +695,9 @@ namespace __gnu_test
}
private:
+ friend std::ptrdiff_t operator-(PointerBase l, PointerBase r)
+ { return l.value - r.value; }
+
Derived&
derived() { return static_cast<Derived&>(*this); }
@@ -648,21 +705,9 @@ namespace __gnu_test
derived() const { return static_cast<const Derived&>(*this); }
};
- template<typename D, typename T>
- std::ptrdiff_t operator-(PointerBase<D, T> l, PointerBase<D, T> r)
- { return l.value - r.value; }
-
- template<typename D, typename T>
- bool operator==(PointerBase<D, T> l, PointerBase<D, T> r)
- { return l.value == r.value; }
-
- template<typename D, typename T>
- bool operator!=(PointerBase<D, T> l, PointerBase<D, T> r)
- { return l.value != r.value; }
-
- // implementation for void specializations
- template<typename T>
- struct PointerBase_void
+ // implementation for pointer-to-void specializations
+ template<typename T>
+ struct PointerBase_void : NullablePointer<T*>
{
typedef T element_type;
@@ -671,25 +716,24 @@ namespace __gnu_test
typedef std::ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
- T* value;
+ using NullablePointer<T*>::NullablePointer;
- explicit PointerBase_void(T* p = nullptr) : value(p) { }
+ T* operator->() const { return this->value; }
template<typename D, typename U,
typename = decltype(static_cast<T*>(std::declval<U*>()))>
- PointerBase_void(const PointerBase<D, U>& p) : value(p.value) { }
-
- explicit operator bool() const { return value != nullptr; }
+ PointerBase_void(const PointerBase<D, U>& p)
+ : NullablePointer<T*>(p.operator->()) { }
};
- template<typename Derived>
+ template<typename Derived>
struct PointerBase<Derived, void> : PointerBase_void<void>
{
using PointerBase_void::PointerBase_void;
typedef Derived pointer;
};
- template<typename Derived>
+ template<typename Derived>
struct PointerBase<Derived, const void> : PointerBase_void<const void>
{
using PointerBase_void::PointerBase_void;