Browse Source

Stop using macros to define pointer comparators.

Sam Jaffe 5 years ago
parent
commit
69706fc294

+ 4 - 3
include/pointers/const_propogating_ptr.hpp

@@ -11,7 +11,10 @@
 #include "pointer_fwd.hpp"
 #include "ptr_compare.hpp"
 
-template <typename P> class const_propogating_ptr : private detail::get_ptr<P> {
+template <typename P>
+class const_propogating_ptr
+    : private detail::get_ptr<P>,
+      public detail::pointer_compare<const_propogating_ptr<P>> {
 public:
   using element_type = typename std::pointer_traits<P>::element_type;
   using pointer = element_type *;
@@ -74,5 +77,3 @@ public:
 private:
   P _ptr;
 };
-
-POINTER_TEMPLATE_COMPARE(const_propogating_ptr)

+ 3 - 3
include/pointers/const_ptr.hpp

@@ -11,7 +11,9 @@
 #include "pointer_fwd.hpp"
 #include "ptr_compare.hpp"
 
-template <typename P> class const_ptr : private detail::get_ptr<P> {
+template <typename P>
+class const_ptr : private detail::get_ptr<P>,
+                  public detail::pointer_compare<const_ptr<P>> {
 public:
   using element_type = typename std::pointer_traits<P>::element_type;
   using pointer = element_type const *;
@@ -44,5 +46,3 @@ public:
 private:
   P _ptr;
 };
-
-POINTER_TEMPLATE_COMPARE(const_ptr)

+ 3 - 2
include/pointers/maybe_null.hpp

@@ -25,7 +25,9 @@ template <typename P> class maybe_null<not_null<P>>; // not permitted
 #define set_tested(_)
 #endif
 
-template <typename P> class maybe_null : private detail::get_ptr<P> {
+template <typename P>
+class maybe_null : private detail::get_ptr<P>,
+                   public detail::pointer_compare<maybe_null<P>> {
 public:
   using element_type = typename std::pointer_traits<P>::element_type;
   using pointer = element_type *;
@@ -90,4 +92,3 @@ private:
 };
 
 #undef set_tested
-POINTER_TEMPLATE_COMPARE(maybe_null)

+ 2 - 3
include/pointers/not_null.hpp

@@ -17,7 +17,8 @@
 template <typename P>
 class not_null<std::weak_ptr<P>>; // A weak_ptr cannot be a not_null
 
-template <typename P> class not_null {
+template <typename P>
+class not_null : public detail::pointer_compare<not_null<P>> {
 public:
   using element_type = typename std::pointer_traits<P>::element_type;
   using pointer = element_type *;
@@ -71,5 +72,3 @@ private:
   }
   P _ptr;
 };
-
-POINTER_TEMPLATE_COMPARE(not_null)

+ 50 - 106
include/pointers/ptr_compare.hpp

@@ -7,109 +7,53 @@
 
 #pragma once
 
-#define POINTER_TEMPLATE_COMPARE(ptr_t)                                        \
-  POINTER_TEMPLATE_COMPARE_FULL(ptr_t, (typename T), (T), (typename U), (U))
-
-#define EXPAND(...) __VA_ARGS__
-
-#define POINTER_TEMPLATE_COMPARE_FULL(ptr_t, T_tname, T, U_tname, U)           \
-  template <EXPAND T_tname, EXPAND U_tname>                                    \
-  bool operator==(ptr_t<EXPAND T> const & lhs,                                 \
-                  ptr_t<EXPAND U> const & rhs) noexcept {                      \
-    return lhs.get() == rhs.get();                                             \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname, EXPAND U_tname>                                    \
-  bool operator!=(ptr_t<EXPAND T> const & lhs,                                 \
-                  ptr_t<EXPAND U> const & rhs) noexcept {                      \
-    return !(lhs == rhs);                                                      \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname, EXPAND U_tname>                                    \
-  bool operator<(ptr_t<EXPAND T> const & lhs,                                  \
-                 ptr_t<EXPAND U> const & rhs) noexcept {                       \
-    typedef                                                                    \
-        typename std::common_type<typename ptr_t<EXPAND T>::pointer,           \
-                                  typename ptr_t<EXPAND U>::pointer>::type V;  \
-    return std::less<V>(lhs.get(), rhs.get());                                 \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname, EXPAND U_tname>                                    \
-  bool operator>(ptr_t<EXPAND T> const & lhs,                                  \
-                 ptr_t<EXPAND U> const & rhs) noexcept {                       \
-    return rhs < lhs;                                                          \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname, EXPAND U_tname>                                    \
-  bool operator<=(ptr_t<EXPAND T> const & lhs,                                 \
-                  ptr_t<EXPAND U> const & rhs) noexcept {                      \
-    return !(rhs < lhs);                                                       \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname, EXPAND U_tname>                                    \
-  bool operator>=(ptr_t<EXPAND T> const & lhs,                                 \
-                  ptr_t<EXPAND U> const & rhs) noexcept {                      \
-    return !(lhs < rhs);                                                       \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator==(ptr_t<EXPAND T> const & lhs, std::nullptr_t) noexcept {      \
-    return !lhs;                                                               \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator==(std::nullptr_t, ptr_t<EXPAND T> const & rhs) noexcept {      \
-    return !rhs;                                                               \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator!=(ptr_t<EXPAND T> const & lhs, std::nullptr_t) noexcept {      \
-    return static_cast<bool>(lhs);                                             \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator!=(std::nullptr_t, ptr_t<EXPAND T> const & rhs) noexcept {      \
-    return static_cast<bool>(rhs);                                             \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator<(ptr_t<EXPAND T> const & lhs, std::nullptr_t) noexcept {       \
-    typedef typename ptr_t<EXPAND T>::pointer V;                               \
-    return std::less<V>(lhs.get(), nullptr);                                   \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator<(std::nullptr_t, ptr_t<EXPAND T> const & rhs) noexcept {       \
-    typedef typename ptr_t<EXPAND T>::pointer V;                               \
-    return std::less<V>(nullptr, rhs.get());                                   \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator>(ptr_t<EXPAND T> const & lhs, std::nullptr_t) noexcept {       \
-    return nullptr < lhs;                                                      \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator>(std::nullptr_t, ptr_t<EXPAND T> const & rhs) noexcept {       \
-    return rhs < nullptr;                                                      \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator<=(ptr_t<EXPAND T> const & lhs, std::nullptr_t) noexcept {      \
-    return !(nullptr < lhs);                                                   \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator<=(std::nullptr_t, ptr_t<EXPAND T> const & rhs) noexcept {      \
-    return !(rhs < nullptr);                                                   \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator>=(ptr_t<EXPAND T> const & lhs, std::nullptr_t) noexcept {      \
-    return !(lhs < nullptr);                                                   \
-  }                                                                            \
-                                                                               \
-  template <EXPAND T_tname>                                                    \
-  bool operator>=(std::nullptr_t, ptr_t<EXPAND T> const & rhs) noexcept {      \
-    return !(nullptr < rhs);                                                   \
-  }
+namespace detail {
+  template <typename Self> struct pointer_compare {
+    friend bool operator==(Self const & lhs, Self const & rhs) {
+      return lhs.get() == rhs.get();
+    }
+    friend bool operator<(Self const & lhs, Self const & rhs) {
+      return lhs.get() < rhs.get();
+    }
+    friend bool operator!=(Self const & lhs, Self const & rhs) {
+      return !(lhs == rhs);
+    }
+    friend bool operator>(Self const & lhs, Self const & rhs) {
+      return rhs < lhs;
+    }
+    friend bool operator<=(Self const & lhs, Self const & rhs) {
+      return !(rhs < lhs);
+    }
+    friend bool operator>=(Self const & lhs, Self const & rhs) {
+      return !(lhs < rhs);
+    }
+    friend bool operator==(Self const & lhs, std::nullptr_t) { return !lhs; }
+    friend bool operator<(Self const & lhs, std::nullptr_t) {
+      return lhs.get() < nullptr;
+    }
+    friend bool operator!=(Self const & lhs, std::nullptr_t) { return !!lhs; }
+    friend bool operator>(Self const & lhs, std::nullptr_t) {
+      return nullptr < lhs;
+    }
+    friend bool operator<=(Self const & lhs, std::nullptr_t) {
+      return !(nullptr < lhs);
+    }
+    friend bool operator>=(Self const & lhs, std::nullptr_t) {
+      return !(lhs < nullptr);
+    }
+    friend bool operator==(std::nullptr_t, Self const & rhs) { return !rhs; }
+    friend bool operator<(std::nullptr_t, Self const & rhs) {
+      return nullptr < rhs.get();
+    }
+    friend bool operator!=(std::nullptr_t, Self const & rhs) { return !!rhs; }
+    friend bool operator>(std::nullptr_t, Self const & rhs) {
+      return rhs < nullptr;
+    }
+    friend bool operator<=(std::nullptr_t, Self const & rhs) {
+      return !(rhs < nullptr);
+    }
+    friend bool operator>=(std::nullptr_t, Self const & rhs) {
+      return !(nullptr < rhs);
+    }
+  };
+}

+ 3 - 3
include/pointers/value_ptr.hpp

@@ -37,7 +37,9 @@ namespace detail {
   POLYMORPHIC_VALUE_PTR_GROUP_FROM_CLONE_FUNCTION(copy);
 }
 
-template <typename T> class value_ptr : private detail::value_ptr_copy<T> {
+template <typename T>
+class value_ptr : private detail::value_ptr_copy<T>,
+                  public detail::pointer_compare<value_ptr<T>> {
 public:
   using element_type = T;
   using pointer = element_type *;
@@ -91,5 +93,3 @@ template <typename T, typename... Args>
 value_ptr<T> make_value(Args &&... args) {
   return value_ptr<T>(new T(std::forward<Args>(args)...));
 }
-
-POINTER_TEMPLATE_COMPARE(value_ptr)