ITK  4.8.0
Insight Segmentation and Registration Toolkit
itkAtomicInt.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 /*=========================================================================
19  *
20  * Program: Visualization Toolkit
21  * Module: vtkAtomicInt.h
22  *
23  * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
24  * All rights reserved.
25  * See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
26  *
27  * This software is distributed WITHOUT ANY WARRANTY; without even
28  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
29  * PURPOSE. See the above copyright notice for more information.
30  *
31  *=========================================================================*/
32 
33 #ifndef itkAtomicInt_h
34 #define itkAtomicInt_h
35 
36 #include "itkMacro.h"
37 #include "itkIntTypes.h"
38 #include "itkConceptChecking.h"
39 #include <cstddef>
40 #include <limits>
41 
42 #include "itkAtomicIntDetail.h"
43 
44 namespace itk
45 {
46 
70 template <typename T>
71 class AtomicInt
72 {
73 private:
76 public:
78  {
79  }
80 
81  AtomicInt(T val)
82  : m_Object(static_cast<typename Impl::ValueType>(val))
83  {
84  }
85 
87  : m_Object(static_cast<typename Impl::ValueType>(ai.load()))
88  {
89  }
90 
92  {
93  return static_cast<T>(Impl::PreIncrement(&this->m_Object));
94  }
95 
96  T operator++(int)
97  {
98  return static_cast<T>(Impl::PostIncrement(&this->m_Object));
99  }
100 
102  {
103  return static_cast<T>(Impl::PreDecrement(&this->m_Object));
104  }
105 
106  T operator--(int)
107  {
108  return static_cast<T>(Impl::PostDecrement(&this->m_Object));
109  }
110 
111  T operator+=(T val)
112  {
113  return static_cast<T>(Impl::AddAndFetch(&this->m_Object,
114  static_cast<typename Impl::ValueType>(val)));
115  }
116 
117  T operator-=(T val)
118  {
119  return static_cast<T>(Impl::SubAndFetch(&this->m_Object,
120  static_cast<typename Impl::ValueType>(val)));
121  }
122 
123  operator T() const
124  {
125  return static_cast<T>(Impl::Load(&this->m_Object));
126  }
127 
128  T operator=(T val)
129  {
130  Impl::Store(&this->m_Object, static_cast<typename Impl::ValueType>(val));
131  return val;
132  }
133 
135  {
136  this->store(ai.load());
137  return *this;
138  }
139 
140  T load() const
141  {
142  return static_cast<T>(Impl::Load(&this->m_Object));
143  }
144 
145  void store(T val)
146  {
147  Impl::Store(&this->m_Object, static_cast<typename Impl::ValueType>(val));
148  }
149 
150 private:
151  typename Impl::AtomicType m_Object;
152 };
153 
154 
155 template <typename T>
156 class AtomicInt<T*>
157 {
158 private:
160 
161 public:
162  AtomicInt() : m_Object(0)
163  {
164  }
165 
166  AtomicInt(T* val)
167  : m_Object(reinterpret_cast<typename Impl::ValueType>(val))
168  {
169  }
170 
172  : m_Object(reinterpret_cast<typename Impl::ValueType>(ai.load()))
173  {
174  }
175 
177  {
178  return reinterpret_cast<T*>(Impl::AddAndFetch(&this->m_Object, sizeof(T)));
179  }
180 
181  T* operator++(int)
182  {
183  T* val = reinterpret_cast<T*>(Impl::AddAndFetch(&this->m_Object, sizeof(T)));
184  return --val;
185  }
186 
188  {
189  return reinterpret_cast<T*>(Impl::SubAndFetch(&this->m_Object, sizeof(T)));
190  }
191 
192  T* operator--(int)
193  {
194  T* val = reinterpret_cast<T*>(Impl::AddAndFetch(&this->m_Object, sizeof(T)));
195  return ++val;
196  }
197 
198  T* operator+=(std::ptrdiff_t val)
199  {
200  return reinterpret_cast<T*>(Impl::AddAndFetch(&this->m_Object,
201  val * sizeof(T)));
202  }
203 
204  T* operator-=(std::ptrdiff_t val)
205  {
206  return reinterpret_cast<T*>(Impl::SubAndFetch(&this->m_Object,
207  val * sizeof(T)));
208  }
209 
210  operator T*() const
211  {
212  return reinterpret_cast<T*>(Impl::Load(&this->m_Object));
213  }
214 
215  T* operator=(T* val)
216  {
217  Impl::Store(&this->m_Object,
218  reinterpret_cast<typename Impl::ValueType>(val));
219  return val;
220  }
221 
223  {
224  this->store(ai.load());
225  return *this;
226  }
227 
228  T* load() const
229  {
230  return reinterpret_cast<T*>(Impl::Load(&this->m_Object));
231  }
232 
233  void store(T* val)
234  {
235  Impl::Store(&this->m_Object,
236  reinterpret_cast<typename Impl::ValueType>(val));
237  }
238 
239 private:
240  typename Impl::AtomicType m_Object;
241 };
242 
243 
244 template <> class AtomicInt<void*>
245 {
246 private:
248 
249 public:
250  AtomicInt() : m_Object(0)
251  {
252  }
253 
254  AtomicInt(void* val)
255  : m_Object(reinterpret_cast<Impl::ValueType>(val))
256  {
257  }
258 
260  : m_Object(reinterpret_cast<Impl::ValueType>(ai.load()))
261  {
262  }
263 
264  operator void*() const
265  {
266  return reinterpret_cast<void*>(Impl::Load(&this->m_Object));
267  }
268 
269  void* operator=(void* val)
270  {
271  Impl::Store(&this->m_Object,
272  reinterpret_cast<Impl::ValueType>(val));
273  return val;
274  }
275 
277  {
278  this->store(ai.load());
279  return *this;
280  }
281 
282  void* load() const
283  {
284  return reinterpret_cast<void*>(Impl::Load(&this->m_Object));
285  }
286 
287  void store(void* val)
288  {
289  Impl::Store(&this->m_Object,
290  reinterpret_cast<Impl::ValueType>(val));
291  }
292 
293 private:
294  Impl::AtomicType m_Object;
295 };
296 
297 } // end namespace itk
298 #endif
T load() const
Definition: itkAtomicInt.h:140
T operator++(int)
Definition: itkAtomicInt.h:96
T * operator-=(std::ptrdiff_t val)
Definition: itkAtomicInt.h:204
Detail::AtomicOps< sizeof(void *)> Impl
Definition: itkAtomicInt.h:247
T operator=(T val)
Definition: itkAtomicInt.h:128
Provides support for atomic integers.
Definition: itkAtomicInt.h:71
void store(void *val)
Definition: itkAtomicInt.h:287
T operator+=(T val)
Definition: itkAtomicInt.h:111
AtomicInt< void * > & operator=(const AtomicInt< void * > &ai)
Definition: itkAtomicInt.h:276
Impl::AtomicType m_Object
Definition: itkAtomicInt.h:151
AtomicInt(T val)
Definition: itkAtomicInt.h:81
void * operator=(void *val)
Definition: itkAtomicInt.h:269
Detail::AtomicOps< sizeof(T *)> Impl
Definition: itkAtomicInt.h:159
Detail::AtomicOps< sizeof(T)> Impl
Definition: itkAtomicInt.h:74
T operator-=(T val)
Definition: itkAtomicInt.h:117
AtomicInt(const AtomicInt< T * > &ai)
Definition: itkAtomicInt.h:171
AtomicInt< T > & operator=(const AtomicInt< T > &ai)
Definition: itkAtomicInt.h:134
AtomicInt(const AtomicInt< void * > &ai)
Definition: itkAtomicInt.h:259
AtomicInt(const AtomicInt< T > &ai)
Definition: itkAtomicInt.h:86
Impl::AtomicType m_Object
Definition: itkAtomicInt.h:294
void store(T val)
Definition: itkAtomicInt.h:145
AtomicInt< T * > & operator=(const AtomicInt< T * > &ai)
Definition: itkAtomicInt.h:222
#define itkConceptMacro(name, concept)
void * load() const
Definition: itkAtomicInt.h:282
T * operator+=(std::ptrdiff_t val)
Definition: itkAtomicInt.h:198
Impl::AtomicType m_Object
Definition: itkAtomicInt.h:240