Code

rework maybe so storage is customizable and can be optimized on a
authormental <mental@users.sourceforge.net>
Thu, 8 Mar 2007 23:42:21 +0000 (23:42 +0000)
committermental <mental@users.sourceforge.net>
Thu, 8 Mar 2007 23:42:21 +0000 (23:42 +0000)
per-type basis

src/libnr/nr-maybe.h

index 6749dfc0123bc0ba7d391b0604f33e8e3ff0c343..59e064f34778241770d22a72a25334f9fa664f62 100644 (file)
@@ -26,185 +26,126 @@ public:
 struct Nothing {};
 
 template <typename T>
-class Maybe {
+class MaybeStorage {
 public:
-    Maybe(Nothing) : _is_nothing(true) {}
-    Maybe(T const &t) : _t(t), _is_nothing(false) {}
-    Maybe(Maybe const &m) : _t(m._t), _is_nothing(m._is_nothing) {}
+    MaybeStorage() : _is_nothing(true) {}
+    MaybeStorage(T const &value)
+    : _value(value), _is_nothing(false) {}
 
-    template <typename T2> Maybe(Maybe<T2> const &m)
-    : _is_nothing(!m)
-    {
-        if (m) {
-            _t = *m;
-        }
-    }
+    bool is_nothing() const { return _is_nothing; }
+    T &value() { return _value; }
+    T const &value() const { return _value; }
 
-    template <typename T2> Maybe(T2 const &t)
-    : _t(t), _is_nothing(false) {}
+private:
+    T _value;
+    bool _is_nothing;
+};
 
-    operator bool() const { return !_is_nothing; }
+template <typename T>
+class MaybeStorage<T &> {
+public:
+    MaybeStorage() : _ref(NULL) {}
+    MaybeStorage(T &value) : _ref(&value) {}
 
-    T const &operator*() const throw(IsNothing) {
-        if (_is_nothing) {
-            throw IsNothing();
-        } else {
-            return _t;
-        }
-    }
-    T &operator*() throw(IsNothing) {
-        if (_is_nothing) {
-            throw IsNothing();
-        } else {
-            return _t;
-        }
-    }
+    bool is_nothing() const { return !_ref; }
+    T &value() const { return *_ref; }
 
-    T const *operator->() const throw(IsNothing) {
-        if (_is_nothing) {
-            throw IsNothing();
-        } else {
-            return &_t;
+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;
         }
     }
-    T *operator->() throw(IsNothing) {
-        if (_is_nothing) {
-            throw IsNothing();
-        } else {
-            return &_t;
+    template <typename T2>
+    Maybe(Maybe<T2> const &m) {
+        if (m) {
+            _storage = *m;
         }
     }
 
     template <typename T2>
-    bool operator==(NR::Maybe<T2> const &other) const {
-        if ( _is_nothing || !other ) {
-            return _is_nothing && !other;
-        } else {
-            return _t == *other;
+    Maybe(Maybe<T2 &> m) {
+        if (m) {
+            _storage = *m;
         }
     }
     template <typename T2>
-    bool operator!=(NR::Maybe<T2> const &other) const {
-        if ( _is_nothing || !other ) {
-            return !_is_nothing || other;
-        } else {
-            return _t != *other;
-        }
-    }
-
-private:
-    T _t;
-    bool _is_nothing;
-};
-
-template <typename T>
-class Maybe<T const> {
-public:
-    Maybe(Nothing) : _is_nothing(true) {}
-    Maybe(T const &t) : _t(t), _is_nothing(false) {}
-    Maybe(Maybe const &m) : _t(m._t), _is_nothing(m._is_nothing) {}
-
-    template <typename T2> Maybe(Maybe<T2> const &m)
-    : _is_nothing(!m)
-    {
+    Maybe(Maybe<T2 const &> m) {
         if (m) {
-            _t = *m;
+            _storage = *m;
         }
     }
 
-    template <typename T2> Maybe(T2 const &t)
-    : _t(t), _is_nothing(false) {}
-
-    operator bool() const { return !_is_nothing; }
+    operator bool() const { return !_storage.is_nothing(); }
 
     T const &operator*() const throw(IsNothing) {
-        if (_is_nothing) {
+        if (_storage.is_nothing()) {
             throw IsNothing();
         } else {
-            return _t;
+            return _storage.value();
         }
     }
-
-    T const *operator->() const throw(IsNothing) {
-        if (_is_nothing) {
+    T &operator*() throw(IsNothing) {
+        if (_storage.is_nothing()) {
             throw IsNothing();
         } else {
-            return &_t;
-        }
-    }
-
-    template <typename T2>
-    bool operator==(NR::Maybe<T2> const &other) const {
-        if ( _is_nothing || !other ) {
-            return _is_nothing && !other;
-        } else {
-            return _t == *other;
+            return _storage.value();
         }
     }
-    template <typename T2>
-    bool operator!=(NR::Maybe<T2> const &other) const {
-        if ( _is_nothing || !other ) {
-            return !_is_nothing || other;
-        } else {
-            return _t != *other;
-        }
-    }
-
-private:
-    T const _t;
-    bool _is_nothing;
-};
 
-template <typename T>
-class Maybe<T &> {
-public:
-    Maybe(Nothing) : _ref(NULL) {}
-    Maybe(T &t) : _ref(&t) {}
-    Maybe(Maybe const &m) : _ref(m._ref) {}
-
-    template <typename T2> Maybe(Maybe<T2> const &m)
-    : _ref( m ? &*m : NULL ) {}
-    template <typename T2> Maybe(T2 &t) : _ref(&t) {}
-
-    operator bool() const { return _ref; }
-
-    T &operator*() const throw(IsNothing) {
-        if (_ref) {
+    T const *operator->() const throw(IsNothing) {
+        if (_storage.is_nothing()) {
             throw IsNothing();
         } else {
-            return *_ref;
+            return &_storage.value();
         }
     }
-
-    T *operator->() const throw(IsNothing) {
-        if (_ref) {
+    T *operator->() throw(IsNothing) {
+        if (_storage.is_nothing()) {
             throw IsNothing();
         } else {
-            return _ref;
+            return &_storage.value();
         }
     }
 
     template <typename T2>
     bool operator==(NR::Maybe<T2> const &other) const {
-        if ( !_ref || !other ) {
-            return !_ref && !other;
+        bool is_nothing = _storage.is_nothing();
+        if ( is_nothing || !other ) {
+            return is_nothing && !other;
         } else {
-            return *_ref == *other;
+            return _storage.value() == *other;
         }
     }
     template <typename T2>
     bool operator!=(NR::Maybe<T2> const &other) const {
-        if ( !_ref || !other ) {
-            return _ref || other;
+        bool is_nothing = _storage.is_nothing();
+        if ( is_nothing || !other ) {
+            return !is_nothing || other;
         } else {
-            return *_ref != *other;
+            return _storage.value() != *other;
         }
     }
 
 private:
-    void operator=(Maybe const &); // no assign
-
-    T *_ref;
+    MaybeStorage<T> _storage;
 };
 
 } /* namespace NR */