diff --git a/src/libnr/nr-maybe.h b/src/libnr/nr-maybe.h
index 679cd9d572beede4a1eeb7fd8beaecb2b3e69fc8..1413f69d2ce8ec533bc4e3de280a09fe5d477fdd 100644 (file)
--- a/src/libnr/nr-maybe.h
+++ b/src/libnr/nr-maybe.h
#include <stdexcept>
#include <string>
+#include <algorithm>
namespace NR {
struct Nothing {};
+template <typename T>
+class MaybeStorage {
+public:
+ MaybeStorage() : _is_nothing(true) {}
+ MaybeStorage(T const &value)
+ : _value(value), _is_nothing(false) {}
+
+ bool is_nothing() const { return _is_nothing; }
+ T &value() { return _value; }
+ T const &value() const { return _value; }
+
+private:
+ T _value;
+ bool _is_nothing;
+};
+
template <typename T>
class Maybe {
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) {}
+ Maybe() {}
+ Maybe(Nothing) {}
+ Maybe(T const &t) : _storage(t) {}
+ Maybe(Maybe const &m) : _storage(m._storage) {}
- template <typename T2> Maybe(Maybe<T2> const &m)
- : _is_nothing(!m)
- {
+ template <typename T2>
+ Maybe(Maybe<T2> const &m) {
if (m) {
- _t = *m;
+ _storage = *m;
}
}
- template <typename T2> Maybe(T2 const &t)
- : _t(t), _is_nothing(false) {}
+ template <typename T2>
+ Maybe(Maybe<T2 const &> m) {
+ if (m) {
+ _storage = *m;
+ }
+ }
- 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 &operator*() 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) {
+ if (_storage.is_nothing()) {
throw IsNothing();
} else {
- return &_t;
+ return &_storage.value();
}
}
T *operator->() throw(IsNothing) {
- if (_is_nothing) {
+ if (_storage.is_nothing()) {
throw IsNothing();
} else {
- return &_t;
+ return &_storage.value();
}
}
template <typename T2>
- bool operator==(NR::Maybe<T2> const &other) const {
- if ( _is_nothing || !other ) {
- return _is_nothing && !other;
+ bool operator==(Maybe<T2> const &other) const {
+ bool is_nothing = _storage.is_nothing();
+ if ( is_nothing || !other ) {
+ return is_nothing && !other;
} else {
- return _t == *other;
+ return _storage.value() == *other;
}
}
template <typename T2>
- bool operator!=(NR::Maybe<T2> const &other) const {
- if ( _is_nothing || !other ) {
- return !_is_nothing || other;
+ bool operator!=(Maybe<T2> const &other) const {
+ bool is_nothing = _storage.is_nothing();
+ if ( is_nothing || !other ) {
+ return !is_nothing || other;
} else {
- return _t != *other;
+ return _storage.value() != *other;
}
}
private:
- T _t;
- bool _is_nothing;
+ MaybeStorage<T> _storage;
};
template <typename T>
-class Maybe<T const> {
+class Maybe<T &> {
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) {}
+ Maybe() : _ref(NULL) {}
+ Maybe(Nothing) : _ref(NULL) {}
+ Maybe(T &t) : _ref(&t) {}
- template <typename T2> Maybe(Maybe<T2> const &m)
- : _is_nothing(!m)
- {
+ template <typename T2>
+ Maybe(Maybe<T2> const &m) {
if (m) {
- _t = *m;
- }
- }
-
- template <typename T2> Maybe(T2 const &t)
- : _t(t), _is_nothing(false) {}
-
- 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;
- }
+ _ref = &*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) {
+ _ref = *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 const &> m) {
+ if (m) {
+ _ref = *m;
}
}
-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) {
+ if (!_ref) {
throw IsNothing();
} else {
return *_ref;
}
}
-
T *operator->() const throw(IsNothing) {
- if (_ref) {
+ if (!_ref) {
throw IsNothing();
} else {
return _ref;
}
template <typename T2>
- bool operator==(NR::Maybe<T2> const &other) const {
+ bool operator==(Maybe<T2> const &other) const {
if ( !_ref || !other ) {
return !_ref && !other;
} else {
}
}
template <typename T2>
- bool operator!=(NR::Maybe<T2> const &other) const {
+ bool operator!=(Maybe <T2> const &other) const {
if ( !_ref || !other ) {
- return _ref || _other;
+ return _ref || other;
} else {
return *_ref != *other;
}
}
private:
- void operator=(Maybe const &); // no assign
-
T *_ref;
};
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :