Code

redo NR::Maybe to be less clever
authormental <mental@users.sourceforge.net>
Sun, 4 Mar 2007 04:23:10 +0000 (04:23 +0000)
committermental <mental@users.sourceforge.net>
Sun, 4 Mar 2007 04:23:10 +0000 (04:23 +0000)
src/libnr/nr-maybe.h
src/object-snapper.cpp
src/shape-editor.cpp

index 9c1aa07081fbf9fb45ea61a6cdd0e749ff80c11e..917323d3f00d2c743c8d98721bf759bbd6507be6 100644 (file)
@@ -2,12 +2,9 @@
 #define __NR_MAYBE_H__
 
 /*
- * Functionalesque "Maybe" class
+ * Nullable values for C++
  *
- * Copyright 2004  MenTaLguY
- *
- * Authors:
- *   MenTaLguY <mental@rydia.net>
+ * Copyright 2004, 2006  MenTaLguY <mental@rydia.net>
  *
  * This code is licensed under the GNU GPL; see COPYING for more information.
  */
 #endif
 
 #include <stdexcept>
-#include <typeinfo>
 #include <string>
 
 namespace NR {
 
-/** An exception class for run-time type errors */
-template <typename T>
-class IsNot : public std::domain_error {
+class IsNothing : public std::domain_error {
 public:
-    IsNot() : domain_error(std::string("Is not ") + typeid(T).name()) {}
+    IsNothing() : domain_error(std::string("Is nothing")) {}
 };
 
 struct Nothing {};
 
-template <typename T>
-struct MaybeTraits;
-
 template <typename T>
 class Maybe {
 public:
-    typedef MaybeTraits<T> traits;
-    typedef typename traits::storage storage;
-    typedef typename traits::pointer pointer;
-    typedef typename traits::reference reference;
+    Maybe(Nothing) : _is_nothing(true), _t() {}
+    Maybe(T const &t) : _is_nothing(false), _t(t) {}
+    Maybe(Maybe const &m) : _is_nothing(m._is_nothing), _t(m._t) {}
 
-    Maybe(Nothing n) : _is_nothing(true), _t() {}
+    template <typename T2> Maybe(Maybe<T2> const &m)
+    : _is_nothing(m._is_nothing), _t(m._t) {}
 
-    Maybe(const Maybe<T> &m) : _is_nothing(m._is_nothing), _t(m._t) {}
+    template <typename T2> Maybe(T2 const &t)
+    : _is_nothing(false), _t(t) {};
 
-    template <typename T2>
-    Maybe(const Maybe<T2> &m)
-    : _is_nothing(m._is_nothing),
-      _t(traits::to_storage(MaybeTraits<T2>::from_storage(m._t))) {}
-
-    template <typename T2>
-    Maybe(T2 t) : _is_nothing(false), _t(traits::to_storage(t)) {}
-
-    bool isNothing() const { return _is_nothing; }
     operator bool() const { return !_is_nothing; }
 
-    reference assume() const throw(IsNot<T>) {
+    T const &operator*() const throw(IsNothing) {
         if (_is_nothing) {
-            throw IsNot<T>();
+            throw IsNothing();
         } else {
-            return traits::from_storage(_t);
+            return _t;
         }
     }
-    reference operator*() const throw(IsNot<T>) {
-        return assume();
+    T &operator*() throw(IsNothing) {
+        if (_is_nothing) {
+            throw IsNothing();
+        } else {
+            return _t;
+        }
     }
-    pointer operator->() const throw(IsNot<T>) {
-        return &assume();
+
+    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;
+        }
     }
 
 private:
     bool _is_nothing;
-    storage _t;
+    T _t;
 };
 
-/* traits classes used by Maybe */
-
 template <typename T>
-struct MaybeTraits {
-    typedef T const storage;
-    typedef T const *pointer;
-    typedef T const &reference;
-    static reference to_storage(reference t) { return t; }
-    static reference from_storage(reference t) { return t; }
+class Maybe<T const> {
+public:
+    Maybe(Nothing) : _is_nothing(true), _t() {}
+    Maybe(T const &t) : _is_nothing(false), _t(t) {}
+    Maybe(Maybe const &m) : _is_nothing(m._is_nothing), _t(m._t) {}
+
+    template <typename T2> Maybe(Maybe<T2> const &m)
+    : _is_nothing(m._is_nothing), _t(m._t) {}
+
+    template <typename T2> Maybe(T2 const &t)
+    : _is_nothing(false), _t(t) {};
+
+    operator bool() const { return !_is_nothing; }
+
+    T const &operator*() const throw(IsNothing) {
+        if (_is_nothing) {
+            throw IsNothing();
+        } else {
+            return _t;
+        }
+    }
+
+    T const *operator->() const throw(IsNothing) {
+        if (_is_nothing) {
+            throw IsNothing();
+        } else {
+            return &_t;
+        }
+    }
+
+private:
+    bool _is_nothing;
+    T const _t;
 };
 
 template <typename T>
-struct MaybeTraits<T&> {
-    typedef T *storage;
-    typedef T *pointer;
-    typedef T &reference;
-    static storage to_storage(reference t) { return &t; }
-    static reference from_storage(storage t) { return *t; }
+class Maybe<T &> {
+public:
+    Maybe(Nothing) : _is_nothing(true), _t() {}
+    Maybe(T &t) : _is_nothing(false), _t(t) {}
+    Maybe(Maybe const &m) : _is_nothing(m._is_nothing), _t(m._t) {}
+
+    template <typename T2> Maybe(Maybe<T2> const &m)
+    : _is_nothing(m._is_nothing), _t(m._t) {}
+
+    template <typename T2> Maybe(T2 &t)
+    : _is_nothing(false), _t(t) {};
+
+    operator bool() const { return !_is_nothing; }
+
+    T &operator*() const throw(IsNothing) {
+        if (_is_nothing) {
+            throw IsNothing();
+        } else {
+            return _t;
+        }
+    }
+
+    T *operator->() const throw(IsNothing) {
+        if (_is_nothing) {
+            throw IsNothing();
+        } else {
+            return &_t;
+        }
+    }
+
+private:
+    bool _is_nothing;
+    T &_t;
 };
 
 } /* namespace NR */
index 4a21cbc04fbfd32677913accf22567219a1ad5aa..684700b3b7f9ad873789bb8eb650ee103b5ecddf 100644 (file)
@@ -131,7 +131,7 @@ void Inkscape::ObjectSnapper::_snapPaths(Inkscape::SnappedPoint &s,
         if (o && o->t >= 0 && o->t <= 1) {
 
             /* Convert the nearest point back to desktop coordinates */
-            NR::Point const o_it = get_point_on_Path(livarot_path, o.assume().piece, o.assume().t);
+            NR::Point const o_it = get_point_on_Path(livarot_path, o->piece, o->t);
             NR::Point const o_dt = desktop->doc2dt(o_it * i2doc);
 
             NR::Coord const dist = NR::L2(o_dt - p);
index 491037bd15ec41caacdf143891187e1580334df3..d9eaf11bc83bebf347bdf20ff6e9d1b789c1e4c4 100644 (file)
@@ -229,7 +229,11 @@ bool ShapeEditor::is_over_stroke (NR::Point event_p, bool remember) {
     sp_nodepath_ensure_livarot_path(this->nodepath);
 
     NR::Maybe<Path::cut_position> position = get_nearest_position_on_Path(this->nodepath->livarot_path, this->curvepoint_doc);
-    NR::Point nearest = get_point_on_Path(this->nodepath->livarot_path, position.assume().piece, position.assume().t);
+    if (!position) {
+        return false;
+    }
+
+    NR::Point nearest = get_point_on_Path(this->nodepath->livarot_path, position->piece, position->t);
     NR::Point delta = nearest - this->curvepoint_doc;
 
     delta = desktop->d2w(delta);
@@ -248,8 +252,8 @@ bool ShapeEditor::is_over_stroke (NR::Point event_p, bool remember) {
         this->curvepoint_event[NR::X] = (gint) event_p [NR::X];
         this->curvepoint_event[NR::Y] = (gint) event_p [NR::Y];
         this->hit = true;
-        this->grab_t = position.assume().t;
-        this->grab_node = position.assume().piece;
+        this->grab_t = position->t;
+        this->grab_node = position->piece;
     }
 
     return close;