]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add __gnu_test::NullablePointer utility to testsuite
authorJonathan Wakely <jwakely@redhat.com>
Tue, 14 May 2019 11:17:23 +0000 (12:17 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 14 May 2019 11:17:23 +0000 (12:17 +0100)
* 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

libstdc++-v3/ChangeLog
libstdc++-v3/testsuite/20_util/allocator_traits/members/allocate_hint_nonpod.cc
libstdc++-v3/testsuite/23_containers/vector/59829.cc
libstdc++-v3/testsuite/23_containers/vector/bool/80893.cc
libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
libstdc++-v3/testsuite/util/testsuite_allocator.h

index b6061f406cb84a2dba2f6e4d09d296b0d0dac1f4..6578a337b9e2e6503fe86bda0f593546fe89ac92 100644 (file)
@@ -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
index a5e2a269a15a281a92450e4d8cfa81dffb886bde..f9193e83e94a912b58540f617b25e35be6fee237 100644 (file)
@@ -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>
index 0e053fa66273156746ab3e134bbd28d010a5bb05..892b9055eb40b4499dbb221df56876c67435b126 100644 (file)
@@ -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>
index f44cdc4a75e9eef18953d663f99f9b6a515526a6..08b15c8d2dad11f56b8337c31408c6b4092cbb59 100644 (file)
@@ -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);
   }
 };
 
index cc588125bdcc89d486432346ab8ee05816f50661..c87c8035c458f8784cb9f8050e08fe1c31cbd44f 100644 (file)
@@ -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;
index 0392421ca041ad6d4bed122f2f0bcaf7e049ed77..428c0823395fbd361c11b4fbba63d4d5736c0810 100644 (file)
@@ -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;