Code

Use subdirectories with icon sizes.
[inkscape.git] / src / libnr / nr-maybe.h
1 #ifndef __NR_MAYBE_H__
2 #define __NR_MAYBE_H__
4 /*
5  * Nullable values for C++
6  *
7  * Copyright 2004, 2007  MenTaLguY <mental@rydia.net>
8  *
9  * This code is licensed under the GNU GPL; see COPYING for more information.
10  */
12 #if HAVE_CONFIG_H
13 #include "config.h"
14 #endif
16 #include <stdexcept>
17 #include <string>
18 #include <algorithm>
20 namespace NR {
22 class IsNothing : public std::domain_error {
23 public:
24     IsNothing() : domain_error(std::string("Is nothing")) {}
25 };
27 struct Nothing {};
29 template <typename T>
30 class MaybeStorage {
31 public:
32     MaybeStorage() : _is_nothing(true) {}
33     MaybeStorage(T const &value)
34     : _value(value), _is_nothing(false) {}
36     bool is_nothing() const { return _is_nothing; }
37     T &value() { return _value; }
38     T const &value() const { return _value; }
40 private:
41     T _value;
42     bool _is_nothing;
43 };
45 template <typename T>
46 class Maybe {
47 public:
48     Maybe() {}
49     Maybe(Nothing) {}
50     Maybe(T const &t) : _storage(t) {}
51     Maybe(Maybe const &m) : _storage(m._storage) {}
53     template <typename T2>
54     Maybe(Maybe<T2> const &m) {
55         if (m) {
56             _storage = *m;
57         }
58     }
60     template <typename T2>
61     Maybe(Maybe<T2 const &> m) {
62         if (m) {
63             _storage = *m;
64         }
65     }
67     operator bool() const { return !_storage.is_nothing(); }
69     T const &operator*() const throw(IsNothing) {
70         if (_storage.is_nothing()) {
71             throw IsNothing();
72         } else {
73             return _storage.value();
74         }
75     }
76     T &operator*() throw(IsNothing) {
77         if (_storage.is_nothing()) {
78             throw IsNothing();
79         } else {
80             return _storage.value();
81         }
82     }
84     T const *operator->() const throw(IsNothing) {
85         if (_storage.is_nothing()) {
86             throw IsNothing();
87         } else {
88             return &_storage.value();
89         }
90     }
91     T *operator->() throw(IsNothing) {
92         if (_storage.is_nothing()) {
93             throw IsNothing();
94         } else {
95             return &_storage.value();
96         }
97     }
99     template <typename T2>
100     bool operator==(Maybe<T2> const &other) const {
101         bool is_nothing = _storage.is_nothing();
102         if ( is_nothing || !other ) {
103             return is_nothing && !other;
104         } else {
105             return _storage.value() == *other;
106         }
107     }
108     template <typename T2>
109     bool operator!=(Maybe<T2> const &other) const {
110         bool is_nothing = _storage.is_nothing();
111         if ( is_nothing || !other ) {
112             return !is_nothing || other;
113         } else {
114             return _storage.value() != *other;
115         }
116     }
118 private:
119     MaybeStorage<T> _storage;
120 };
122 template <typename T>
123 class Maybe<T &> {
124 public:
125     Maybe() : _ref(NULL) {}
126     Maybe(Nothing) : _ref(NULL) {}
127     Maybe(T &t) : _ref(&t) {}
129     template <typename T2>
130     Maybe(Maybe<T2> const &m) {
131         if (m) {
132             _ref = &*m;
133         } 
134     }
136     template <typename T2>
137     Maybe(Maybe<T2 &> m) {
138         if (m) {
139             _ref = *m;
140         }
141     }
143     template <typename T2>
144     Maybe(Maybe<T2 const &> m) {
145         if (m) {
146             _ref = *m;
147         }
148     }
150     operator bool() const { return _ref; }
152     T &operator*() const throw(IsNothing) {
153         if (!_ref) {
154             throw IsNothing();
155         } else {
156             return *_ref;
157         }
158     }
159     T *operator->() const throw(IsNothing) {
160         if (!_ref) {
161             throw IsNothing();
162         } else {
163             return _ref;
164         }
165     }
167     template <typename T2>
168     bool operator==(Maybe<T2> const &other) const {
169         if ( !_ref || !other ) {
170             return !_ref && !other;
171         } else {
172             return *_ref == *other;
173         }
174     }
175     template <typename T2>
176     bool operator!=(Maybe <T2> const &other) const {
177         if ( !_ref || !other ) {
178             return _ref || other;
179         } else {
180             return *_ref != *other;
181         }
182     }
184 private:
185     T *_ref;
186 };
188 } /* namespace NR */
190 #endif
192 /*
193   Local Variables:
194   mode:c++
195   c-file-style:"stroustrup"
196   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
197   indent-tabs-mode:nil
198   fill-column:99
199   End:
200 */
201 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :