00001 /***************************************************************************** 00002 * Copyright (C) 2011 by Benjamin Hadorn (b_hadorn@bluewin.ch) 00003 ***************************************************************************** 00004 * Project : Zeus Base Library 00005 * Module : AtomicValueType 00006 * Package : Zeus.ZeusBase.System 00007 * Author : Benjamin Hadorn 00008 * Date : 27.12.2011 00009 * System : Zeus-Framework 00010 ***************************************************************************** 00011 * Licence: * 00012 * This library is free software; you can redistribute it and/or modify * 00013 * it under the terms of the GNU Lesser General Public License as * 00014 * published by the Free Software Foundation; either version * 00015 * 2.1 of the License, or (at your option) any later version. * 00016 * * 00017 * This library is distributed in the hope that it will be useful, * 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00020 * GNU Lesser General Public License for more details. * 00021 * * 00022 * You should have received a copy of the GNU Lesser General Public * 00023 * License along with this library; if not, write to the Free Software * 00024 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA * 00025 *****************************************************************************/ 00026 00027 /***************************************************************************** 00028 * Changes: 00029 * 27.12.2011 bha: created zeus 2.0 00030 *****************************************************************************/ 00031 00032 #ifndef AtomicValueTypeHPP 00033 #define AtomicValueTypeHPP 00034 00035 #include <zeusbase/System/ZObject.h> 00036 #include <zeusbase/System/CriticalScopeLock.hpp> 00037 #include <zeusbase/System/CriticalSection.h> 00038 00039 BEGIN_NAMESPACE_Zeus 00040 00041 /***************************************************************************/ 00045 /***************************************************************************/ 00046 template <class T> class TAtomicValueType : public TZObject 00047 { 00048 public: 00049 TAtomicValueType(); 00050 TAtomicValueType(T tValue); 00051 TAtomicValueType(const TAtomicValueType<T>& rValue); 00052 virtual ~TAtomicValueType(); 00053 00054 //Methods 00055 T addAndGet(T tValue); 00056 bool compareAndSet(T tExpectedValue, T tUpdate); 00057 T decrementAndGet(); 00058 T divideAndGet(T tValue); 00059 bool equals(T tExpectedValue) const; 00060 const T getAndDecrement(); 00061 const T getAndIncrement(); 00062 T getValue(); 00063 T getValue() const; 00064 T incrementAndGet(); 00065 T multiplyAndGet(T tValue); 00066 void setValue(T tValue); 00067 00068 //Operators 00069 TAtomicValueType<T>& operator+= (const T tValue); 00070 TAtomicValueType<T>& operator-= (const T tValue); 00071 TAtomicValueType<T>& operator*= (const T tValue); 00072 TAtomicValueType<T>& operator/= (const T tValue); 00073 TAtomicValueType<T>& operator = (const TAtomicValueType<T>& rInVal) { setValue(rInVal.getValue()); return *this;} 00074 inline TAtomicValueType<T>& operator = (T tValue) { setValue(tValue); return *this; } 00075 inline bool operator ==(const T tValue)const { return equals(tValue); } 00076 inline bool operator ==(const int iValue)const { return equals(T(iValue)); } 00077 inline bool operator !=(const T tValue)const { return !equals(tValue); } 00078 inline bool operator !=(const int iValue)const { return !equals(T(iValue)); } 00079 inline const T operator++() { return incrementAndGet(); } 00080 inline const T operator--() { return decrementAndGet(); } 00081 inline T operator++(int) { return getAndIncrement(); } 00082 inline T operator--(int) { return getAndDecrement(); } 00083 inline operator T() const { return getValue(); } 00084 00085 protected: 00087 T m_tValue; 00089 TCriticalSection& m_rLock; 00090 00091 private: 00092 00093 }; 00094 00095 00096 /****************************************************************************/ 00099 /****************************************************************************/ 00100 template <class T> inline TAtomicValueType<T>::TAtomicValueType() 00101 : TZObject(), 00102 m_rLock(*new TCriticalSection(TCriticalSection::etRecursive)), 00103 m_tValue(T()) 00104 {} 00105 00106 /**************************************************************************/ 00109 /**************************************************************************/ 00110 template <class T> inline TAtomicValueType<T>::TAtomicValueType(T tValue) 00111 : TZObject(), 00112 m_rLock(*new TCriticalSection(TCriticalSection::etRecursive)), 00113 m_tValue(tValue) 00114 { 00115 } 00116 00117 /**************************************************************************/ 00121 /**************************************************************************/ 00122 template <class T> inline TAtomicValueType<T>::TAtomicValueType(const TAtomicValueType<T>& rValue) 00123 : TZObject(), 00124 m_rLock(*new TCriticalSection(TCriticalSection::etRecursive)) 00125 { 00126 m_tValue = rValue.getValue(); 00127 } 00128 00129 00130 /**************************************************************************/ 00133 /**************************************************************************/ 00134 template <class T> inline TAtomicValueType<T>::~TAtomicValueType() 00135 { 00136 m_rLock.release(); 00137 } 00138 00139 /**************************************************************************/ 00142 /**************************************************************************/ 00143 template <class T> inline const T TAtomicValueType<T>::getAndDecrement() 00144 { 00145 TCriticalScopeLock Lock(m_rLock); 00146 T tRetval = m_tValue; 00147 --m_tValue; 00148 return tRetval; 00149 } 00150 00151 /**************************************************************************/ 00154 /**************************************************************************/ 00155 template <class T> inline const T TAtomicValueType<T>::getAndIncrement() 00156 { 00157 TCriticalScopeLock Lock(m_rLock); 00158 T tRetval = m_tValue; 00159 ++m_tValue; 00160 return tRetval; 00161 } 00162 00163 /**************************************************************************/ 00166 /**************************************************************************/ 00167 template <class T> inline T TAtomicValueType<T>::getValue() 00168 { 00169 TCriticalScopeLock Lock(m_rLock); 00170 return m_tValue; 00171 } 00172 00173 /**************************************************************************/ 00176 /**************************************************************************/ 00177 template <class T> inline T TAtomicValueType<T>::getValue() const 00178 { 00179 TCriticalScopeLock Lock(m_rLock); 00180 return m_tValue; 00181 } 00182 00183 /**************************************************************************/ 00186 /**************************************************************************/ 00187 template <class T> inline T TAtomicValueType<T>::incrementAndGet() 00188 { 00189 TCriticalScopeLock Lock(m_rLock); 00190 ++m_tValue; 00191 return m_tValue; 00192 } 00193 00194 /**************************************************************************/ 00197 /**************************************************************************/ 00198 template <class T> inline T TAtomicValueType<T>::decrementAndGet() 00199 { 00200 TCriticalScopeLock Lock(m_rLock); 00201 --m_tValue; 00202 return m_tValue; 00203 } 00204 00205 /**************************************************************************/ 00212 /**************************************************************************/ 00213 template <class T> inline bool TAtomicValueType<T>::compareAndSet(T tExpectedValue, T tUpdate) 00214 { 00215 TCriticalScopeLock Lock(m_rLock); 00216 bool bRetval = (m_tValue == tExpectedValue); 00217 if (bRetval) 00218 { 00219 m_tValue = tUpdate; 00220 } 00221 return bRetval; 00222 } 00223 00224 /**************************************************************************/ 00227 /**************************************************************************/ 00228 template <class T> inline bool TAtomicValueType<T>::equals(T tExpectedValue) const 00229 { 00230 TCriticalScopeLock Lock(m_rLock); 00231 return (m_tValue == tExpectedValue); 00232 } 00233 00234 00235 /**************************************************************************/ 00238 /**************************************************************************/ 00239 template <class T> inline void TAtomicValueType<T>::setValue(T tValue) 00240 { 00241 TCriticalScopeLock Lock(m_rLock); 00242 m_tValue = tValue; 00243 } 00244 00245 /**************************************************************************/ 00248 /**************************************************************************/ 00249 template <class T> inline T TAtomicValueType<T>::addAndGet(T tValue) 00250 { 00251 TCriticalScopeLock Lock(m_rLock); 00252 m_tValue += tValue; 00253 return m_tValue; 00254 } 00255 00256 /**************************************************************************/ 00259 /**************************************************************************/ 00260 template <class T> inline T TAtomicValueType<T>::multiplyAndGet(T tValue) 00261 { 00262 TCriticalScopeLock Lock(m_rLock); 00263 m_tValue *= tValue; 00264 return m_tValue; 00265 } 00266 00267 /**************************************************************************/ 00270 /**************************************************************************/ 00271 template <class T> inline T TAtomicValueType<T>::divideAndGet(T tValue) 00272 { 00273 TCriticalScopeLock Lock(m_rLock); 00274 m_tValue /= tValue; 00275 return m_tValue; 00276 } 00277 00278 00280 // OPERATORS 00281 /**************************************************************************/ 00284 /**************************************************************************/ 00285 template <class T> inline TAtomicValueType<T>& TAtomicValueType<T>::operator+= (const T tValue) 00286 { 00287 TCriticalScopeLock Lock(m_rLock); 00288 m_tValue += tValue; 00289 return *this; 00290 } 00291 00292 /**************************************************************************/ 00295 /**************************************************************************/ 00296 template <class T> inline TAtomicValueType<T>& TAtomicValueType<T>::operator-= (const T tValue) 00297 { 00298 TCriticalScopeLock Lock(m_rLock); 00299 m_tValue -= tValue; 00300 return *this; 00301 } 00302 00303 /**************************************************************************/ 00306 /**************************************************************************/ 00307 template <class T> inline TAtomicValueType<T>& TAtomicValueType<T>::operator*= (const T tValue) 00308 { 00309 TCriticalScopeLock Lock(m_rLock); 00310 m_tValue *= tValue; 00311 return *this; 00312 } 00313 00314 /**************************************************************************/ 00317 /**************************************************************************/ 00318 template <class T> inline TAtomicValueType<T>& TAtomicValueType<T>::operator/= (const T tValue) 00319 { 00320 TCriticalScopeLock Lock(m_rLock); 00321 m_tValue /= tValue; 00322 return *this; 00323 } 00324 00325 00326 END_NAMESPACE_Zeus 00327 00328 #endif 00329