ITK  4.13.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 "itkAtomicIntDetail.h"
39 #include "itkConceptChecking.h"
40 
41 #if !ITK_COMPILER_CXX_ATOMIC
42 # include <cstddef>
43 # include <limits>
44 #else
45 # include <atomic>
46 #endif
47 
48 
49 namespace itk
50 {
51 
76  #if !ITK_COMPILER_CXX_ATOMIC
77 template <typename T>
78 class AtomicInt
79 {
80 private:
83 
84 public:
86  {
87  }
88 
89  AtomicInt(T val)
90  : m_Object(static_cast<typename Impl::ValueType>(val))
91  {
92  }
93 
95  : m_Object(static_cast<typename Impl::ValueType>(ai.load()))
96  {
97  }
98 
100  {
101  return static_cast<T>(Impl::PreIncrement(&this->m_Object));
102  }
103 
104  T operator++(int)
105  {
106  return static_cast<T>(Impl::PostIncrement(&this->m_Object));
107  }
108 
110  {
111  return static_cast<T>(Impl::PreDecrement(&this->m_Object));
112  }
113 
114  T operator--(int)
115  {
116  return static_cast<T>(Impl::PostDecrement(&this->m_Object));
117  }
118 
119  T operator+=(T val)
120  {
121  return static_cast<T>(Impl::AddAndFetch(&this->m_Object,
122  static_cast<typename Impl::ValueType>(val)));
123  }
124 
125  T operator-=(T val)
126  {
127  return static_cast<T>(Impl::SubAndFetch(&this->m_Object,
128  static_cast<typename Impl::ValueType>(val)));
129  }
130 
131  operator T() const
132  {
133  return static_cast<T>(Impl::Load(&this->m_Object));
134  }
135 
136  T operator=(T val)
137  {
138  Impl::Store(&this->m_Object, static_cast<typename Impl::ValueType>(val));
139  return val;
140  }
141 
143  {
144  this->store(ai.load());
145  return *this;
146  }
147 
148  T load() const
149  {
150  return static_cast<T>(Impl::Load(&this->m_Object));
151  }
152 
153  void store(T val)
154  {
155  Impl::Store(&this->m_Object, static_cast<typename Impl::ValueType>(val));
156  }
157 
158 private:
159  typename Impl::AtomicType m_Object;
160 };
161 
162 
163 template <typename T>
164 class AtomicInt<T*>
165 {
166 private:
168 
169 public:
170  AtomicInt() : m_Object(0)
171  {
172  }
173 
174  AtomicInt(T* val)
175  : m_Object(reinterpret_cast<typename Impl::ValueType>(val))
176  {
177  }
178 
180  : m_Object(reinterpret_cast<typename Impl::ValueType>(ai.load()))
181  {
182  }
183 
185  {
186  return reinterpret_cast<T*>(Impl::AddAndFetch(&this->m_Object, sizeof(T)));
187  }
188 
189  T* operator++(int)
190  {
191  T* val = reinterpret_cast<T*>(Impl::AddAndFetch(&this->m_Object, sizeof(T)));
192  return --val;
193  }
194 
196  {
197  return reinterpret_cast<T*>(Impl::SubAndFetch(&this->m_Object, sizeof(T)));
198  }
199 
200  T* operator--(int)
201  {
202  T* val = reinterpret_cast<T*>(Impl::AddAndFetch(&this->m_Object, sizeof(T)));
203  return ++val;
204  }
205 
206  T* operator+=(std::ptrdiff_t val)
207  {
208  return reinterpret_cast<T*>(Impl::AddAndFetch(&this->m_Object,
209  val * sizeof(T)));
210  }
211 
212  T* operator-=(std::ptrdiff_t val)
213  {
214  return reinterpret_cast<T*>(Impl::SubAndFetch(&this->m_Object,
215  val * sizeof(T)));
216  }
217 
218  operator T*() const
219  {
220  return reinterpret_cast<T*>(Impl::Load(&this->m_Object));
221  }
222 
223  T* operator=(T* val)
224  {
225  Impl::Store(&this->m_Object,
226  reinterpret_cast<typename Impl::ValueType>(val));
227  return val;
228  }
229 
231  {
232  this->store(ai.load());
233  return *this;
234  }
235 
236  T* load() const
237  {
238  return reinterpret_cast<T*>(Impl::Load(&this->m_Object));
239  }
240 
241  void store(T* val)
242  {
243  Impl::Store(&this->m_Object,
244  reinterpret_cast<typename Impl::ValueType>(val));
245  }
246 
247 private:
248  typename Impl::AtomicType m_Object;
249 };
250 
251 
252 template <> class AtomicInt<void*>
253 {
254 private:
256 
257 public:
258  AtomicInt() : m_Object(0)
259  {
260  }
261 
262  AtomicInt(void* val)
263  : m_Object(reinterpret_cast<Impl::ValueType>(val))
264  {
265  }
266 
268  : m_Object(reinterpret_cast<Impl::ValueType>(ai.load()))
269  {
270  }
271 
272  operator void*() const
273  {
274  return reinterpret_cast<void*>(Impl::Load(&this->m_Object));
275  }
276 
277  void* operator=(void* val)
278  {
279  Impl::Store(&this->m_Object,
280  reinterpret_cast<Impl::ValueType>(val));
281  return val;
282  }
283 
285  {
286  this->store(ai.load());
287  return *this;
288  }
289 
290  void* load() const
291  {
292  return reinterpret_cast<void*>(Impl::Load(&this->m_Object));
293  }
294 
295  void store(void* val)
296  {
297  Impl::Store(&this->m_Object,
298  reinterpret_cast<Impl::ValueType>(val));
299  }
300 
301 private:
302  Impl::AtomicType m_Object;
303 };
304 
305 #else // C++11 ITK_COMPILER_CXX_ATOMIC == 1
306 
307 template <typename T>
308 class AtomicInt
309 {
310 private:
312  typedef typename Impl::ValueType ValueType;
314 
315 public:
316  AtomicInt() : m_Object(0)
317  {
318  }
319 
320  AtomicInt(T val)
321  : m_Object(static_cast<ValueType>(val))
322  {
323  }
324 
325  AtomicInt(const AtomicInt<T> &ai)
326  : m_Object(static_cast<ValueType>(ai.load()))
327  {
328  }
329 
330  T operator++()
331  {
332  return static_cast<T>(++m_Object);
333  }
334 
335  T operator++(int)
336  {
337  return static_cast<T>(m_Object++);
338  }
339 
340  T operator--()
341  {
342  return static_cast<T>(--m_Object);
343  }
344 
345  T operator--(int)
346  {
347  return static_cast<T>(m_Object--);
348  }
349 
350  T operator+=(T val)
351  {
352  return static_cast<T>(m_Object+=static_cast<ValueType>(val));
353  }
354 
355  T operator-=(T val)
356  {
357  return static_cast<T>(m_Object-=static_cast<ValueType>(val));
358  }
359 
360  operator T() const
361  {
362  return static_cast<T>(m_Object.load());
363  }
364 
365  T operator=(T val)
366  {
367  m_Object.store(static_cast<ValueType>(val));
368  return val;
369  }
370 
371  AtomicInt<T>& operator=(const AtomicInt<T> &ai)
372  {
373  this->store(ai.load());
374  return *this;
375  }
376 
377  T load() const
378  {
379  return static_cast<T>(m_Object.load());
380  }
381 
382  void store(T val)
383  {
384  m_Object.store(static_cast<ValueType>(val));
385  }
386 
387  private:
388  std::atomic<typename Detail::AtomicOps<sizeof(T)>::ValueType > m_Object;
389 };
390 
391 
392 template <typename T>
393 class AtomicInt<T*>
394 {
395 private:
396  typedef Detail::AtomicOps<sizeof(T*)> Impl;
397  typedef typename Impl::ValueType ValueType;
398 
399 public:
400  AtomicInt() : m_Object(0)
401  {
402  }
403 
404  AtomicInt(T* val)
405  : m_Object(reinterpret_cast<ValueType>(val))
406  {
407  }
408 
409  AtomicInt(const AtomicInt<T*> &ai)
410  : m_Object(reinterpret_cast<ValueType>(ai.load()))
411  {
412  }
413 
414  T* operator++()
415  {
416  return reinterpret_cast<T*>(m_Object.fetch_add(sizeof(T))+sizeof(T));
417  }
418 
419  T* operator++(int)
420  {
421  return reinterpret_cast<T*>(m_Object.fetch_add(sizeof(T)));
422  }
423 
424  T* operator--()
425  {
426  return reinterpret_cast<T*>(m_Object.fetch_sub(sizeof(T))-sizeof(T));
427  }
428 
429  T* operator--(int)
430  {
431  return reinterpret_cast<T*>(m_Object.fetch_sub(sizeof(T)));
432  }
433 
434  T* operator+=(std::ptrdiff_t val)
435  {
436  return reinterpret_cast<T*>(m_Object += val * sizeof(T));
437  }
438 
439  T* operator-=(std::ptrdiff_t val)
440  {
441  return reinterpret_cast<T*>(m_Object -= val * sizeof(T));
442  }
443 
444  operator T*() const
445  {
446  return reinterpret_cast<T*>(m_Object.load());
447  }
448 
449  T* operator=(T* val)
450  {
451  m_Object.store(reinterpret_cast<ValueType>(val));
452  return val;
453  }
454 
455  AtomicInt<T*>& operator=(const AtomicInt<T*> &ai)
456  {
457  this->store(ai.load());
458  return *this;
459  }
460 
461  T* load() const
462  {
463  return reinterpret_cast<T*>(m_Object.load());
464  }
465 
466  void store(T* val)
467  {
468  m_Object.store(reinterpret_cast<ValueType>(val));
469  }
470 
471  private:
472  std::atomic<typename Detail::AtomicOps<sizeof(T*)>::ValueType > m_Object;
473 };
474 
475 
476 template <> class AtomicInt<void*>
477 {
478 private:
479  typedef Detail::AtomicOps<sizeof(void*)> Impl;
480  typedef Impl::ValueType ValueType;
481 
482 public:
483  AtomicInt() : m_Object(0)
484  {
485  }
486 
487  AtomicInt(void* val)
488  : m_Object(reinterpret_cast<ValueType>(val))
489  {
490  }
491 
492  AtomicInt(const AtomicInt<void*> &ai)
493  : m_Object(reinterpret_cast<ValueType>(ai.load()))
494  {
495  }
496 
497  operator void*() const
498  {
499  return reinterpret_cast<void*>(m_Object.load());
500  }
501 
502  void* operator=(void* val)
503  {
504  m_Object.store(reinterpret_cast<ValueType>(val));
505  return val;
506  }
507 
508  AtomicInt<void*>& operator=(const AtomicInt<void*> &ai)
509  {
510  this->store(ai.load());
511  return *this;
512  }
513 
514  void* load() const
515  {
516  return reinterpret_cast<void*>(m_Object.load());
517  }
518 
519  void store(void* val)
520  {
521  m_Object.store(reinterpret_cast<ValueType>(val));
522  }
523 
524  private:
525  std::atomic<typename Detail::AtomicOps<sizeof(void*)>::ValueType > m_Object;
526 };
527 
528 #endif
529 
530 } // end namespace itk
531 
532 #endif
T load() const
Definition: itkAtomicInt.h:148
T * operator-=(std::ptrdiff_t val)
Definition: itkAtomicInt.h:212
Detail::AtomicOps< sizeof(void *)> Impl
Definition: itkAtomicInt.h:255
T operator=(T val)
Definition: itkAtomicInt.h:136
Provides support for atomic integers.
Definition: itkAtomicInt.h:78
void store(void *val)
Definition: itkAtomicInt.h:295
T operator+=(T val)
Definition: itkAtomicInt.h:119
AtomicInt< void * > & operator=(const AtomicInt< void * > &ai)
Definition: itkAtomicInt.h:284
Impl::AtomicType m_Object
Definition: itkAtomicInt.h:159
AtomicInt(T val)
Definition: itkAtomicInt.h:89
void * operator=(void *val)
Definition: itkAtomicInt.h:277
Detail::AtomicOps< sizeof(T *)> Impl
Definition: itkAtomicInt.h:167
Detail::AtomicOps< sizeof(T)> Impl
Definition: itkAtomicInt.h:81
T operator-=(T val)
Definition: itkAtomicInt.h:125
AtomicInt(const AtomicInt< T * > &ai)
Definition: itkAtomicInt.h:179
AtomicInt< T > & operator=(const AtomicInt< T > &ai)
Definition: itkAtomicInt.h:142
AtomicInt(const AtomicInt< void * > &ai)
Definition: itkAtomicInt.h:267
AtomicInt(const AtomicInt< T > &ai)
Definition: itkAtomicInt.h:94
Impl::AtomicType m_Object
Definition: itkAtomicInt.h:302
void store(T val)
Definition: itkAtomicInt.h:153
AtomicInt< T * > & operator=(const AtomicInt< T * > &ai)
Definition: itkAtomicInt.h:230
#define itkConceptMacro(name, concept)
void * load() const
Definition: itkAtomicInt.h:290
T * operator+=(std::ptrdiff_t val)
Definition: itkAtomicInt.h:206
Impl::AtomicType m_Object
Definition: itkAtomicInt.h:248