ソースを参照

Updating maybe_null and not_null.

not_null now demotes to maybe_null with an operator type(), instead of a constructor.
Fixing various operators. Removing varargs constructor.
Samuel Jaffe 9 年 前
コミット
d043a50a6d
2 ファイル変更31 行追加31 行削除
  1. 16 24
      maybe_null.hpp
  2. 15 7
      not_null.hpp

+ 16 - 24
maybe_null.hpp

@@ -13,8 +13,6 @@
 
 #include "pointer_fwd.hpp"
 
-#include "not_null.hpp"
-
 class unchecked_pointer_exception : public std::logic_error {
   using std::logic_error::logic_error;
 };
@@ -29,16 +27,19 @@ public:
   using reference = element_type &;
   
   maybe_null() : _ptr(nullptr) {}
-  template <typename... Args> maybe_null(Args && ...args) : _ptr(std::forward<Args>(args)...) { }
+  maybe_null(T const & p) : _ptr(p) { }
+  maybe_null(T && p) : _ptr(std::move(p)) { }
   maybe_null(maybe_null const&) = default;
-  template <typename Y> maybe_null(maybe_null<Y> const& other) : _ptr(other.ptr_) { }
-  template <typename Y> maybe_null(not_null<Y> const& other) : _ptr(other.get()) { }
   
-  maybe_null& operator=(T ptr) { return operator=(maybe_null<T>(ptr)); }
+  template <typename Y>
+  explicit operator maybe_null<Y>() const {
+    return _ptr;
+  }
+  
   maybe_null& operator=(maybe_null const&) = default;
   template <typename Y> maybe_null& operator=(maybe_null<Y> const&other) {
-    if (_ptr != other.get()) {
-      _ptr = other.get();
+    if (_ptr != other._ptr) {
+      _ptr = other._ptr;
 #if defined( DEBUG )
       tested_ = other.tested_;
 #endif
@@ -46,34 +47,25 @@ public:
     return *this;
   }
   
-  template <typename Y> maybe_null& operator=(not_null<Y> const&other) {
-    _ptr = other.get();
-#if defined( DEBUG )
-    tested_ = true;
-#endif
-    return *this;
-  }
-  
-  
   operator bool() const {
 #if defined( DEBUG )
     tested_ = true;
 #endif
-    return bool(_ptr);
+    return static_cast<bool>(_ptr);
   }
   
-  pointer get() const {
+  pointer get() const { return std::addressof(*_ptr); }
+  pointer operator->() const {
+    return std::addressof(operator*());
+  }
+  reference operator*() const {
 #if defined( DEBUG )
     if ( !tested_ ) {
       throw unchecked_pointer_exception{"did not verify that pointer was non-null"};
     }
 #endif
-    return std::addressof(operator*());
+    return *_ptr;
   }
-  //  operator T() const { return get(); }
-  pointer operator->() const { return get(); }
-  reference operator*() const { return *_ptr; }
-  
   bool operator==(maybe_null const&rhs) const { return _ptr == rhs._ptr; }
   bool operator!=(maybe_null const&rhs) const { return _ptr != rhs._ptr; }
   bool operator<=(maybe_null const&rhs) const { return _ptr <= rhs._ptr; }

+ 15 - 7
not_null.hpp

@@ -12,6 +12,7 @@
 #include <memory>
 
 #include "pointer_fwd.hpp"
+#include "maybe_null.hpp"
 
 class null_pointer_exception : public std::invalid_argument {
   using std::invalid_argument::invalid_argument;
@@ -28,19 +29,26 @@ public:
   
   explicit not_null(std::nullptr_t) = delete;
   explicit not_null(int) = delete;
-  not_null(T p) : _ptr(p) { validate(); }
+  not_null(T const & p) : _ptr(p) { validate(); }
+  not_null(T && p) : _ptr(std::move(p)) { validate(); }
   not_null(not_null const&) = default;
-  template <typename Y> not_null(not_null<Y> const& other) : _ptr(other.get()) { }
-  
-  not_null& operator=(std::nullptr_t) = delete;
-  not_null& operator=(int) = delete;
-  not_null& operator=(T ptr) { return operator=(not_null<T>(ptr)); }
+
+  template <typename Y>
+  explicit operator maybe_null<Y>() const {
+    return _ptr;
+  }
+  template <typename Y>
+  explicit operator not_null<Y>() const {
+    return _ptr;
+  }
+
   not_null& operator=(not_null const&) = default;
   template <typename Y> not_null& operator=(not_null<Y> const&other) {
-    _ptr = other.get();
+    _ptr = other._ptr;
     return *this;
   }
   
+  explicit operator maybe_null<T>() const;
   operator bool() const { return true; }
   
   pointer get() const { return std::addressof(operator*()); }