Code

fix reference maybes by separate specialization
authormental <mental@users.sourceforge.net>
Fri, 9 Mar 2007 00:25:36 +0000 (00:25 +0000)
committermental <mental@users.sourceforge.net>
Fri, 9 Mar 2007 00:25:36 +0000 (00:25 +0000)
src/libnr/nr-maybe.h

index 59e064f34778241770d22a72a25334f9fa664f62..94078c211b757b889cae027609cca3bc59a1ba4b 100644 (file)
@@ -41,38 +41,14 @@ private:
     bool _is_nothing;
 };
 
-template <typename T>
-class MaybeStorage<T &> {
-public:
-    MaybeStorage() : _ref(NULL) {}
-    MaybeStorage(T &value) : _ref(&value) {}
-
-    bool is_nothing() const { return !_ref; }
-    T &value() const { return *_ref; }
-
-private:
-    T *_ref;
-};
-
 template <typename T>
 class Maybe {
 public:
     Maybe() {}
-
     Maybe(Nothing) {}
-
-    Maybe(T &t) : _storage(t) {}
     Maybe(T const &t) : _storage(t) {}
-
-    Maybe(Maybe &m) : _storage(m._storage) {}
     Maybe(Maybe const &m) : _storage(m._storage) {}
 
-    template <typename T2>
-    Maybe(Maybe<T2> &m) {
-        if (m) {
-            _storage = *m;
-        }
-    }
     template <typename T2>
     Maybe(Maybe<T2> const &m) {
         if (m) {
@@ -80,12 +56,6 @@ public:
         }
     }
 
-    template <typename T2>
-    Maybe(Maybe<T2 &> m) {
-        if (m) {
-            _storage = *m;
-        }
-    }
     template <typename T2>
     Maybe(Maybe<T2 const &> m) {
         if (m) {
@@ -126,7 +96,7 @@ public:
     }
 
     template <typename T2>
-    bool operator==(NR::Maybe<T2> const &other) const {
+    bool operator==(Maybe<T2> const &other) const {
         bool is_nothing = _storage.is_nothing();
         if ( is_nothing || !other ) {
             return is_nothing && !other;
@@ -135,7 +105,7 @@ public:
         }
     }
     template <typename T2>
-    bool operator!=(NR::Maybe<T2> const &other) const {
+    bool operator!=(Maybe<T2> const &other) const {
         bool is_nothing = _storage.is_nothing();
         if ( is_nothing || !other ) {
             return !is_nothing || other;
@@ -148,6 +118,72 @@ private:
     MaybeStorage<T> _storage;
 };
 
+template <typename T>
+class Maybe<T &> {
+public:
+    Maybe() : _ref(NULL) {}
+    Maybe(Nothing) : _ref(NULL) {}
+    Maybe(T &t) : _ref(&t) {}
+
+    template <typename T2>
+    Maybe(Maybe<T2> const &m) {
+        if (m) {
+            _ref = &*m;
+        } 
+    }
+
+    template <typename T2>
+    Maybe(Maybe<T2 &> m) {
+        if (m) {
+            _ref = *m;
+        }
+    }
+
+    template <typename T2>
+    Maybe(Maybe<T2 const &> m) {
+        if (m) {
+            _ref = *m;
+        }
+    }
+
+    operator bool() const { return _ref; }
+
+    T &operator*() const throw(IsNothing) {
+        if (!_ref) {
+            throw IsNothing();
+        } else {
+            return *_ref;
+        }
+    }
+    T *operator->() const throw(IsNothing) {
+        if (!_ref) {
+            throw IsNothing();
+        } else {
+            return _ref;
+        }
+    }
+
+    template <typename T2>
+    bool operator==(Maybe<T2> const &other) const {
+        if ( !_ref || !other ) {
+            return !_ref && !other;
+        } else {
+            return *_ref == *other;
+        }
+    }
+    template <typename T2>
+    bool operator!=(Maybe <T2> const &other) const {
+        if ( !_ref || !other ) {
+            return _ref || other;
+        } else {
+            return *_ref != *other;
+        }
+    }
+
+private:
+    T *_ref;
+};
+
 } /* namespace NR */
 
 #endif