![]() |
Main Page
Class Hierarchy
Alphabetical List
Compound List
File List
Compound Members
![]() |
00001 /******************************************************************************** 00002 * * 00003 * Atomic Variables * 00004 * * 00005 ********************************************************************************* 00006 * Copyright (C) 2003 by Mathew Robertson. All Rights Reserved. * 00007 ********************************************************************************* 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU Lesser General Public * 00010 * License as published by the Free Software Foundation; either * 00011 * version 2.1 of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public * 00019 * License along with this library; if not, write to the Free Software * 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * 00021 *********************************************************************************/ 00022 #ifndef FXATOMIC_H 00023 #define FXATOMIC_H 00024 00025 namespace FXEX { 00026 class FXFastMutex; 00027 00028 // declaration 00029 template<class TYPE> class FXAtomic; 00030 00031 /// Support an atomic boolean type 00032 typedef FXAtomic<FXbool> FXAtomicBool; 00033 00034 /// Support an atomic integer type 00035 typedef FXAtomic<FXint> FXAtomicInt; 00036 00037 /// Support an atomic floating point type 00038 typedef FXAtomic<FXfloat> FXAtomicFloat; 00039 00040 /// Support an atomic FXString type 00041 typedef FXAtomic<FXString> FXAtomicString; 00042 00043 /*********** must declare operators for template definition ************/ 00044 /// check for equality 00045 template<class TYPE> FXAPI FXbool operator==(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00046 template<class TYPE> FXAPI FXbool operator==(FXAtomic<TYPE>& v1,const TYPE v2); 00047 template<class TYPE> FXAPI FXbool operator==(const TYPE v1,FXAtomic<TYPE>& v2); 00048 /// check for in-equality 00049 template<class TYPE> FXAPI FXbool operator!=(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00050 template<class TYPE> FXAPI FXbool operator!=(FXAtomic<TYPE>& v1,const TYPE v2); 00051 template<class TYPE> FXAPI FXbool operator!=(const TYPE v1,FXAtomic<TYPE>& v2); 00052 /// less than 00053 template<class TYPE> FXAPI FXbool operator<(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00054 template<class TYPE> FXAPI FXbool operator<(FXAtomic<TYPE>& v1,const TYPE v2); 00055 template<class TYPE> FXAPI FXbool operator<(const TYPE v1,FXAtomic<TYPE>& v2); 00056 /// greater than 00057 template<class TYPE> FXAPI FXbool operator>(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00058 template<class TYPE> FXAPI FXbool operator>(FXAtomic<TYPE>& v1,const TYPE v2); 00059 template<class TYPE> FXAPI FXbool operator>(const TYPE v1,FXAtomic<TYPE>& v2); 00060 /// less than-equal 00061 template<class TYPE> FXAPI FXbool operator<=(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00062 template<class TYPE> FXAPI FXbool operator<=(FXAtomic<TYPE>& v1,const TYPE v2); 00063 template<class TYPE> FXAPI FXbool operator<=(const TYPE v1,FXAtomic<TYPE>& v2); 00064 /// greater than-equal 00065 template<class TYPE> FXAPI FXbool operator>=(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00066 template<class TYPE> FXAPI FXbool operator>=(FXAtomic<TYPE>& v1,const TYPE v2); 00067 template<class TYPE> FXAPI FXbool operator>=(const TYPE v1,FXAtomic<TYPE>& v2); 00068 /// Stream operators 00069 template<class TYPE> FXAPI FXStream& operator<<(FXStream& store,const FXAtomic<TYPE>& v); 00070 template<class TYPE> FXAPI FXStream& operator>>(FXStream& store,FXAtomic<TYPE>& v); 00071 00072 00073 00074 /** 00075 * FXAtomic objects provide atomic access to an a value, for use by multiple threads. 00076 * This is achieved by providing mutex-locking each function call to set or get the 00077 * actual value. 00078 */ 00079 template<class TYPE> 00080 class FXAPI FXAtomic { 00081 00082 private: 00083 FXFastMutex *mutex; // used to control access to the value 00084 TYPE value; // actual value 00085 00086 public: 00087 /// Create an atomic value 00088 FXAtomic(const TYPE v=0); 00089 00090 /// set the value 00091 void setValue(const TYPE v); 00092 00093 /// get the value 00094 TYPE getValue(); 00095 00096 /// return a TYPE, say for use in a 'return' or an 'if' 00097 operator TYPE(); 00098 00099 /// allow assignment to new value of type FXAtomic<TYPE> 00100 FXAtomic<TYPE>& operator=(const FXAtomic<TYPE>& v); 00101 00102 /// allow assignment to new value of type TYPE 00103 FXAtomic<TYPE>& operator=(const TYPE v); 00104 00105 /// increment value (prefix and postfix) 00106 TYPE operator++(); 00107 TYPE operator++(TYPE); 00108 00109 /// decrement value (prefix and postfix) 00110 TYPE operator--(); 00111 TYPE operator--(TYPE); 00112 00113 /// addition 00114 TYPE operator+(const TYPE v); 00115 00116 /// subtraction 00117 TYPE operator-(const TYPE v); 00118 00119 /// multiplication 00120 TYPE operator*(const TYPE v); 00121 00122 /// divisiion 00123 TYPE operator/(const TYPE v); 00124 00125 /// increment by some value 00126 TYPE operator+=(const TYPE v); 00127 00128 /// decrement by some value 00129 TYPE operator-=(const TYPE v); 00130 00131 /// multiply by some value 00132 TYPE operator*=(const TYPE v); 00133 00134 /// divide by some value 00135 TYPE operator/=(const TYPE v); 00136 00137 /// check for equality 00138 friend FXAPI FXbool operator== <TYPE>(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00139 friend FXAPI FXbool operator== <TYPE>(FXAtomic<TYPE>& v1,const TYPE v2); 00140 friend FXAPI FXbool operator== <TYPE>(const TYPE v1,FXAtomic<TYPE>& v2); 00141 00142 /// check for in-equality 00143 friend FXAPI FXbool operator!= <TYPE>(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00144 friend FXAPI FXbool operator!= <TYPE>(FXAtomic<TYPE>& v1,const TYPE v2); 00145 friend FXAPI FXbool operator!= <TYPE>(const TYPE v1,FXAtomic<TYPE>& v2); 00146 00147 /// less than 00148 friend FXAPI FXbool operator< <TYPE>(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00149 friend FXAPI FXbool operator< <TYPE>(FXAtomic<TYPE>& v1,const TYPE v2); 00150 friend FXAPI FXbool operator< <TYPE>(const TYPE v1,FXAtomic<TYPE>& v2); 00151 00152 /// greater than 00153 friend FXAPI FXbool operator> <TYPE>(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00154 friend FXAPI FXbool operator> <TYPE>(FXAtomic<TYPE>& v1,const TYPE v2); 00155 friend FXAPI FXbool operator> <TYPE>(const TYPE v1,FXAtomic<TYPE>& v2); 00156 00157 /// less than-equal 00158 friend FXAPI FXbool operator<= <TYPE>(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00159 friend FXAPI FXbool operator<= <TYPE>(FXAtomic<TYPE>& v1,const TYPE v2); 00160 friend FXAPI FXbool operator<= <TYPE>(const TYPE v1,FXAtomic<TYPE>& v2); 00161 00162 /// greater than-equal 00163 friend FXAPI FXbool operator>= <TYPE>(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2); 00164 friend FXAPI FXbool operator>= <TYPE>(FXAtomic<TYPE>& v1,const TYPE v2); 00165 friend FXAPI FXbool operator>= <TYPE>(const TYPE v1,FXAtomic<TYPE>& v2); 00166 00167 /// Saving to a stream 00168 friend FXAPI FXStream& operator<< <TYPE>(FXStream& store,const FXAtomic<TYPE>& v); 00169 00170 /// Load from a stream 00171 friend FXAPI FXStream& operator>> <TYPE>(FXStream& store,FXAtomic<TYPE>& v); 00172 00173 /// dtor 00174 ~FXAtomic(); 00175 }; 00176 00177 /********************** I m p l e m e n t a t i o n ************************/ 00178 // when you define a template class, the implementation must exist in the same file 00179 // as the definition 00180 00181 // ctor 00182 template<class TYPE> 00183 FXAtomic<TYPE>::FXAtomic(const TYPE v) : value(v) { 00184 mutex=new FXFastMutex(); 00185 } 00186 00187 template<class TYPE> 00188 FXAtomic<TYPE>::~FXAtomic(){ 00189 delete mutex; 00190 } 00191 00192 // set the value 00193 template<class TYPE> 00194 void FXAtomic<TYPE>::setValue(const TYPE v){ 00195 mutex->lock(); 00196 value=v; 00197 mutex->unlock(); 00198 } 00199 00200 // return the value 00201 template<class TYPE> 00202 TYPE FXAtomic<TYPE>::getValue(void) { 00203 mutex->lock(); 00204 TYPE t(value); 00205 mutex->unlock(); 00206 return t; 00207 } 00208 00209 // return an TYPE 00210 template<class TYPE> 00211 FXAtomic<TYPE>::operator TYPE(void){ 00212 return getValue(); 00213 } 00214 00215 // set to new FXAtomic value 00216 template<class TYPE> 00217 FXAtomic<TYPE>& FXAtomic<TYPE>::operator=(const FXAtomic<TYPE>& v){ 00218 setValue(v.getValue()); 00219 return *this; 00220 } 00221 00222 // set to new TYPE value 00223 template<class TYPE> 00224 FXAtomic<TYPE>& FXAtomic<TYPE>::operator=(const TYPE v){ 00225 setValue(v); 00226 return *this; 00227 } 00228 00229 // increment 00230 template<class TYPE> 00231 TYPE FXAtomic<TYPE>::operator++(void){ 00232 mutex->lock(); 00233 TYPE t(++value); 00234 mutex->unlock(); 00235 return t; 00236 } 00237 00238 // increment 00239 template<class TYPE> 00240 TYPE FXAtomic<TYPE>::operator++(TYPE){ 00241 mutex->lock(); 00242 TYPE t(value++); 00243 mutex->unlock(); 00244 return t; 00245 } 00246 00247 // decrement 00248 template<class TYPE> 00249 TYPE FXAtomic<TYPE>::operator--(void){ 00250 mutex->lock(); 00251 TYPE t(--value); 00252 mutex->unlock(); 00253 return t; 00254 } 00255 00256 // decrement 00257 template<class TYPE> 00258 TYPE FXAtomic<TYPE>::operator--(TYPE){ 00259 mutex->lock(); 00260 TYPE t(value--); 00261 mutex->unlock(); 00262 return t; 00263 } 00264 00265 // addition 00266 template<class TYPE> 00267 TYPE FXAtomic<TYPE>::operator+(const TYPE v){ 00268 mutex->lock(); 00269 TYPE t(value); 00270 mutex->unlock(); 00271 return t+v; 00272 } 00273 00274 // subtraction 00275 template<class TYPE> 00276 TYPE FXAtomic<TYPE>::operator-(const TYPE v){ 00277 mutex->lock(); 00278 TYPE t(value); 00279 mutex->unlock(); 00280 return t-v; 00281 } 00282 00283 // multiplication 00284 template<class TYPE> 00285 TYPE FXAtomic<TYPE>::operator*(const TYPE v){ 00286 mutex->lock(); 00287 TYPE t(value); 00288 mutex->unlock(); 00289 return t*v; 00290 } 00291 00292 // division 00293 template<class TYPE> 00294 TYPE FXAtomic<TYPE>::operator/(const TYPE v){ 00295 mutex->lock(); 00296 TYPE t(value); 00297 mutex->unlock(); 00298 return t/v; 00299 } 00300 00301 // increment by some value 00302 template<class TYPE> 00303 TYPE FXAtomic<TYPE>::operator+=(const TYPE v){ 00304 mutex->lock(); 00305 value+=v; 00306 TYPE t(value); 00307 mutex->unlock(); 00308 return t; 00309 } 00310 00311 // decrement by some value 00312 template<class TYPE> 00313 TYPE FXAtomic<TYPE>::operator-=(const TYPE v){ 00314 mutex->lock(); 00315 value-=v; 00316 TYPE t(value); 00317 mutex->unlock(); 00318 return t; 00319 } 00320 00321 // multiply by some value 00322 template<class TYPE> 00323 TYPE FXAtomic<TYPE>::operator*=(const TYPE v){ 00324 mutex->lock(); 00325 value*=v; 00326 TYPE t(value); 00327 mutex->unlock(); 00328 return t; 00329 } 00330 00331 // divide by some value 00332 template<class TYPE> 00333 TYPE FXAtomic<TYPE>::operator/=(const TYPE v){ 00334 mutex->lock(); 00335 value/=v; 00336 TYPE t(value); 00337 mutex->unlock(); 00338 return t; 00339 } 00340 00341 // test equality 00342 template<class TYPE> 00343 FXbool operator==(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2){ 00344 return v1.getValue()==v2.getValue(); 00345 } 00346 00347 // test equality 00348 template<class TYPE> 00349 FXbool operator==(FXAtomic<TYPE>& v1,const TYPE v2){ 00350 return v1.getValue()==v2; 00351 } 00352 00353 // test equality 00354 template<class TYPE> 00355 FXbool operator==(const TYPE v1,FXAtomic<TYPE>& v2){ 00356 return v1==v2.getValue(); 00357 } 00358 00359 // test in-equality 00360 template<class TYPE> 00361 FXbool operator!=(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2){ 00362 return v1.getValue()!=v2.getValue(); 00363 } 00364 00365 // test in-equality 00366 template<class TYPE> 00367 FXbool operator!=(FXAtomic<TYPE>& v1,const TYPE v2){ 00368 return v1.getValue()!=v2; 00369 } 00370 00371 // test in-equality 00372 template<class TYPE> 00373 FXbool operator!=(const TYPE v1,FXAtomic<TYPE>& v2){ 00374 return v1!=v2.getValue(); 00375 } 00376 00377 // test greater than 00378 template<class TYPE> 00379 FXbool operator>(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2){ 00380 return v1.getValue()>v2.getValue(); 00381 } 00382 00383 // test greater than 00384 template<class TYPE> 00385 FXbool operator>(FXAtomic<TYPE>& v1,const TYPE v2){ 00386 return v1.getValue()>v2; 00387 } 00388 00389 // test greater than 00390 template<class TYPE> 00391 FXbool operator>(const TYPE v1,FXAtomic<TYPE>& v2){ 00392 return v1>v2.getValue(); 00393 } 00394 00395 // test less than 00396 template<class TYPE> 00397 FXbool operator<(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2){ 00398 return v1.getValue()<v2.getValue(); 00399 } 00400 00401 // test less than 00402 template<class TYPE> 00403 FXbool operator<(FXAtomic<TYPE>& v1,const TYPE v2){ 00404 return v1.getValue()<v2; 00405 } 00406 00407 // test less than 00408 template<class TYPE> 00409 FXbool operator<(const TYPE v1,FXAtomic<TYPE>& v2){ 00410 return v1<v2.getValue(); 00411 } 00412 00413 // test greater than-equal 00414 template<class TYPE> 00415 FXbool operator>=(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2){ 00416 return v1.getValue()>=v2.getValue(); 00417 } 00418 00419 // test greater than-equal 00420 template<class TYPE> 00421 FXbool operator>=(FXAtomic<TYPE>& v1,const TYPE v2){ 00422 return v1.getValue()>=v2; 00423 } 00424 00425 // test greater than-equal 00426 template<class TYPE> 00427 FXbool operator>=(const TYPE v1,FXAtomic<TYPE>& v2){ 00428 return v1>=v2.getValue(); 00429 } 00430 00431 // test less than-equal 00432 template<class TYPE> 00433 FXbool operator<=(FXAtomic<TYPE>& v1,FXAtomic<TYPE>& v2){ 00434 return v1.getValue()<=v2.getValue(); 00435 } 00436 00437 // test less than-equal 00438 template<class TYPE> 00439 FXbool operator<=(FXAtomic<TYPE>& v1,const TYPE v2){ 00440 return v1.getValue()<=v2; 00441 } 00442 00443 // test less than-equal 00444 template<class TYPE> 00445 FXbool operator<=(const TYPE v1,FXAtomic<TYPE>& v2){ 00446 return v1<=v2.getValue(); 00447 } 00448 00449 // save to stream 00450 template<class TYPE> 00451 FXStream& operator<<(FXStream& store,const FXAtomic<TYPE>& v){ 00452 store << v.getValue(); 00453 return store; 00454 } 00455 00456 // load from stream 00457 template<class TYPE> 00458 FXStream& operator>>(FXStream& store,FXAtomic<TYPE>& v){ 00459 TYPE t; 00460 store >> t; 00461 v.setValue(t); 00462 return store; 00463 } 00464 00465 } // namespace FXEX 00466 #endif // FXATOMIC_H