/*========================================================================= Program: Visualization Toolkit Module: vtkAtomic.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ // .NAME vtkAtomic - // .SECTION Description #ifndef vtkAtomic_h #define vtkAtomic_h #include "vtkCommonCoreModule.h" // For export macro #include "vtkAtomicTypeConcepts.h" #include "vtkSystemIncludes.h" #include #ifndef __VTK_WRAP__ namespace detail { template class AtomicOps; template <> class VTKCOMMONCORE_EXPORT AtomicOps<8> { public: typedef vtkTypeInt64 atomic_type; static vtkTypeInt64 AddAndFetch(vtkTypeInt64 *ref, vtkTypeInt64 val); static vtkTypeInt64 SubAndFetch(vtkTypeInt64 *ref, vtkTypeInt64 val); static vtkTypeInt64 PreIncrement(vtkTypeInt64 *ref); static vtkTypeInt64 PreDecrement(vtkTypeInt64 *ref); static vtkTypeInt64 PostIncrement(vtkTypeInt64 *ref); static vtkTypeInt64 PostDecrement(vtkTypeInt64 *ref); static vtkTypeInt64 Load(const vtkTypeInt64 *ref); static void Store(vtkTypeInt64 *ref, vtkTypeInt64 val); }; template <> class VTKCOMMONCORE_EXPORT AtomicOps<4> { public: typedef vtkTypeInt32 atomic_type; static vtkTypeInt32 AddAndFetch(vtkTypeInt32 *ref, vtkTypeInt32 val); static vtkTypeInt32 SubAndFetch(vtkTypeInt32 *ref, vtkTypeInt32 val); static vtkTypeInt32 PreIncrement(vtkTypeInt32 *ref); static vtkTypeInt32 PreDecrement(vtkTypeInt32 *ref); static vtkTypeInt32 PostIncrement(vtkTypeInt32 *ref); static vtkTypeInt32 PostDecrement(vtkTypeInt32 *ref); static vtkTypeInt32 Load(const vtkTypeInt32 *ref); static void Store(vtkTypeInt32 *ref, vtkTypeInt32 val); }; } // detail #endif // __VTK_WRAP__ template class vtkAtomic : private vtk::atomic::detail::IntegralType { private: typedef detail::AtomicOps Impl; public: vtkAtomic() : Atomic(0) { } vtkAtomic(T val) : Atomic(static_cast(val)) { } vtkAtomic(const vtkAtomic &atomic) : Atomic(static_cast(atomic.load())) { } T operator++() { return static_cast(Impl::PreIncrement(&this->Atomic)); } T operator++(int) { return static_cast(Impl::PostIncrement(&this->Atomic)); } T operator--() { return static_cast(Impl::PreDecrement(&this->Atomic)); } T operator--(int) { return static_cast(Impl::PostDecrement(&this->Atomic)); } T operator+=(T val) { return static_cast(Impl::AddAndFetch(&this->Atomic, static_cast(val))); } T operator-=(T val) { return static_cast(Impl::SubAndFetch(&this->Atomic, static_cast(val))); } operator T() const { return static_cast(Impl::Load(&this->Atomic)); } T operator=(T val) { Impl::Store(&this->Atomic, static_cast(val)); return val; } vtkAtomic& operator=(const vtkAtomic &atomic) { this->store(atomic.load()); return *this; } T load() const { return static_cast(Impl::Load(&this->Atomic)); } void store(T val) { Impl::Store(&this->Atomic, static_cast(val)); } private: typename Impl::atomic_type Atomic; }; template class vtkAtomic { private: typedef detail::AtomicOps Impl; public: vtkAtomic() : Atomic(0) { } vtkAtomic(T* val) : Atomic(reinterpret_cast(val)) { } vtkAtomic(const vtkAtomic &atomic) : Atomic(reinterpret_cast(atomic.load())) { } T* operator++() { return reinterpret_cast(Impl::AddAndFetch(&this->Atomic, sizeof(T))); } T* operator++(int) { T* val = reinterpret_cast(Impl::AddAndFetch(&this->Atomic, sizeof(T))); return --val; } T* operator--() { return reinterpret_cast(Impl::SubAndFetch(&this->Atomic, sizeof(T))); } T* operator--(int) { T* val = reinterpret_cast(Impl::AddAndFetch(&this->Atomic, sizeof(T))); return ++val; } T* operator+=(std::ptrdiff_t val) { return reinterpret_cast(Impl::AddAndFetch(&this->Atomic, val * sizeof(T))); } T* operator-=(std::ptrdiff_t val) { return reinterpret_cast(Impl::SubAndFetch(&this->Atomic, val * sizeof(T))); } operator T*() const { return reinterpret_cast(Impl::Load(&this->Atomic)); } T* operator=(T* val) { Impl::Store(&this->Atomic, reinterpret_cast(val)); return val; } vtkAtomic& operator=(const vtkAtomic &atomic) { this->store(atomic.load()); return *this; } T* load() const { return reinterpret_cast(Impl::Load(&this->Atomic)); } void store(T* val) { Impl::Store(&this->Atomic, reinterpret_cast(val)); } private: typename Impl::atomic_type Atomic; }; template <> class vtkAtomic { private: typedef detail::AtomicOps Impl; public: vtkAtomic() : Atomic(0) { } vtkAtomic(void* val) : Atomic(reinterpret_cast(val)) { } vtkAtomic(const vtkAtomic &atomic) : Atomic(reinterpret_cast(atomic.load())) { } operator void*() const { return reinterpret_cast(Impl::Load(&this->Atomic)); } void* operator=(void* val) { Impl::Store(&this->Atomic, reinterpret_cast(val)); return val; } vtkAtomic& operator=(const vtkAtomic &atomic) { this->store(atomic.load()); return *this; } void* load() const { return reinterpret_cast(Impl::Load(&this->Atomic)); } void store(void* val) { Impl::Store(&this->Atomic, reinterpret_cast(val)); } private: Impl::atomic_type Atomic; }; #endif // VTK-HeaderTest-Exclude: vtkAtomic.h