pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_Atomic.h
00001 /*
00002  -------------------------------------------------------------------------------
00003  This file is part of the Plink, Plonk, Plank libraries
00004   by Martin Robinson
00005  
00006  http://code.google.com/p/pl-nk/
00007  
00008  Copyright University of the West of England, Bristol 2011-14
00009  All rights reserved.
00010  
00011  Redistribution and use in source and binary forms, with or without
00012  modification, are permitted provided that the following conditions are met:
00013  
00014  * Redistributions of source code must retain the above copyright
00015    notice, this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright
00017    notice, this list of conditions and the following disclaimer in the
00018    documentation and/or other materials provided with the distribution.
00019  * Neither the name of University of the West of England, Bristol nor 
00020    the names of its contributors may be used to endorse or promote products
00021    derived from this software without specific prior written permission.
00022  
00023  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00026  DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 
00027  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00028  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00029  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00030  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00031  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
00032  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00033  
00034  This software makes use of third party libraries. For more information see:
00035  doc/license.txt included in the distribution.
00036  -------------------------------------------------------------------------------
00037  */
00038 
00039 #ifndef PLONK_ATOMIC_H
00040 #define PLONK_ATOMIC_H
00041 
00043 class AtomicOps //: public PlonkBase // need to reorganise headers etc
00044 {
00045 public:
00046     inline static void memoryBarrier() throw()
00047     {
00048         pl_AtomicMemoryBarrier();
00049     }
00050 };
00051 
00052 template<class Type>
00053 class AtomicBase : public AtomicOps
00054 {
00055 };
00056 
00057 template<class Type>
00058 class AtomicBase<Type*> : public AtomicOps
00059 {
00060 public:
00061     static inline Long incrementSize() { return sizeof (Type); }
00062 };
00063 
00064 template<>
00065 class AtomicBase<void*> : public AtomicOps
00066 {
00067 public:
00068     static inline Long incrementSize() { return 1; }
00069 };
00070 
00071 
00075 template<class Type>
00076 class AtomicValue : public AtomicBase<Type>
00077 {
00078 public:
00079 };
00080 
00086 template<class Type>
00087 class AtomicExtended : public AtomicBase<Type>
00088 {
00089 };
00090 
00091 
00092 #define PLONK_ATOMIC_DEFINE(ATOMIC_CLASS,TYPECODE,FUNCCODE,NUMCODE,ALIGN) \
00093     template<>\
00094     class ATOMIC_CLASS<Plank##TYPECODE> : public AtomicBase<Plank##TYPECODE>\
00095     {\
00096     public:\
00097         typedef PlankAtomic##FUNCCODE AtomType;\
00098         typedef PlankAtomic##FUNCCODE##Ref AtomTypeRef;\
00099         \
00100         inline ATOMIC_CLASS() throw() {\
00101             pl_Atomic##FUNCCODE##_Init (getAtomicRef());\
00102         }\
00103         \
00104         inline ATOMIC_CLASS (const Plank##TYPECODE initialValue) throw() {\
00105             pl_Atomic##FUNCCODE##_Init (getAtomicRef());\
00106             pl_Atomic##FUNCCODE##_SetUnchecked (getAtomicRef(), initialValue);\
00107         }\
00108         \
00109         inline ATOMIC_CLASS (ATOMIC_CLASS const& copy) throw() {\
00110             pl_Atomic##FUNCCODE##_Init (getAtomicRef());\
00111             pl_Atomic##FUNCCODE##_SetUnchecked (getAtomicRef(), pl_Atomic##FUNCCODE##_Get (copy.getAtomicRef()));\
00112         }\
00113         \
00114         inline  ~ATOMIC_CLASS() {\
00115             pl_Atomic##FUNCCODE##_DeInit (getAtomicRef());\
00116         }\
00117         \
00118         inline ATOMIC_CLASS& operator= (ATOMIC_CLASS const& other) throw() {\
00119             if (this != &other) pl_Atomic##FUNCCODE##_Set (getAtomicRef(), pl_Atomic##FUNCCODE##_Get (other.getAtomicRef()));\
00120             return *this;\
00121         }\
00122         inline ATOMIC_CLASS& operator= (const Plank##TYPECODE other) throw() {\
00123             pl_Atomic##FUNCCODE##_Set (getAtomicRef(), other);\
00124             return *this;\
00125         }\
00126         \
00127         template<class OtherType>\
00128         inline ATOMIC_CLASS& operator= (const OtherType other) throw() {\
00129             pl_Atomic##FUNCCODE##_Set (getAtomicRef(), static_cast<const Plank##TYPECODE> (other));\
00130             return *this;\
00131         }\
00132         \
00133         inline bool compareAndSwap (const Plank##NUMCODE oldValue, const Plank##NUMCODE newValue) throw() {\
00134             return pl_Atomic##FUNCCODE##_CompareAndSwap (getAtomicRef(), oldValue, newValue);\
00135         }\
00136         \
00137         inline bool compareAndSwap (const Plank##NUMCODE newValue) throw() {\
00138             return pl_Atomic##FUNCCODE##_CompareAndSwap (getAtomicRef(), this->getValueUnchecked(), newValue);\
00139         }\
00140         \
00141         inline Plank##NUMCODE swap (const Plank##NUMCODE newValue) throw() {\
00142             return pl_Atomic##FUNCCODE##_Swap (getAtomicRef(), newValue);\
00143         }\
00144         inline void swapWith (ATOMIC_CLASS& other) throw() {\
00145             return pl_Atomic##FUNCCODE##_SwapOther (getAtomicRef(), other.getAtomicRef());\
00146         }\
00147         \
00148         inline void setValue (const Plank##TYPECODE other) throw() { pl_Atomic##FUNCCODE##_Set (getAtomicRef(), other); }\
00149         inline Plank##TYPECODE getValue() const throw() { return pl_Atomic##FUNCCODE##_Get (getAtomicRef()); }\
00150         inline Plank##TYPECODE getValueUnchecked() const throw() { return pl_Atomic##FUNCCODE##_GetUnchecked (getAtomicRef()); }\
00151         \
00152         template<class OtherType> operator OtherType () const throw() { return static_cast<OtherType> (pl_Atomic##FUNCCODE##_Get (getAtomicRef())); }\
00153         inline operator Plank##TYPECODE () const throw() { return pl_Atomic##FUNCCODE##_Get (getAtomicRef()); }\
00154         inline const Plank##NUMCODE getExtra() const throw() { return pl_Atomic##FUNCCODE##_GetExtra (getAtomicRef()); }\
00155         inline const Plank##NUMCODE getExtraUnchecked() const throw() { return pl_Atomic##FUNCCODE##_GetExtraUnchecked (getAtomicRef()); }\
00156         inline const Plank##TYPECODE operator+= (const Plank##NUMCODE operand) throw() { return pl_Atomic##FUNCCODE##_Add (getAtomicRef(), operand); }\
00157         inline const Plank##TYPECODE operator-= (const Plank##NUMCODE operand) throw() { return pl_Atomic##FUNCCODE##_Add (getAtomicRef(), -operand); }\
00158         inline const Plank##TYPECODE operator++() throw() { return pl_Atomic##FUNCCODE##_Increment (getAtomicRef()); }\
00159         inline const Plank##TYPECODE operator--() throw() { return pl_Atomic##FUNCCODE##_Decrement (getAtomicRef()); }\
00160         inline const Plank##TYPECODE operator++ (int) throw() { const Plank##TYPECODE oldValue = pl_Atomic##FUNCCODE##_Get (getAtomicRef()); ++(*this); return oldValue; }\
00161         inline const Plank##TYPECODE operator-- (int) throw() { const Plank##TYPECODE oldValue = pl_Atomic##FUNCCODE##_Get (getAtomicRef()); --(*this); return oldValue; }\
00162         \
00163         template<class OtherType> bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == Plank##TYPECODE (other); }\
00164         template<class OtherType> bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != Plank##TYPECODE (other); }\
00165         template<class OtherType> bool operator<  (OtherType const& other) const throw() { return this->getValueUnchecked() <  Plank##TYPECODE (other); }\
00166         template<class OtherType> bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= Plank##TYPECODE (other); }\
00167         template<class OtherType> bool operator>  (OtherType const& other) const throw() { return this->getValueUnchecked() >  Plank##TYPECODE (other); }\
00168         template<class OtherType> bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= Plank##TYPECODE (other); }\
00169         \
00170         inline const void setIfLarger (const Plank##TYPECODE newValue) throw()\
00171         {\
00172             Plank##TYPECODE oldValue;\
00173             bool success;\
00174             do {\
00175                 oldValue = getValueUnchecked();\
00176                 success = compareAndSwap (oldValue, newValue > oldValue ? newValue : oldValue);\
00177             } while (!success);\
00178         }\
00179         \
00180         inline const void setIfSmaller (const Plank##TYPECODE newValue) throw()\
00181         {\
00182             Plank##TYPECODE oldValue;\
00183             bool success;\
00184             do {\
00185                 oldValue = getValueUnchecked();\
00186                 success = compareAndSwap (oldValue, newValue < oldValue ? newValue : oldValue);\
00187             } while (!success);\
00188         }\
00189         \
00190         inline AtomTypeRef getAtomicRef() { return static_cast<AtomTypeRef> (&atomic); }\
00191         inline const AtomTypeRef getAtomicRef() const { return const_cast<AtomTypeRef> (&atomic); }\
00192     private:\
00193         \
00194         PLONK_ALIGN(ALIGN)\
00195         AtomType atomic;\
00196     };
00197 
00198 #define PLONK_ATOMIC_DEFINE_SIMPLE(TYPECODE,ALIGN) PLONK_ATOMIC_DEFINE(AtomicValue,TYPECODE,TYPECODE,TYPECODE,ALIGN)
00199 
00200 PLONK_ATOMIC_DEFINE_SIMPLE(I,4);
00201 PLONK_ATOMIC_DEFINE(AtomicValue,UI,I,I,4);
00202 PLONK_ATOMIC_DEFINE_SIMPLE(L,PLONK_WORDSIZE);
00203 PLONK_ATOMIC_DEFINE(AtomicValue,UL,L,L,PLONK_WORDSIZE);
00204 
00205 #if !(PLANK_WIN && PLANK_64BIT) || DOXYGEN
00206 PLONK_ATOMIC_DEFINE_SIMPLE(LL,8);
00207 PLONK_ATOMIC_DEFINE(AtomicValue,ULL,LL,LL,8);
00208 #endif
00209 
00210 PLONK_ATOMIC_DEFINE_SIMPLE(F,4);
00211 PLONK_ATOMIC_DEFINE_SIMPLE(D,8);
00212 
00213 template<class Type>
00214 class AtomicValue<Type*> : public AtomicBase<Type*>
00215 {
00216 public:
00217     inline AtomicValue() throw() 
00218     {
00219         pl_AtomicP_Init (getAtomicRef());
00220     }
00221 
00222     inline AtomicValue (Type& initialValue) throw() 
00223     {
00224         pl_AtomicP_Init (getAtomicRef());
00225         pl_AtomicP_SetUnchecked (getAtomicRef(), &initialValue);
00226     }
00227     
00228         template<class OtherType>
00229     inline AtomicValue (OtherType* initialPtr) throw() 
00230     {
00231         pl_AtomicP_Init (getAtomicRef());
00232         pl_AtomicP_SetUnchecked (getAtomicRef(), static_cast<Type*> (initialPtr));
00233     }
00234     
00235     inline AtomicValue (Type* initialPtr) throw() 
00236     {
00237         pl_AtomicP_Init (getAtomicRef());
00238         pl_AtomicP_SetUnchecked (getAtomicRef(), initialPtr);
00239     }
00240     
00241     inline AtomicValue (AtomicValue const& copy) throw() 
00242     {
00243         pl_AtomicP_Init (getAtomicRef());
00244         pl_AtomicP_SetUnchecked (getAtomicRef(), pl_AtomicP_Get (copy.getAtomicRef()));
00245     }
00246     
00247     inline ~AtomicValue() 
00248     {
00249         pl_AtomicP_DeInit (getAtomicRef());
00250     }
00251     
00252     inline AtomicValue& operator= (AtomicValue const& other) throw() 
00253     {
00254         if (this != &other) 
00255             pl_AtomicP_Set (getAtomicRef(), pl_AtomicP_Get (other.getAtomicRef()));
00256         
00257         return *this;
00258     }
00259         
00260         template<class OtherType>
00261     inline AtomicValue& operator= (OtherType* other) throw() 
00262     {
00263         pl_AtomicP_Set (getAtomicRef(), static_cast<Type*> (other));
00264         return *this;
00265     }    
00266 
00267     inline AtomicValue& operator= (Type& other) throw() 
00268     {
00269         pl_AtomicP_Set (getAtomicRef(), static_cast<Type*> (&other));
00270         return *this;
00271     }    
00272     
00273     inline bool compareAndSwap (const Type* oldValue, const Type* newValue) throw() 
00274     {
00275         return pl_AtomicP_CompareAndSwap (getAtomicRef(), oldValue, newValue);
00276     }
00277     
00278     inline bool compareAndSwap (const Type* newValue) throw() 
00279     {
00280         return pl_AtomicP_CompareAndSwap (getAtomicRef(), this->getValueUnchecked(), newValue);
00281     }
00282     
00283     inline Type* swap (const Type* newValue) throw() 
00284     {
00285         return pl_AtomicP_Swap (getAtomicRef(), newValue);
00286     }
00287     
00288     inline void swapWith (AtomicValue& other) throw() 
00289     {
00290         return pl_AtomicP_SwapOther (getAtomicRef(), other.getAtomicRef());
00291     }
00292 
00293     inline void setValue (Type* other) throw()              { pl_AtomicP_Set (getAtomicRef(), static_cast<void*> (other)); }
00294     inline void setPtr (Type* other) throw()                { pl_AtomicP_Set (getAtomicRef(), static_cast<void*> (other)); }
00295 
00296     inline Type* getValue() const throw()                   { return static_cast<Type*> (pl_AtomicP_Get (getAtomicRef())); }
00297     inline Type* getPtr() const throw()                     { return static_cast<Type*> (pl_AtomicP_Get (getAtomicRef())); }
00298     inline Type* operator->() const throw()                 { return static_cast<Type*> (pl_AtomicP_Get (getAtomicRef())); }
00299 
00300     inline Type* getValueUnchecked() const throw()          { return static_cast<Type*> (pl_AtomicP_GetUnchecked (getAtomicRef())); }
00301     inline Type* getPtrUnchecked() const throw()            { return static_cast<Type*> (pl_AtomicP_GetUnchecked (getAtomicRef())); }
00302     inline Long getExtra() const throw()                    { return pl_AtomicP_GetExtra (getAtomicRef()); }
00303     inline Long getExtraUnchecked() const throw()           { return pl_AtomicP_GetExtraUnchecked (getAtomicRef()); }
00304 
00305     inline operator const Type* () const throw()            { return static_cast<const Type*> (pl_AtomicP_GetUnchecked (getAtomicRef())); }
00306     inline operator Type* () const throw()                  { return static_cast<Type*> (pl_AtomicP_GetUnchecked (getAtomicRef())); }
00307 
00308     inline void deletePtr() throw()                         { delete this->getPtrUnchecked(); }
00309     inline void deleteAndZeroPtr() throw()                  { delete this->swap (0); }
00310 
00311     template<class OtherType> inline bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == static_cast<Type*> (other); }
00312     template<class OtherType> inline bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != static_cast<Type*> (other); }
00313     template<class OtherType> inline bool operator<  (OtherType const& other) const throw() { return this->getValueUnchecked() <  static_cast<Type*> (other); }
00314     template<class OtherType> inline bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= static_cast<Type*> (other); }
00315     template<class OtherType> inline bool operator>  (OtherType const& other) const throw() { return this->getValueUnchecked() >  static_cast<Type*> (other); }
00316     template<class OtherType> inline bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= static_cast<Type*> (other); }
00317 
00318     inline bool operator== (Type* const other) const throw() { return this->getPtrUnchecked() == other; }
00319     inline bool operator!= (Type* const other) const throw() { return this->getPtrUnchecked() != other; }
00320     inline bool operator<  (Type* const other) const throw() { return this->getPtrUnchecked() <  other; }
00321     inline bool operator<= (Type* const other) const throw() { return this->getPtrUnchecked() <= other; }
00322     inline bool operator>  (Type* const other) const throw() { return this->getPtrUnchecked() >  other; }
00323     inline bool operator>= (Type* const other) const throw() { return this->getPtrUnchecked() >= other; }
00324 
00325     inline Type* const operator+= (const Long operand) throw() 
00326     { 
00327         return pl_AtomicP_Add (getAtomicRef(), operand * AtomicValue::incrementSize()); 
00328     }
00329     
00330     inline Type* const operator-= (const Long operand) throw() 
00331     { 
00332         return pl_AtomicP_Add (getAtomicRef(), -operand * AtomicValue::incrementSize()); 
00333     }
00334     
00335     inline Type* const operator++() throw() 
00336     { 
00337         return pl_AtomicP_Add (getAtomicRef(), AtomicValue::incrementSize()); 
00338     }
00339     
00340     inline Type* const operator--() throw() 
00341     { 
00342         return pl_AtomicP_Subtract (getAtomicRef(), AtomicValue::incrementSize()); 
00343     }
00344     
00345     inline Type* const operator++ (int) throw() 
00346     { 
00347         Type* const oldPtr = static_cast<Type*> (pl_AtomicP_Get (getAtomicRef())); 
00348         ++(*this); 
00349         return oldPtr; 
00350     }
00351     
00352     inline Type* const operator-- (int) throw() 
00353     { 
00354         Type* const oldPtr = static_cast<Type*> (pl_AtomicP_Get (getAtomicRef())); 
00355         --(*this); 
00356         return oldPtr; 
00357     }
00358     
00359     inline PlankAtomicPRef getAtomicRef() { return static_cast<PlankAtomicPRef> (&u.atomic); }
00360     inline const PlankAtomicPRef getAtomicRef() const { return const_cast<PlankAtomicPRef> (&u.atomic); }
00361     
00362 private:
00363     union Union
00364     {
00365         PlankAtomicP atomic;
00366         Type* ptr;
00367     };
00368     
00369     PLONK_ALIGN(PLONK_WORDSIZE) Union u;
00370 };
00371 
00372 template<>
00373 class AtomicValue<void*> : public AtomicBase<void*>
00374 {
00375 public:
00376     inline AtomicValue() throw() 
00377     {
00378         pl_AtomicP_Init (getAtomicRef());
00379     }
00380         
00381         template<class OtherType>
00382     inline AtomicValue (OtherType* initialPtr) throw() 
00383     {
00384         pl_AtomicP_Init (getAtomicRef());
00385         pl_AtomicP_SetUnchecked (getAtomicRef(), static_cast<void*> (initialPtr));
00386     }
00387     
00388     inline AtomicValue (void* initialPtr) throw() 
00389     {
00390         pl_AtomicP_Init (getAtomicRef());
00391         pl_AtomicP_SetUnchecked (getAtomicRef(), initialPtr);
00392     }
00393     
00394     inline AtomicValue (AtomicValue const& copy) throw() 
00395     {
00396         pl_AtomicP_Init (getAtomicRef());
00397         pl_AtomicP_SetUnchecked (getAtomicRef(), pl_AtomicP_Get (copy.getAtomicRef()));
00398     }
00399     
00400     inline ~AtomicValue() 
00401     {
00402         pl_AtomicP_DeInit (getAtomicRef());
00403     }
00404     
00405     inline AtomicValue& operator= (AtomicValue const& other) throw() 
00406     {
00407         if (this != &other) 
00408             pl_AtomicP_Set (getAtomicRef(), pl_AtomicP_Get (other.getAtomicRef()));
00409         
00410         return *this;
00411     }
00412     
00413         template<class OtherType>
00414     inline AtomicValue& operator= (OtherType* other) throw() 
00415     {
00416         pl_AtomicP_Set (getAtomicRef(), static_cast<void*> (other));
00417         return *this;
00418     }    
00419         
00420     inline bool compareAndSwap (void* oldValue, void* newValue) throw() 
00421     {
00422         return pl_AtomicP_CompareAndSwap (getAtomicRef(), oldValue, newValue);
00423     }
00424     
00425     inline bool compareAndSwap (void* newValue) throw() 
00426     {
00427         return pl_AtomicP_CompareAndSwap (getAtomicRef(), this->getValueUnchecked(), newValue);
00428     }
00429     
00430     inline void* swap (void* newValue) throw() 
00431     {
00432         return pl_AtomicP_Swap (getAtomicRef(), newValue);
00433     }
00434     
00435     inline void swapWith (AtomicValue& other) throw() 
00436     {
00437         return pl_AtomicP_SwapOther (getAtomicRef(), other.getAtomicRef());
00438     }
00439     
00440     inline void setValue (void* other) throw()              { pl_AtomicP_Set (getAtomicRef(), static_cast<void*> (other)); }
00441     inline void setPtr (void* other) throw()                { pl_AtomicP_Set (getAtomicRef(), static_cast<void*> (other)); }
00442         
00443     inline void* getValue() const throw()                   { return pl_AtomicP_Get (getAtomicRef()); }
00444     inline void* getPtr() const throw()                     { return pl_AtomicP_Get (getAtomicRef()); }
00445     inline void* operator->() const throw()                 { return pl_AtomicP_Get (getAtomicRef()); }
00446     
00447     inline void* getValueUnchecked() const throw()          { return pl_AtomicP_GetUnchecked (getAtomicRef()); }
00448     inline void* getPtrUnchecked() const throw()            { return pl_AtomicP_GetUnchecked (getAtomicRef()); }
00449     inline UnsignedLong getExtra() const throw()                    { return pl_AtomicP_GetExtra (getAtomicRef()); }
00450     inline UnsignedLong getExtraUnchecked() const throw()           { return pl_AtomicP_GetExtraUnchecked (getAtomicRef()); }
00451     
00452     inline operator const void* () const throw()            { return static_cast<const void*> (pl_AtomicP_GetUnchecked (getAtomicRef())); }
00453     inline operator void* () const throw()                  { return pl_AtomicP_GetUnchecked (getAtomicRef()); }
00454         
00455     template<class OtherType> inline bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == reinterpret_cast<void*> (other); }
00456     template<class OtherType> inline bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != reinterpret_cast<void*> (other); }
00457     template<class OtherType> inline bool operator<  (OtherType const& other) const throw() { return this->getValueUnchecked() <  reinterpret_cast<void*> (other); }
00458     template<class OtherType> inline bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= reinterpret_cast<void*> (other); }
00459     template<class OtherType> inline bool operator>  (OtherType const& other) const throw() { return this->getValueUnchecked() >  reinterpret_cast<void*> (other); }
00460     template<class OtherType> inline bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= reinterpret_cast<void*> (other); }
00461     
00462     inline bool operator== (void* const other) const throw() { return this->getPtrUnchecked() == other; }
00463     inline bool operator!= (void* const other) const throw() { return this->getPtrUnchecked() != other; }
00464     inline bool operator<  (void* const other) const throw() { return this->getPtrUnchecked() <  other; }
00465     inline bool operator<= (void* const other) const throw() { return this->getPtrUnchecked() <= other; }
00466     inline bool operator>  (void* const other) const throw() { return this->getPtrUnchecked() >  other; }
00467     inline bool operator>= (void* const other) const throw() { return this->getPtrUnchecked() >= other; }
00468     
00469     inline void* const operator+= (const Long operand) throw() 
00470     { 
00471         return pl_AtomicP_Add (getAtomicRef(), operand * AtomicValue::incrementSize()); 
00472     }
00473     
00474     inline void* const operator-= (const Long operand) throw() 
00475     { 
00476         return pl_AtomicP_Add (getAtomicRef(), -operand * AtomicValue::incrementSize()); 
00477     }
00478     
00479     inline void* const operator++() throw() 
00480     { 
00481         return pl_AtomicP_Add (getAtomicRef(), AtomicValue::incrementSize()); 
00482     }
00483     
00484     inline void* const operator--() throw() 
00485     { 
00486         return pl_AtomicP_Subtract (getAtomicRef(), AtomicValue::incrementSize()); 
00487     }
00488     
00489     inline void* const operator++ (int) throw() 
00490     { 
00491         void* const oldPtr = pl_AtomicP_Get (getAtomicRef()); 
00492         ++(*this); 
00493         return oldPtr; 
00494     }
00495     
00496     inline void* const operator-- (int) throw() 
00497     { 
00498         void* const oldPtr = pl_AtomicP_Get (getAtomicRef()); 
00499         --(*this); 
00500         return oldPtr; 
00501     }
00502     
00503     inline PlankAtomicPRef getAtomicRef() { return static_cast<PlankAtomicPRef> (&atomic); }
00504     inline const PlankAtomicPRef getAtomicRef() const { return const_cast<PlankAtomicPRef> (&atomic); }
00505    
00506 private:
00507     PLONK_ALIGN(PLONK_WORDSIZE) 
00508     PlankAtomicP atomic;
00509 };
00510 
00511 
00512 template<class Type>
00513 class AtomicExtended<Type*> : public AtomicBase<Type*>
00514 {
00515 public:
00516     
00517     template<class OtherType>
00518     static inline bool ptrUsesValidBits (OtherType* ptr) throw()
00519     {
00520         union Utility
00521         {
00522             OtherType* ptr;
00523             UnsignedLong bits;
00524         };
00525 
00526         Utility u;
00527         u.ptr = ptr;
00528         return (u.bits & PLANK_ATOMIC_PMASK) == u.bits;
00529     }
00530     
00531     inline AtomicExtended() throw() 
00532     {
00533         pl_AtomicPX_Init (getAtomicRef());
00534     }
00535     
00536     inline AtomicExtended (Type& initialValue) throw() 
00537     {
00538         plonk_assert (ptrUsesValidBits (&initialValue));
00539         pl_AtomicPX_Init (getAtomicRef());
00540         pl_AtomicPX_SetAllUnchecked (getAtomicRef(), static_cast<void*> (&initialValue), 0);
00541     }
00542     
00543         template<class OtherType>
00544     inline AtomicExtended (OtherType* const initialPtr) throw() 
00545     {
00546         plonk_assert (ptrUsesValidBits (initialPtr));
00547         pl_AtomicPX_Init (getAtomicRef());
00548         pl_AtomicPX_SetAllUnchecked (getAtomicRef(), static_cast<Type*> (initialPtr), 0);
00549     }
00550     
00551     inline AtomicExtended (Type* initialPtr) throw() 
00552     {
00553         plonk_assert (ptrUsesValidBits (initialPtr));
00554         pl_AtomicPX_Init (getAtomicRef());
00555         pl_AtomicPX_SetAllUnchecked (getAtomicRef(), initialPtr, 0);
00556     }
00557     
00558     inline AtomicExtended (Type* initialPtr, const UnsignedLong extra) throw()
00559     {
00560         plonk_assert (ptrUsesValidBits (initialPtr));
00561         pl_AtomicPX_Init (getAtomicRef());
00562         pl_AtomicPX_SetAllUnchecked (getAtomicRef(), initialPtr, extra);
00563     }
00564     
00565     inline AtomicExtended (AtomicExtended const& copy) throw() 
00566     {
00567         pl_AtomicPX_Init (getAtomicRef());
00568         pl_AtomicPX_SetAllUnchecked (getAtomicRef(), pl_AtomicPX_Get (copy.getAtomicRef()), 0);
00569     }
00570     
00571     inline ~AtomicExtended() 
00572     {
00573         pl_AtomicPX_DeInit (getAtomicRef());
00574     }
00575     
00576     inline AtomicExtended& operator= (AtomicExtended const& other) throw() 
00577     {
00578         if (this != &other) 
00579             pl_AtomicPX_Set (getAtomicRef(), pl_AtomicPX_Get (other.getAtomicRef()));
00580         
00581         return *this;
00582     }
00583     
00584 //    inline AtomicExtended& operator= (void* other) throw() 
00585 //    {
00586 //        plonk_assert (other == 0);
00587 //        pl_AtomicPX_Set (getAtomicRef(), static_cast<Type*> (other));
00588 //        return *this;
00589 //    }    
00590 //    
00591 
00592         template<class OtherType>
00593     inline AtomicExtended& operator= (OtherType* const other) throw() 
00594     {
00595         plonk_assert (ptrUsesValidBits (other));
00596         pl_AtomicPX_Set (getAtomicRef(), static_cast<Type*> (other));
00597         return *this;
00598     }    
00599     
00600 //    inline AtomicExtended& operator= (Type& other) throw() 
00601 //    {
00602 //        pl_AtomicPX_Set (getAtomicRef(), static_cast<void*> (&other));
00603 //        return *this;
00604 //    }    
00605 
00606     inline AtomicExtended& operator= (Type* other) throw() 
00607     {
00608         plonk_assert (ptrUsesValidBits (other));
00609         pl_AtomicPX_Set (getAtomicRef(), const_cast<Type*> (other));
00610         return *this;
00611     }        
00612     
00613     inline void setAll (Type* const other, const UnsignedLong extra) throw()
00614     {
00615         plonk_assert (ptrUsesValidBits (other));
00616         pl_AtomicPX_SetAll (getAtomicRef(), other, extra);
00617     }
00618     
00619     inline bool compareAndSwap (Type* const oldValue, const UnsignedLong oldExtra, Type* const newValue, const UnsignedLong newExtra) throw()
00620     {
00621         plonk_assert (ptrUsesValidBits (newValue));
00622         return pl_AtomicPX_CompareAndSwap (getAtomicRef(), oldValue, oldExtra, newValue, newExtra);
00623     }
00624     
00625     inline bool compareAndSwap (Type* const newValue, const UnsignedLong newExtra) throw()
00626     {
00627         plonk_assert (ptrUsesValidBits (newValue));
00628         return pl_AtomicPX_CompareAndSwap (getAtomicRef(), this->getValueUnchecked(), this->getExtraUnchecked(), newValue, newExtra);
00629     }
00630     
00631     inline Type* swap (Type* const newValue) throw() 
00632     {
00633         plonk_assert (ptrUsesValidBits (newValue));
00634         return pl_AtomicPX_Swap (getAtomicRef(), newValue);
00635     }
00636     
00637     inline Type* swapAll (Type* const newValue, const UnsignedLong newExtra) throw()
00638     {
00639         plonk_assert (ptrUsesValidBits (newValue));
00640         return pl_AtomicPX_SwapAll (getAtomicRef(), newValue, newExtra, 0);
00641     }
00642     
00643     inline Type* swapAll (Type* const newValue, const UnsignedLong newExtra, UnsignedLong& oldExtra) throw()
00644     {
00645         plonk_assert (ptrUsesValidBits (newValue));
00646         return pl_AtomicPX_SwapAll (getAtomicRef(), newValue, newExtra, &oldExtra);
00647     }
00648     
00649     inline void swapWith (AtomicExtended& other) throw() 
00650     {
00651         return pl_AtomicPX_SwapOther (getAtomicRef(), other.getAtomicRef());
00652     }
00653     
00654     inline void setValue (Type* const other) throw()        { plonk_assert (ptrUsesValidBits (other)); pl_AtomicPX_Set (getAtomicRef(), static_cast<void*> (other)); }
00655     inline void setPtr (Type* const other) throw()          { plonk_assert (ptrUsesValidBits (other)); pl_AtomicPX_Set (getAtomicRef(), static_cast<void*> (other)); }
00656     
00657     inline Type* getValue() const throw()                   { return static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); }
00658     inline Type* getPtr() const throw()                     { return static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); }
00659     inline Type* operator->() const throw()                 { return static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); }
00660     
00661     inline Type* getValueUnchecked() const throw()          { return static_cast<Type*> (pl_AtomicPX_GetUnchecked (getAtomicRef())); }
00662     inline Type* getPtrUnchecked() const throw()            { return static_cast<Type*> (pl_AtomicPX_GetUnchecked (getAtomicRef())); }
00663 
00664     inline operator const Type* () const throw()            { return static_cast<const Type*> (pl_AtomicPX_GetUnchecked (getAtomicRef())); }
00665     inline operator Type* () throw()                        { return static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); }
00666 
00667     inline UnsignedLong getExtra() const throw()            { return pl_AtomicPX_GetExtra (getAtomicRef()); }
00668     inline UnsignedLong getExtraUnchecked() const throw()   { return pl_AtomicPX_GetExtraUnchecked (getAtomicRef()); }
00669     
00670     inline void deletePtr() throw()                         { delete this->getPtrUnchecked(); }
00671     inline void deleteAndZeroPtr() throw()                  { delete this->getPtrUnchecked(); this->setPtr (0); }
00672 
00673     template<class OtherType> inline bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == static_cast<Type*> (other); }
00674     template<class OtherType> inline bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != static_cast<Type*> (other); }
00675     template<class OtherType> inline bool operator<  (OtherType const& other) const throw() { return this->getValueUnchecked() <  static_cast<Type*> (other); }
00676     template<class OtherType> inline bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= static_cast<Type*> (other); }
00677     template<class OtherType> inline bool operator>  (OtherType const& other) const throw() { return this->getValueUnchecked() >  static_cast<Type*> (other); }
00678     template<class OtherType> inline bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= static_cast<Type*> (other); }
00679     
00680     inline bool operator== (Type* const other) const throw() { return this->getPtrUnchecked() == other; }
00681     inline bool operator!= (Type* const other) const throw() { return this->getPtrUnchecked() != other; }
00682     inline bool operator<  (Type* const other) const throw() { return this->getPtrUnchecked() <  other; }
00683     inline bool operator<= (Type* const other) const throw() { return this->getPtrUnchecked() <= other; }
00684     inline bool operator>  (Type* const other) const throw() { return this->getPtrUnchecked() >  other; }
00685     inline bool operator>= (Type* const other) const throw() { return this->getPtrUnchecked() >= other; }
00686 
00687 //    inline Type* const operator+= (const Long operand) throw() 
00688 //    { 
00689 //        return pl_AtomicPX_Add (getAtomicRef(), operand * AtomicExtended::incrementSize()); 
00690 //    }
00691 //    
00692 //    inline Type* const operator-= (const Long operand) throw() 
00693 //    { 
00694 //        return pl_AtomicPX_Add (getAtomicRef(), -operand * AtomicExtended::incrementSize()); 
00695 //    }
00696 //    
00697 //    inline Type* const operator++() throw() 
00698 //    { 
00699 //        return pl_AtomicPX_Add (getAtomicRef(), AtomicExtended::incrementSize()); 
00700 //    }
00701 //    
00702 //    inline Type* const operator--() throw() 
00703 //    { 
00704 //        return pl_AtomicPX_Subtract (getAtomicRef(), AtomicExtended::incrementSize()); 
00705 //    }
00706 //    
00707 //    inline Type* const operator++ (int) throw() 
00708 //    { 
00709 //        Type* const oldPtr = static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); 
00710 //        ++(*this); 
00711 //        return oldPtr; 
00712 //    }
00713 //    
00714 //    inline Type* const operator-- (int) throw() 
00715 //    { 
00716 //        Type* const oldPtr = static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); 
00717 //        --(*this); 
00718 //        return oldPtr; 
00719 //    }
00720     
00721     inline PlankAtomicPXRef getAtomicRef() { return static_cast<PlankAtomicPXRef> (&atomic); }
00722     inline const PlankAtomicPXRef getAtomicRef() const { return const_cast<PlankAtomicPXRef> (&atomic); }
00723     
00724 private:
00725     PLONK_ALIGN(PLONK_WIDESIZE) PlankAtomicPX atomic;
00726 };
00727 
00728 template<>
00729 class AtomicExtended<Int> : public AtomicBase<LongLong>
00730 {
00731 public:
00732     inline AtomicExtended() throw() 
00733     {
00734     }
00735     
00736     inline AtomicExtended (const Int initialValue) throw() 
00737     :   atom (fromParts (initialValue, 0))
00738     {
00739     }    
00740     
00741     inline AtomicExtended (AtomicExtended const& copy) throw() 
00742     {
00743         setValue (copy.getValue());
00744     }
00745     
00746     inline ~AtomicExtended() 
00747     {
00748         plonk_staticassert (sizeof (Separate) == sizeof (LongLong));
00749         plonk_staticassert (sizeof (Element) == sizeof (LongLong));
00750     }
00751     
00752     inline AtomicExtended& operator= (AtomicExtended const& other) throw() 
00753     {
00754         if (this != &other) 
00755             setValue (other.getValue());
00756         
00757         return *this;
00758     }
00759     
00760     inline AtomicExtended& operator= (const Int other) throw() 
00761     {
00762         setValue (other);
00763         return *this;
00764     }        
00765     
00766     inline void setAll (const Int other, const Int extra) throw() 
00767     { 
00768         atom.setValue (fromParts (other, extra));
00769     }
00770     
00771     inline bool compareAndSwap (const Int oldValue, const Int oldExtra, const Int newValue, const Int newExtra) throw() 
00772     {
00773         return atom.compareAndSwap (fromParts (oldValue, oldExtra), fromParts (newValue, newExtra));
00774     }
00775     
00776     inline bool compareAndSwap (const Int newValue, const Int newExtra) throw() 
00777     {
00778         return atom.compareAndSwap (atom.getValueUnchecked(), fromParts (newValue, newExtra));
00779     }
00780     
00781     inline Int swap (const Int newValue) throw() 
00782     {
00783         bool success;
00784         Element oldAll, newAll;
00785         
00786         do 
00787         {
00788             oldAll.whole = atom.getValueUnchecked();
00789             newAll.separate.value = newValue;
00790             newAll.separate.extra = oldAll.separate.extra + 1;
00791             success = atom.compareAndSwap (oldAll.whole, newAll.whole);
00792         } while (!success);
00793         
00794         return oldAll.separate.value;
00795     }
00796     
00797     Int swapAll (const Int newValue, const Int newExtra) throw() 
00798     {
00799         return swapAll (newValue, newExtra, 0);
00800     }
00801     
00802     Int swapAll (const Int newValue, const Int newExtra, Int* oldExtraPtr) throw() 
00803     {
00804         bool success;
00805         Element oldAll;
00806         
00807         do 
00808         {
00809             oldAll.whole = atom.getValueUnchecked();
00810             success = atom.compareAndSwap (oldAll.whole, fromParts (newValue, newExtra));
00811         } while (!success);
00812         
00813         if (oldExtraPtr != 0)
00814             *oldExtraPtr = oldAll.separate.extra;
00815         
00816         return oldAll.separate.value;
00817     }
00818     
00819     inline void setValue (const Int other) throw() 
00820     { 
00821         swap (other);
00822     }
00823     
00824     inline Int getValue() const throw() 
00825     { 
00826         Element element;
00827         element.whole = atom.getValue();
00828         return element.separate.value;
00829     }
00830     
00831     inline Int getExtra() const throw() 
00832     { 
00833         Element element;
00834         element.whole = atom.getValue();
00835         return element.separate.extra;
00836     }
00837     
00838     inline Int getValueUnchecked() const throw() 
00839     { 
00840         Element element;
00841         element.whole = atom.getValueUnchecked();
00842         return element.separate.value;
00843     }
00844     
00845     inline Int getExtraUnchecked() const throw() 
00846     { 
00847         Element element;
00848         element.whole = atom.getValueUnchecked();
00849         return element.separate.extra;
00850     }
00851     
00852     template<class OtherType> bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == static_cast<Int> (other); }
00853     template<class OtherType> bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != static_cast<Int> (other); }
00854     template<class OtherType> bool operator<  (OtherType const& other) const throw() { return this->getValueUnchecked() <  static_cast<Int> (other); }
00855     template<class OtherType> bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= static_cast<Int> (other); }
00856     template<class OtherType> bool operator>  (OtherType const& other) const throw() { return this->getValueUnchecked() >  static_cast<Int> (other); }
00857     template<class OtherType> bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= static_cast<Int> (other); }
00858     
00859     bool operator== (const Int other) const throw() { return this->getValueUnchecked() == other; }
00860     bool operator!= (const Int other) const throw() { return this->getValueUnchecked() != other; }
00861     bool operator<  (const Int other) const throw() { return this->getValueUnchecked() <  other; }
00862     bool operator<= (const Int other) const throw() { return this->getValueUnchecked() <= other; }
00863     bool operator>  (const Int other) const throw() { return this->getValueUnchecked() >  other; }
00864     bool operator>= (const Int other) const throw() { return this->getValueUnchecked() >= other; }
00865 
00866     inline Int operator+= (const Int operand) throw() 
00867     { 
00868         bool success;
00869         Element oldAll, newAll;
00870         
00871         do 
00872         {
00873             oldAll.whole = atom.getValueUnchecked();
00874             newAll.separate.value = oldAll.separate.value + operand;
00875             newAll.separate.extra = oldAll.separate.extra + 1;
00876             success = atom.compareAndSwap (oldAll.whole, newAll.whole);
00877         } while (!success);
00878         
00879         return newAll.separate.value;
00880     }
00881     
00882     inline Int operator-= (const Int operand) throw() 
00883     { 
00884         return operator+= (-operand);
00885     }
00886     
00887     inline Int operator++() throw() 
00888     { 
00889         return operator+= (1);
00890     }
00891     
00892     inline Int operator--() throw() 
00893     { 
00894         return operator+= (-1);
00895     }
00896     
00897     inline Int operator++ (int) throw() 
00898     { 
00899         const Int oldValue = getValueUnchecked(); 
00900         ++(*this); 
00901         return oldValue; 
00902     }
00903     
00904     inline Int operator-- (int) throw() 
00905     { 
00906         const Int oldValue = getValueUnchecked(); 
00907         --(*this); 
00908         return oldValue; 
00909     }
00910     
00911 private:    
00912     AtomicValue<LongLong> atom;
00913     
00914     struct Separate
00915     {
00916         Int value;
00917         Int extra;
00918     };
00919         
00920     union Element
00921     {
00922         Separate separate;
00923         LongLong whole;
00924     };
00925     
00926     static inline LongLong fromParts (const Int value, const Int extra) throw()
00927     {
00928         Element element;
00929         element.separate.value = value;
00930         element.separate.extra = extra;
00931         return element.whole;
00932     }
00933     
00934     static inline Separate fromWhole (LongLong const& whole) throw()
00935     {
00936         Element element;
00937         element.whole = whole;
00938         return element.separate;
00939     }
00940     
00941 };
00942 
00943 template<>
00944 class AtomicExtended<Short> : public AtomicBase<Int>
00945 {
00946 public:
00947     inline AtomicExtended() throw() 
00948     {
00949     }
00950     
00951     inline AtomicExtended (const Short initialValue) throw() 
00952     :   atom (fromParts (initialValue, 0))
00953     {
00954     }    
00955     
00956     inline AtomicExtended (AtomicExtended const& copy) throw() 
00957     {
00958         setValue (copy.getValue());
00959     }
00960     
00961     inline ~AtomicExtended() 
00962     {
00963         plonk_staticassert (sizeof (Separate) == sizeof (Int));
00964         plonk_staticassert (sizeof (Element) == sizeof (Int));
00965     }
00966     
00967     inline AtomicExtended& operator= (AtomicExtended const& other) throw() 
00968     {
00969         if (this != &other) 
00970             setValue (other.getValue());
00971         
00972         return *this;
00973     }
00974     
00975     inline AtomicExtended& operator= (const Short other) throw() 
00976     {
00977         setValue (other);
00978         return *this;
00979     }        
00980     
00981     inline void setAll (const Short other, const Short extra) throw() 
00982     { 
00983         atom.setValue (fromParts (other, extra));
00984     }
00985     
00986     inline bool compareAndSwap (const Short oldValue, const Short oldExtra, const Short newValue, const Short newExtra) throw() 
00987     {
00988         return atom.compareAndSwap (fromParts (oldValue, oldExtra), fromParts (newValue, newExtra));
00989     }
00990     
00991     inline bool compareAndSwap (const Short newValue, const Short newExtra) throw() 
00992     {
00993         return atom.compareAndSwap (atom.getValueUnchecked(), fromParts (newValue, newExtra));
00994     }
00995     
00996     inline Short swap (const Short newValue) throw() 
00997     {
00998         bool success;
00999         Element oldAll, newAll;
01000         
01001         do 
01002         {
01003             oldAll.whole = atom.getValueUnchecked();
01004             newAll.separate.value = newValue;
01005             newAll.separate.extra = oldAll.separate.extra + 1;
01006             success = atom.compareAndSwap (oldAll.whole, newAll.whole);
01007         } while (!success);
01008         
01009         return oldAll.separate.value;
01010     }
01011     
01012     Short swapAll (const Short newValue, const Short newExtra) throw() 
01013     {
01014         return swapAll (newValue, newExtra, 0);
01015     }
01016     
01017     Short swapAll (const Short newValue, const Short newExtra, Short* oldExtraPtr) throw() 
01018     {
01019         bool success;
01020         Element oldAll;
01021         
01022         do 
01023         {
01024             oldAll.whole = atom.getValueUnchecked();
01025             success = atom.compareAndSwap (oldAll.whole, fromParts (newValue, newExtra));
01026         } while (!success);
01027         
01028         if (oldExtraPtr != 0)
01029             *oldExtraPtr = oldAll.separate.extra;
01030         
01031         return oldAll.separate.value;
01032     }
01033     
01034     inline void setValue (const Short other) throw() 
01035     { 
01036         swap (other);
01037     }
01038     
01039     inline Short getValue() const throw() 
01040     { 
01041         Element element;
01042         element.whole = atom.getValue();
01043         return element.separate.value;
01044     }
01045     
01046     inline Short getExtra() const throw() 
01047     { 
01048         Element element;
01049         element.whole = atom.getValue();
01050         return element.separate.extra;
01051     }
01052     
01053     inline Short getValueUnchecked() const throw() 
01054     { 
01055         Element element;
01056         element.whole = atom.getValueUnchecked();
01057         return element.separate.value;
01058     }
01059     
01060     inline Short getExtraUnchecked() const throw() 
01061     { 
01062         Element element;
01063         element.whole = atom.getValueUnchecked();
01064         return element.separate.extra;
01065     }
01066     
01067     template<class OtherType> bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == static_cast<Short> (other); }
01068     template<class OtherType> bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != static_cast<Short> (other); }
01069     template<class OtherType> bool operator<  (OtherType const& other) const throw() { return this->getValueUnchecked() <  static_cast<Short> (other); }
01070     template<class OtherType> bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= static_cast<Short> (other); }
01071     template<class OtherType> bool operator>  (OtherType const& other) const throw() { return this->getValueUnchecked() >  static_cast<Short> (other); }
01072     template<class OtherType> bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= static_cast<Short> (other); }
01073     
01074     bool operator== (const Short other) const throw() { return this->getValueUnchecked() == other; }
01075     bool operator!= (const Short other) const throw() { return this->getValueUnchecked() != other; }
01076     bool operator<  (const Short other) const throw() { return this->getValueUnchecked() <  other; }
01077     bool operator<= (const Short other) const throw() { return this->getValueUnchecked() <= other; }
01078     bool operator>  (const Short other) const throw() { return this->getValueUnchecked() >  other; }
01079     bool operator>= (const Short other) const throw() { return this->getValueUnchecked() >= other; }
01080 
01081     inline Short operator+= (const Short operand) throw() 
01082     { 
01083         bool success;
01084         Element oldAll, newAll;
01085         
01086         do 
01087         {
01088             oldAll.whole = atom.getValueUnchecked();
01089             newAll.separate.value = oldAll.separate.value + operand;
01090             newAll.separate.extra = oldAll.separate.extra + 1;
01091             success = atom.compareAndSwap (oldAll.whole, newAll.whole);
01092         } while (!success);
01093         
01094         return newAll.separate.value;
01095     }
01096     
01097     inline Short operator-= (const Short operand) throw() 
01098     { 
01099         return operator+= (-operand);
01100     }
01101     
01102     inline Short operator++() throw() 
01103     { 
01104         return operator+= (1);
01105     }
01106     
01107     inline Short operator--() throw() 
01108     { 
01109         return operator+= (-1);
01110     }
01111     
01112     inline Short operator++ (int) throw() 
01113     { 
01114         const Short oldValue = getValueUnchecked(); 
01115         ++(*this); 
01116         return oldValue; 
01117     }
01118     
01119     inline Short operator-- (int) throw() 
01120     { 
01121         const Short oldValue = getValueUnchecked(); 
01122         --(*this); 
01123         return oldValue; 
01124     }
01125     
01126 private:    
01127     AtomicValue<Int> atom;
01128     
01129     struct Separate
01130     {
01131         Short value;
01132         Short extra;
01133     };
01134     
01135     union Element
01136     {
01137         Separate separate;
01138         Int whole;
01139     };
01140     
01141     static inline Int fromParts (const Short value, const Short extra) throw()
01142     {
01143         Element element;
01144         element.separate.value = value;
01145         element.separate.extra = extra;
01146         return element.whole;
01147     }
01148     
01149     static inline Separate fromWhole (const Short whole) throw()
01150     {
01151         Element element;
01152         element.whole = whole;
01153         return element.separate;
01154     }
01155     
01156 };
01157 
01158 
01159 #endif // PLONK_ATOMIC_H
 All Classes Functions Typedefs Enumerations Enumerator Properties