~valavanisalex/ubuntu/oneiric/inkscape/inkscape_0.48.1-2ubuntu4

« back to all changes in this revision

Viewing changes to src/libnr/nr-maybe.h

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook, Kees Cook, Ted Gould
  • Date: 2008-02-10 14:20:16 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20080210142016-vcnb2zqyhszu0xvb
Tags: 0.46~pre1-0ubuntu1
[ Kees Cook ]
* debian/control:
  - add libgtkspell-dev build-dep to gain GtkSpell features (LP: #183547).
  - update Standards version (no changes needed).
  - add Vcs and Homepage fields.
  - switch to new python-lxml dep.
* debian/{control,rules}: switch from dpatch to quilt for more sanity.
* debian/patches/20_fix_glib_and_gxx43_ftbfs.patch:
  - merged against upstream fixes.
  - added additional fixes for newly written code.
* debian/rules: enable parallel building.

[ Ted Gould ]
* Updating POTFILES.in to make it so things build correctly.
* debian/control:
  - add ImageMagick++ and libboost-dev to build-deps

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
#define __NR_MAYBE_H__
3
3
 
4
4
/*
5
 
 * Functionalesque "Maybe" class
6
 
 *
7
 
 * Copyright 2004  MenTaLguY
8
 
 *
9
 
 * Authors:
10
 
 *   MenTaLguY <mental@rydia.net>
 
5
 * Nullable values for C++
 
6
 *
 
7
 * Copyright 2004, 2007  MenTaLguY <mental@rydia.net>
11
8
 *
12
9
 * This code is licensed under the GNU GPL; see COPYING for more information.
13
10
 */
17
14
#endif
18
15
 
19
16
#include <stdexcept>
20
 
#include <typeinfo>
21
17
#include <string>
22
18
 
23
19
namespace NR {
24
20
 
25
 
/** An exception class for run-time type errors */
26
 
template <typename T>
27
 
class IsNot : public std::domain_error {
28
 
public:
29
 
    IsNot() : domain_error(std::string("Is not ") + typeid(T).name()) {}
30
 
};
31
 
 
32
 
/** A type with only one value, which (in principle) is only equal to itself.
33
 
 *
34
 
 *  Types that may (at runtime) pretend to be Nothing need only provide an
35
 
 *  operator bool operator==(Type, Nothing); the rest of the operator
36
 
 *  definitions will be taken care of automatically.
37
 
 *
38
 
 *  Such types should also provide a casting operator to Nothing, obviously.
39
 
 */
40
 
struct Nothing {
41
 
    bool operator==(Nothing n) { return true; }
42
 
    bool operator!=(Nothing n) { return false; }
43
 
    template <typename T>
44
 
    bool operator==(T t) { return t == *this; }
45
 
    template <typename T>
46
 
    bool operator!=(T t) { return t != *this; }
47
 
};
48
 
 
49
 
template <typename T>
50
 
bool operator==(T t, Nothing n) { return false; }
51
 
template <typename T>
52
 
bool operator!=(T t, Nothing n) { return !( t == n ); }
53
 
 
54
 
template <typename T>
55
 
struct MaybeTraits;
 
21
class IsNothing : public std::domain_error {
 
22
public:
 
23
    IsNothing() : domain_error(std::string("Is nothing")) {}
 
24
};
 
25
 
 
26
struct Nothing {};
 
27
 
 
28
template <typename T>
 
29
class MaybeStorage {
 
30
public:
 
31
    MaybeStorage() : _is_nothing(true) {}
 
32
    MaybeStorage(T const &value)
 
33
    : _value(value), _is_nothing(false) {}
 
34
 
 
35
    bool is_nothing() const { return _is_nothing; }
 
36
    T &value() { return _value; }
 
37
    T const &value() const { return _value; }
 
38
 
 
39
private:
 
40
    T _value;
 
41
    bool _is_nothing;
 
42
};
56
43
 
57
44
template <typename T>
58
45
class Maybe {
59
46
public:
60
 
    typedef MaybeTraits<T> traits;
61
 
    typedef typename traits::storage storage;
62
 
    typedef typename traits::reference reference;
63
 
 
64
 
    Maybe(Nothing n) : _is_nothing(true), _t() {}
65
 
 
66
 
    Maybe(const Maybe<T> &m) : _is_nothing(m._is_nothing), _t(m._t) {}
67
 
 
68
 
    template <typename T2>
69
 
    Maybe(const Maybe<T2> &m)
70
 
    : _is_nothing(m._is_nothing),
71
 
      _t(traits::to_storage(MaybeTraits<T2>::from_storage(m._t))) {}
72
 
 
73
 
    template <typename T2>
74
 
    Maybe(T2 t) : _is_nothing(false), _t(traits::to_storage(t)) {}
75
 
 
76
 
    reference assume() const throw(IsNot<T>) {
77
 
        if (_is_nothing) {
78
 
            throw IsNot<T>();
79
 
        } else {
80
 
            return traits::from_storage(_t);
81
 
        }
82
 
    }
83
 
 
84
 
    operator reference() const throw(IsNot<T>) {
85
 
        if (_is_nothing) {
86
 
            throw IsNot<T>();
87
 
        } else {
88
 
            return traits::from_storage(_t);
89
 
        }
90
 
    }
91
 
    operator Nothing() const throw(IsNot<Nothing>) {
92
 
        if (!_is_nothing) {
93
 
            throw IsNot<Nothing>();
94
 
        } else {
95
 
            return Nothing();
96
 
        }
97
 
    }
98
 
 
99
 
    bool operator==(Nothing n) { return _is_nothing; }
100
 
    bool operator==(reference r) {
101
 
        return traits::from_storage(_t) == r;
102
 
    }
103
 
 
104
 
private:
105
 
    bool _is_nothing;
106
 
    storage _t;
107
 
};
108
 
 
109
 
/* traits classes used by Maybe */
110
 
 
111
 
template <typename T>
112
 
struct MaybeTraits {
113
 
    typedef T const storage;
114
 
    typedef T const &reference;
115
 
    static reference to_storage(reference t) { return t; }
116
 
    static reference from_storage(reference t) { return t; }
117
 
};
118
 
 
119
 
template <typename T>
120
 
struct MaybeTraits<T&> {
121
 
    typedef T *storage;
122
 
    typedef T &reference;
123
 
    static storage to_storage(reference t) { return &t; }
124
 
    static reference from_storage(storage t) { return *t; }
 
47
    Maybe() {}
 
48
    Maybe(Nothing) {}
 
49
    Maybe(T const &t) : _storage(t) {}
 
50
    Maybe(Maybe const &m) : _storage(m._storage) {}
 
51
 
 
52
    template <typename T2>
 
53
    Maybe(Maybe<T2> const &m) {
 
54
        if (m) {
 
55
            _storage = *m;
 
56
        }
 
57
    }
 
58
 
 
59
    template <typename T2>
 
60
    Maybe(Maybe<T2 const &> m) {
 
61
        if (m) {
 
62
            _storage = *m;
 
63
        }
 
64
    }
 
65
 
 
66
    operator bool() const { return !_storage.is_nothing(); }
 
67
 
 
68
    T const &operator*() const throw(IsNothing) {
 
69
        if (_storage.is_nothing()) {
 
70
            throw IsNothing();
 
71
        } else {
 
72
            return _storage.value();
 
73
        }
 
74
    }
 
75
    T &operator*() throw(IsNothing) {
 
76
        if (_storage.is_nothing()) {
 
77
            throw IsNothing();
 
78
        } else {
 
79
            return _storage.value();
 
80
        }
 
81
    }
 
82
 
 
83
    T const *operator->() const throw(IsNothing) {
 
84
        if (_storage.is_nothing()) {
 
85
            throw IsNothing();
 
86
        } else {
 
87
            return &_storage.value();
 
88
        }
 
89
    }
 
90
    T *operator->() throw(IsNothing) {
 
91
        if (_storage.is_nothing()) {
 
92
            throw IsNothing();
 
93
        } else {
 
94
            return &_storage.value();
 
95
        }
 
96
    }
 
97
 
 
98
    template <typename T2>
 
99
    bool operator==(Maybe<T2> const &other) const {
 
100
        bool is_nothing = _storage.is_nothing();
 
101
        if ( is_nothing || !other ) {
 
102
            return is_nothing && !other;
 
103
        } else {
 
104
            return _storage.value() == *other;
 
105
        }
 
106
    }
 
107
    template <typename T2>
 
108
    bool operator!=(Maybe<T2> const &other) const {
 
109
        bool is_nothing = _storage.is_nothing();
 
110
        if ( is_nothing || !other ) {
 
111
            return !is_nothing || other;
 
112
        } else {
 
113
            return _storage.value() != *other;
 
114
        }
 
115
    }
 
116
 
 
117
private:
 
118
    MaybeStorage<T> _storage;
 
119
};
 
120
 
 
121
template <typename T>
 
122
class Maybe<T &> {
 
123
public:
 
124
    Maybe() : _ref(NULL) {}
 
125
    Maybe(Nothing) : _ref(NULL) {}
 
126
    Maybe(T &t) : _ref(&t) {}
 
127
 
 
128
    template <typename T2>
 
129
    Maybe(Maybe<T2> const &m) {
 
130
        if (m) {
 
131
            _ref = &*m;
 
132
        } 
 
133
    }
 
134
 
 
135
    template <typename T2>
 
136
    Maybe(Maybe<T2 &> m) {
 
137
        if (m) {
 
138
            _ref = *m;
 
139
        }
 
140
    }
 
141
 
 
142
    template <typename T2>
 
143
    Maybe(Maybe<T2 const &> m) {
 
144
        if (m) {
 
145
            _ref = *m;
 
146
        }
 
147
    }
 
148
 
 
149
    operator bool() const { return _ref; }
 
150
 
 
151
    T &operator*() const throw(IsNothing) {
 
152
        if (!_ref) {
 
153
            throw IsNothing();
 
154
        } else {
 
155
            return *_ref;
 
156
        }
 
157
    }
 
158
    T *operator->() const throw(IsNothing) {
 
159
        if (!_ref) {
 
160
            throw IsNothing();
 
161
        } else {
 
162
            return _ref;
 
163
        }
 
164
    }
 
165
 
 
166
    template <typename T2>
 
167
    bool operator==(Maybe<T2> const &other) const {
 
168
        if ( !_ref || !other ) {
 
169
            return !_ref && !other;
 
170
        } else {
 
171
            return *_ref == *other;
 
172
        }
 
173
    }
 
174
    template <typename T2>
 
175
    bool operator!=(Maybe <T2> const &other) const {
 
176
        if ( !_ref || !other ) {
 
177
            return _ref || other;
 
178
        } else {
 
179
            return *_ref != *other;
 
180
        }
 
181
    }
 
182
 
 
183
private:
 
184
    T *_ref;
125
185
};
126
186
 
127
187
} /* namespace NR */