Main Page Class Hierarchy Alphabetical List Compound List File List Compound Members

FXAtomic.h

Go to the documentation of this file.
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