ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/truck/Common/scopes.hpp
Revision: 33
Committed: 2008-02-29T19:05:18-08:00 (14 years, 3 months ago) by douglas
File size: 6362 byte(s)
Log Message:
This is starting to work, but there seems to be some strange with mutexes every once in a while, grr!

File Contents

# Content
1 // Truck Computer Dooom!
2 //
3 // Douglas Thrift
4 //
5 // $Id$
6
7 /* Menes - C++ High-Level Utility Library
8 * Copyright (C) 2003-2005 Jay Freeman (saurik)
9 */
10
11 /*
12 * Redistribution and use in source and binary
13 * forms, with or without modification, are permitted
14 * provided that the following conditions are met:
15 *
16 * 1. Redistributions of source code must retain the
17 * above copyright notice, this list of conditions
18 * and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the
20 * above copyright notice, this list of conditions
21 * and the following disclaimer in the documentation
22 * and/or other materials provided with the
23 * distribution.
24 * 3. The name of the author may not be used to endorse
25 * or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
30 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
34 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
38 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 #ifndef _scopes_hpp_
45 #define _scopes_hpp_
46
47 #include <foreach.hpp>
48
49 #include <algorithm>
50 #include <vector>
51
52 namespace be {
53 struct Destruct {
54 virtual ~Destruct() {
55 }
56 };
57
58 // XXX: this should support allocator templates
59 template <typename Type_>
60 struct DestructImpl :
61 public Destruct
62 {
63 private:
64 Type_ *object_;
65
66 public:
67 DestructImpl(Type_ *object) :
68 object_(object)
69 {
70 }
71
72 ~DestructImpl() {
73 delete object_;
74 }
75 };
76 }
77
78 class Scope {
79 public:
80 inline operator bool() const {
81 return false;
82 }
83 };
84
85 // XXX: this should be generalized as it sounds too specific to even be useful
86 class ScopeDestruct {
87 private:
88 typedef std::vector<be::Destruct *> DestructList_;
89 DestructList_ destructs_;
90
91 public:
92 template <typename Type_>
93 void Insert(Type_ *object) {
94 destructs_.push_back(static_cast<be::Destruct *>(new be::DestructImpl<Type_>(object)));
95 }
96
97 ~ScopeDestruct() {
98 _foreach (std::vector<be::Destruct *>, destruct, destructs_)
99 delete *destruct;
100 }
101 };
102
103 template <typename Type_, typename Temp_ = Type_>
104 class ScopeIncrement {
105 private:
106 Temp_ rhs_;
107 Type_ &lhs_;
108 bool keep_;
109
110 public:
111 inline ScopeIncrement(Type_ &lhs) :
112 rhs_(lhs),
113 lhs_(lhs),
114 keep_(false)
115 {
116 ++lhs;
117 }
118
119 inline ~ScopeIncrement() {
120 if (!keep_)
121 --lhs_;
122 }
123
124 inline void Keep() {
125 keep_ = true;
126 }
127
128 operator const Temp_ &() const {
129 return rhs_;
130 }
131 };
132
133 template <typename Type_, typename Temp_ = Type_>
134 class ScopeSet {
135 private:
136 Temp_ rhs_;
137 Type_ &lhs_;
138 bool keep_;
139
140 public:
141 inline ScopeSet(Type_ &lhs, const Temp_ &rhs) :
142 rhs_(lhs),
143 lhs_(lhs),
144 keep_(false)
145 {
146 lhs = rhs;
147 }
148
149 inline ~ScopeSet() {
150 if (!keep_)
151 lhs_ = rhs_;
152 }
153
154 inline const Temp_ &GetValue() const {
155 return rhs_;
156 }
157
158 inline void Keep() {
159 keep_ = true;
160 }
161
162 operator const Temp_ &() const {
163 return GetValue();
164 }
165 };
166
167 template <typename Type_>
168 class ScopeSwap {
169 private:
170 Type_ &lhs_;
171 Type_ &rhs_;
172
173 public:
174 inline ScopeSwap(Type_ &lhs, Type_ &rhs) :
175 lhs_(lhs), rhs_(rhs)
176 {
177 std::swap(lhs_, rhs_);
178 }
179
180 inline ~ScopeSwap() {
181 std::swap(lhs_, rhs_);
182 }
183 };
184
185 // XXX: move this out into the world somewhere
186 class FreeLock {
187 public:
188 inline static void Lock() {
189 }
190
191 inline static void Unlock() {
192 }
193 };
194
195 template <typename Lock_>
196 class ScopeLock :
197 public Scope
198 {
199 protected:
200 Lock_ *lock_;
201
202 public:
203 explicit ScopeLock(Lock_ &lock) :
204 lock_(&lock)
205 {
206 lock_->Lock();
207 }
208
209 ScopeLock(Lock_ &lock, bool locked) {
210 if (!locked)
211 lock_ = NULL;
212 else {
213 lock_ = &lock;
214 lock_->Lock();
215 }
216 }
217
218 ~ScopeLock() {
219 Release();
220 }
221
222 void Release() {
223 if (lock_ != NULL) {
224 lock_->Unlock();
225 lock_ = NULL;
226 }
227 }
228 };
229
230 namespace be {
231 template <typename Lock_>
232 inline ScopeLock<Lock_> ScopeLock_(Lock_ &lock) {
233 return ScopeLock<Lock_>(lock);
234 } }
235
236 #define _synchronized(lock) if (const Scope &_scope __attribute__((unused)) = be::ScopeLock_(lock)); else
237
238 template <typename Lock_>
239 class ScopeUnlock :
240 public Scope
241 {
242 protected:
243 Lock_ *lock_;
244 bool unlocked_;
245
246 public:
247 explicit ScopeUnlock(Lock_ &lock) :
248 lock_(&lock)
249 {
250 lock_->Unlock();
251 }
252
253 ScopeUnlock(Lock_ &lock, bool unlocked) {
254 if (!unlocked)
255 lock_ = NULL;
256 else {
257 lock_ = &lock;
258 lock_->Unlock();
259 }
260 }
261
262 ~ScopeUnlock() {
263 Release();
264 }
265
266 void Release() {
267 if (lock_ != NULL) {
268 lock_->Lock();
269 lock_ = NULL;
270 }
271 }
272 };
273
274 namespace be {
275 template <typename Lock_>
276 inline ScopeUnlock<Lock_> ScopeUnlock_(Lock_ &lock) {
277 return ScopeUnlock<Lock_>(lock);
278 } }
279
280 #define _desynchronized(lock) if (const Scope &_scope __attribute__((unused)) = be::ScopeUnlock_(lock)); else
281
282 template <typename Lock_>
283 class ScopeReadLock :
284 public Scope
285 {
286 private:
287 Lock_ &lock_;
288
289 public:
290 ScopeReadLock(Lock_ &lock) :
291 lock_(lock)
292 {
293 lock_.ReadLock();
294 }
295
296 ~ScopeReadLock() {
297 lock_.ReadUnlock();
298 }
299 };
300
301 template <typename Lock_>
302 class ScopeWriteLock :
303 public Scope
304 {
305 private:
306 Lock_ &lock_;
307
308 public:
309 ScopeWriteLock(Lock_ &lock) :
310 lock_(lock)
311 {
312 lock_.WriteLock();
313 }
314
315 ~ScopeWriteLock() {
316 lock_.WriteUnlock();
317 }
318 };
319
320 #endif//_scopes_hpp_

Properties

Name Value
svn:keywords Id