libcopp  1.3.0
atomic_int_type.h
Go to the documentation of this file.
1 
18 #ifndef LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_H
19 #define LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_H
20 
21 #pragma once
22 
23 #include "std/explicit_declare.h"
24 
25 #if __cplusplus >= 201103L
26 #include <cstdint>
27 #elif defined(_MSC_VER) && defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
28 #include <cstdint>
29 #else
30 
31 // patch for old gcc
32 #ifndef __STDC_LIMIT_MACROS
33 #define _UNDEF__STDC_LIMIT_MACROS
34 #define __STDC_LIMIT_MACROS
35 #endif
36 #ifndef __STDC_CONSTANT_MACROS
37 #define _UNDEF__STDC_CONSTANT_MACROS
38 #define __STDC_CONSTANT_MACROS
39 #endif
40 #include <limits.h>
41 #include <stdint.h>
42 #ifdef _UNDEF__STDC_LIMIT_MACROS
43 #undef __STDC_LIMIT_MACROS
44 #undef _UNDEF__STDC_LIMIT_MACROS
45 #endif
46 #ifdef _UNDEF__STDC_CONSTANT_MACROS
47 #undef __STDC_CONSTANT_MACROS
48 #undef _UNDEF__STDC_CONSTANT_MACROS
49 #endif
50 
51 #endif
52 
53 #if defined(__cplusplus) && __cplusplus >= 201103L
54 
55 #include <atomic>
56 #define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD
57 
58 #elif defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 1)) && __cplusplus >= 201103L
59 
60 #include <atomic>
61 #define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD
62 
63 #elif defined(_MSC_VER) && (_MSC_VER >= 1900) // 1900 means VC 14.0,2015, there some problem with std::atomic implement in old MSVC
64 
65 #include <atomic>
66 #define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD
67 
68 // There is a BUG in gcc 4.6, which will cause 'undefined reference to `std::atomic_thread_fence(std::memory_order)'
69 // In gcc 4.7 and upper, we can use -std=c++11 or upper
70 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51038
71 // #elif defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || __GNUC__ > 4) && defined(__GXX_EXPERIMENTAL_CXX0X__)
72 //
73 // #include <atomic>
74 // #define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD
75 
76 #endif
77 
78 #if !defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD) && defined(_MSC_VER)
80 #endif
81 
82 #include <cstddef>
83 
86 
87 namespace libcopp {
88  namespace util {
89  namespace lock {
90 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD
98 
99 #define LIBCOPP_UTIL_LOCK_ATOMIC_THREAD_FENCE(order) ::std::atomic_thread_fence(order)
100 #define LIBCOPP_UTIL_LOCK_ATOMIC_SIGNAL_FENCE(order) ::std::atomic_signal_fence(order)
101 
108  template <typename Ty = int>
109  class LIBCOPP_COPP_API_HEAD_ONLY atomic_int_type {
110  public:
111  typedef Ty value_type;
112 
113  private:
114  ::std::atomic<value_type> data_;
115  atomic_int_type(const atomic_int_type &) UTIL_CONFIG_DELETED_FUNCTION;
116 #ifndef _MSC_VER
117  atomic_int_type &operator=(const atomic_int_type &) UTIL_CONFIG_DELETED_FUNCTION;
118  atomic_int_type &operator=(const atomic_int_type &) volatile UTIL_CONFIG_DELETED_FUNCTION;
119 #endif
120 
121 
122  public:
123  atomic_int_type() UTIL_CONFIG_NOEXCEPT : data_() {}
124  atomic_int_type(value_type desired) UTIL_CONFIG_NOEXCEPT : data_(desired) {}
125 
126  inline void
127  store(value_type desired,
129  data_.store(desired, order);
130  }
131  inline void store(value_type desired, ::libcopp::util::lock::memory_order order =
132  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
133  data_.store(desired, order);
134  }
135 
136  inline value_type
137  load(::libcopp::util::lock::memory_order order = ::libcopp::util::lock::memory_order_seq_cst) const UTIL_CONFIG_NOEXCEPT {
138  return data_.load(order);
139  }
140  inline value_type load(::libcopp::util::lock::memory_order order = ::libcopp::util::lock::memory_order_seq_cst) const
141  volatile UTIL_CONFIG_NOEXCEPT {
142  return data_.load(order);
143  }
144 
145  inline operator value_type() const UTIL_CONFIG_NOEXCEPT { return load(); }
146  inline operator value_type() const volatile UTIL_CONFIG_NOEXCEPT { return load(); }
147 
148  inline value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT {
149  store(desired);
150  return desired;
151  }
152  inline value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT {
153  store(desired);
154  return desired;
155  }
156 
157  inline value_type operator++() UTIL_CONFIG_NOEXCEPT { return ++data_; }
158  inline value_type operator++() volatile UTIL_CONFIG_NOEXCEPT { return ++data_; }
159  inline value_type operator++(int) UTIL_CONFIG_NOEXCEPT { return data_++; }
160  inline value_type operator++(int) volatile UTIL_CONFIG_NOEXCEPT { return data_++; }
161  inline value_type operator--() UTIL_CONFIG_NOEXCEPT { return --data_; }
162  inline value_type operator--() volatile UTIL_CONFIG_NOEXCEPT { return --data_; }
163  inline value_type operator--(int) UTIL_CONFIG_NOEXCEPT { return data_--; }
164  inline value_type operator--(int) volatile UTIL_CONFIG_NOEXCEPT { return data_--; }
165 
166  inline value_type
167  exchange(value_type desired,
169  return data_.exchange(desired, order);
170  }
171  inline value_type exchange(
172  value_type desired,
173  ::libcopp::util::lock::memory_order order = ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
174  return data_.exchange(desired, order);
175  }
176 
177  inline bool compare_exchange_weak(value_type &expected, value_type desired, ::libcopp::util::lock::memory_order success,
178  ::libcopp::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT {
179  return data_.compare_exchange_weak(expected, desired, success, failure);
180  }
181  inline bool compare_exchange_weak(value_type &expected, value_type desired, ::libcopp::util::lock::memory_order success,
182  ::libcopp::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT {
183  return data_.compare_exchange_weak(expected, desired, success, failure);
184  }
185 
186  inline bool compare_exchange_weak(value_type &expected, value_type desired,
188  UTIL_CONFIG_NOEXCEPT {
189  return data_.compare_exchange_weak(expected, desired, order);
190  }
191  inline bool compare_exchange_weak(
192  value_type &expected, value_type desired,
193  ::libcopp::util::lock::memory_order order = ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
194  return data_.compare_exchange_weak(expected, desired, order);
195  }
196 
197  inline bool compare_exchange_strong(value_type &expected, value_type desired, ::libcopp::util::lock::memory_order success,
198  ::libcopp::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT {
199  return data_.compare_exchange_strong(expected, desired, success, failure);
200  }
201  inline bool compare_exchange_strong(value_type &expected, value_type desired, ::libcopp::util::lock::memory_order success,
202  ::libcopp::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT {
203  return data_.compare_exchange_strong(expected, desired, success, failure);
204  }
205 
206  inline bool compare_exchange_strong(value_type &expected, value_type desired,
208  UTIL_CONFIG_NOEXCEPT {
209  return data_.compare_exchange_strong(expected, desired, order);
210  }
211  inline bool compare_exchange_strong(
212  value_type &expected, value_type desired,
213  ::libcopp::util::lock::memory_order order = ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
214  return data_.compare_exchange_strong(expected, desired, order);
215  }
216 
217  inline value_type
218  fetch_add(value_type arg,
220  return data_.fetch_add(arg, order);
221  }
222  inline value_type fetch_add(value_type arg, ::libcopp::util::lock::memory_order order =
223  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
224  return data_.fetch_add(arg, order);
225  }
226 
227  inline value_type
228  fetch_sub(value_type arg,
230  return data_.fetch_sub(arg, order);
231  }
232  inline value_type fetch_sub(value_type arg, ::libcopp::util::lock::memory_order order =
233  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
234  return data_.fetch_sub(arg, order);
235  }
236 
237  inline value_type
238  fetch_and(value_type arg,
240  return data_.fetch_and(arg, order);
241  }
242  inline value_type fetch_and(value_type arg, ::libcopp::util::lock::memory_order order =
243  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
244  return data_.fetch_and(arg, order);
245  }
246 
247  inline value_type
248  fetch_or(value_type arg,
250  return data_.fetch_or(arg, order);
251  }
252  inline value_type fetch_or(value_type arg, ::libcopp::util::lock::memory_order order =
253  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
254  return data_.fetch_or(arg, order);
255  }
256 
257  inline value_type
258  fetch_xor(value_type arg,
260  return data_.fetch_xor(arg, order);
261  }
262  inline value_type fetch_xor(value_type arg, ::libcopp::util::lock::memory_order order =
263  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
264  return data_.fetch_xor(arg, order);
265  }
266  };
267 #else
268 
269 #if defined(__clang__)
270 
271 #if !defined(__GCC_ATOMIC_INT_LOCK_FREE) && (!defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1))
272 #error clang version is too old
273 #endif
274 
275 #if defined(__GCC_ATOMIC_INT_LOCK_FREE)
276 // @see https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
277 #define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC 1
278 #else
279 // @see https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html
280 #define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC 1
281 #endif
282 
283 #elif defined(_MSC_VER)
284 
285 #define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC 1
286 
287 
288 #elif defined(__GNUC__) || defined(__INTEL_COMPILER)
289 
290 #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1))
291 #error gcc version must be greater or equal than 4.1
292 #endif
293 
294 #if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1100
295 #error intel compiler version must be greater or equal than 11.0
296 #endif
297 
298 #if defined(__GCC_ATOMIC_INT_LOCK_FREE)
299 // @see https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
300 #define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC 1
301 #else
302 // @see https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html
303 #define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC 1
304 #endif
305 
306 #else
307 
308 #error currently only gcc, msvc, intel compiler & llvm-clang are supported
309 
310 #endif
311 
312 #if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
313  enum memory_order {
314  memory_order_relaxed = __ATOMIC_RELAXED,
315  memory_order_consume = __ATOMIC_CONSUME,
316  memory_order_acquire = __ATOMIC_ACQUIRE,
317  memory_order_release = __ATOMIC_RELEASE,
318  memory_order_acq_rel = __ATOMIC_ACQ_REL,
319  memory_order_seq_cst = __ATOMIC_SEQ_CST
320  };
321 
322 #define LIBCOPP_UTIL_LOCK_ATOMIC_THREAD_FENCE(order) __atomic_thread_fence(order)
323 #define LIBCOPP_UTIL_LOCK_ATOMIC_SIGNAL_FENCE(order) __atomic_signal_fence(order)
324 
325 #elif !defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC) // old gcc and old msvc use this
333  };
334 #endif
335 
336 #ifndef LIBCOPP_UTIL_LOCK_ATOMIC_THREAD_FENCE
337 #define LIBCOPP_UTIL_LOCK_ATOMIC_THREAD_FENCE(x)
338 #endif
339 
340 #ifndef LIBCOPP_UTIL_LOCK_ATOMIC_SIGNAL_FENCE
341 #define LIBCOPP_UTIL_LOCK_ATOMIC_SIGNAL_FENCE(x)
342 #endif
343 
344  template <typename Ty = int>
345  class LIBCOPP_COPP_API_HEAD_ONLY atomic_int_type {
346  public:
347  typedef Ty value_type;
348 
349  private:
350 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
351  // char has no cas api in msvc
353 #else
354  volatile value_type data_;
355 #endif
356  atomic_int_type(const atomic_int_type &) UTIL_CONFIG_DELETED_FUNCTION;
357 #ifndef _MSC_VER
358  atomic_int_type &operator=(const atomic_int_type &) UTIL_CONFIG_DELETED_FUNCTION;
359  atomic_int_type &operator=(const atomic_int_type &) volatile UTIL_CONFIG_DELETED_FUNCTION;
360 #endif
361 
362  public:
363  atomic_int_type() UTIL_CONFIG_NOEXCEPT : data_() {
364 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
365 #if __cplusplus >= 201703L
366  if
367  constexpr(sizeof(data_) != sizeof(value_type)) {
368 #else
369  if (sizeof(data_) != sizeof(value_type)) {
370 #endif
371  data_ = static_cast<value_type>(data_);
372  }
373 #endif
374  }
375 
376  atomic_int_type(value_type desired) UTIL_CONFIG_NOEXCEPT : data_(desired) {}
377 
378  inline void store(value_type desired, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
379  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
380 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
382  typedef typename int_opr_t::opr_t opr_t;
383  int_opr_t::exchange(&data_, static_cast<opr_t>(desired), order);
384 
385 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
386  __atomic_store_n(&data_, desired, order);
387 #else
388  __sync_lock_test_and_set(&data_, desired);
389 #endif
390  }
391 
392  inline void store(value_type desired, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
393  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
394 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
396  typedef typename int_opr_t::opr_t opr_t;
397  int_opr_t::exchange(&data_, static_cast<opr_t>(desired), order);
398 
399 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
400  __atomic_store_n(&data_, desired, order);
401 #else
402  __sync_lock_test_and_set(&data_, desired);
403 #endif
404  }
405 
407  ::libcopp::util::lock::memory_order_seq_cst) const UTIL_CONFIG_NOEXCEPT {
408 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
410  typedef typename int_opr_t::opr_t opr_t;
411  return static_cast<value_type>(int_opr_t:: or (const_cast<opr_t *>(&data_), static_cast<opr_t>(0), order));
412 
413 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
414  return __atomic_load_n(&data_, order);
415 #else
416  __sync_synchronize();
417  return data_;
418 #endif
419  }
420 
421  inline value_type
423  volatile UTIL_CONFIG_NOEXCEPT {
424 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
426  typedef typename int_opr_t::opr_t opr_t;
427  return static_cast<value_type>(int_opr_t:: or (const_cast<opr_t *>(&data_), static_cast<opr_t>(0), order));
428 
429 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
430  return __atomic_load_n(&data_, order);
431 #else
432  __sync_synchronize();
433  return data_;
434 #endif
435  }
436 
437  inline operator value_type() const UTIL_CONFIG_NOEXCEPT { return load(); }
438  inline operator value_type() const volatile UTIL_CONFIG_NOEXCEPT { return load(); }
439 
440  inline value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT {
441  store(desired);
442  return desired;
443  }
444  inline value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT {
445  store(desired);
446  return desired;
447  }
448 
449  inline value_type operator++() UTIL_CONFIG_NOEXCEPT {
450 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
452  typedef typename int_opr_t::opr_t opr_t;
453  return static_cast<value_type>(int_opr_t::inc(&data_, ::libcopp::util::lock::memory_order_seq_cst));
454 #else
455  return fetch_add(1) + 1;
456 #endif
457  }
458  inline value_type operator++() volatile UTIL_CONFIG_NOEXCEPT {
459 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
461  typedef typename int_opr_t::opr_t opr_t;
462  return static_cast<value_type>(int_opr_t::inc(&data_, ::libcopp::util::lock::memory_order_seq_cst));
463 #else
464  return fetch_add(1) + 1;
465 #endif
466  }
467  inline value_type operator++(int) UTIL_CONFIG_NOEXCEPT {
468 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
470  typedef typename int_opr_t::opr_t opr_t;
471  return static_cast<value_type>(int_opr_t::inc(&data_, ::libcopp::util::lock::memory_order_seq_cst) - 1);
472 #else
473  return fetch_add(1);
474 #endif
475  }
476  inline value_type operator++(int) volatile UTIL_CONFIG_NOEXCEPT {
477 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
479  typedef typename int_opr_t::opr_t opr_t;
480  return static_cast<value_type>(int_opr_t::inc(&data_, ::libcopp::util::lock::memory_order_seq_cst) - 1);
481 #else
482  return fetch_add(1);
483 #endif
484  }
485  inline value_type operator--() UTIL_CONFIG_NOEXCEPT {
486 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
488  typedef typename int_opr_t::opr_t opr_t;
489  return static_cast<value_type>(int_opr_t::dec(&data_, ::libcopp::util::lock::memory_order_seq_cst));
490 #else
491  return fetch_sub(1) - 1;
492 #endif
493  }
494  inline value_type operator--() volatile UTIL_CONFIG_NOEXCEPT {
495 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
497  typedef typename int_opr_t::opr_t opr_t;
498  return static_cast<value_type>(int_opr_t::dec(&data_, ::libcopp::util::lock::memory_order_seq_cst));
499 #else
500  return fetch_sub(1) - 1;
501 #endif
502  }
503  inline value_type operator--(int) UTIL_CONFIG_NOEXCEPT {
504 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
506  typedef typename int_opr_t::opr_t opr_t;
507  return static_cast<value_type>(int_opr_t::dec(&data_, ::libcopp::util::lock::memory_order_seq_cst) + 1);
508 #else
509  return fetch_sub(1);
510 #endif
511  }
512  inline value_type operator--(int) volatile UTIL_CONFIG_NOEXCEPT {
513 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
515  typedef typename int_opr_t::opr_t opr_t;
516  return static_cast<value_type>(int_opr_t::dec(&data_, ::libcopp::util::lock::memory_order_seq_cst) + 1);
517 #else
518  return fetch_sub(1);
519 #endif
520  }
521 
522  inline value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
523  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
524 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
526  typedef typename int_opr_t::opr_t opr_t;
527  return static_cast<value_type>(
528  static_cast<value_type>(int_opr_t::exchange(&data_, static_cast<opr_t>(desired), order)));
529 
530 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
531  return __atomic_exchange_n(&data_, desired, order);
532 #else
533  value_type old_value = data_;
534  while (!__sync_bool_compare_and_swap(&data_, old_value, desired)) {
535  old_value = data_;
536  }
537  return old_value;
538 #endif
539  }
540 
541  inline value_type exchange(value_type desired,
543  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
544 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
546  typedef typename int_opr_t::opr_t opr_t;
547  return static_cast<value_type>(
548  static_cast<value_type>(int_opr_t::exchange(&data_, static_cast<opr_t>(desired), order)));
549 
550 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
551  return __atomic_exchange_n(&data_, desired, order);
552 #else
553  value_type old_value = data_;
554  while (!__sync_bool_compare_and_swap(&data_, old_value, desired)) {
555  old_value = data_;
556  }
557  return old_value;
558 #endif
559  }
560 
561  inline bool compare_exchange_weak(value_type &expected, value_type desired,
563  EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT {
564 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
566  typedef typename int_opr_t::opr_t opr_t;
567  if (expected == static_cast<value_type>(
568  int_opr_t::cas(&data_, static_cast<opr_t>(desired), static_cast<opr_t>(expected), success))) {
569  return true;
570  } else {
571  expected = static_cast<value_type>(data_);
572  return false;
573  }
574 
575 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
576  return __atomic_compare_exchange_n(&data_, &expected, desired, true, success, failure);
577 #else
578  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
579  return true;
580  } else {
581  expected = data_;
582  return false;
583  }
584 #endif
585  }
586 
587  inline bool
588  compare_exchange_weak(value_type &expected, value_type desired,
590  EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT {
591 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
593  typedef typename int_opr_t::opr_t opr_t;
594  if (expected == static_cast<value_type>(
595  int_opr_t::cas(&data_, static_cast<opr_t>(desired), static_cast<opr_t>(expected), success))) {
596  return true;
597  } else {
598  expected = static_cast<value_type>(data_);
599  return false;
600  }
601 
602 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
603  return __atomic_compare_exchange_n(&data_, &expected, desired, true, success, failure);
604 #else
605  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
606  return true;
607  } else {
608  expected = data_;
609  return false;
610  }
611 #endif
612  }
613 
614  inline bool compare_exchange_weak(value_type &expected, value_type desired,
616  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
617 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
619  typedef typename int_opr_t::opr_t opr_t;
620  if (expected ==
621  static_cast<value_type>(int_opr_t::cas(&data_, static_cast<opr_t>(desired), static_cast<opr_t>(expected), order))) {
622  return true;
623  } else {
624  expected = static_cast<value_type>(data_);
625  return false;
626  }
627 
628 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
629  return __atomic_compare_exchange_n(&data_, &expected, desired, true, order, order);
630 #else
631  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
632  return true;
633  } else {
634  expected = data_;
635  return false;
636  }
637 #endif
638  }
639 
640  inline bool compare_exchange_weak(value_type &expected, value_type desired,
642  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
643 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
645  typedef typename int_opr_t::opr_t opr_t;
646  if (expected ==
647  static_cast<value_type>(int_opr_t::cas(&data_, static_cast<opr_t>(desired), static_cast<opr_t>(expected), order))) {
648  return true;
649  } else {
650  expected = data_;
651  return false;
652  }
653 
654 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
655  return __atomic_compare_exchange_n(&data_, &expected, desired, true, order, order);
656 #else
657  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
658  return true;
659  } else {
660  expected = data_;
661  return false;
662  }
663 #endif
664  }
665 
666  inline bool compare_exchange_strong(value_type &expected, value_type desired,
668  EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT {
669 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
671  typedef typename int_opr_t::opr_t opr_t;
672  if (expected == static_cast<value_type>(
673  int_opr_t::cas(&data_, static_cast<opr_t>(desired), static_cast<opr_t>(expected), success))) {
674  return true;
675  } else {
676  expected = data_;
677  return false;
678  }
679 
680 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
681  return __atomic_compare_exchange_n(&data_, &expected, desired, false, success, failure);
682 #else
683  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
684  return true;
685  } else {
686  expected = data_;
687  return false;
688  }
689 #endif
690  }
691 
692  inline bool
693  compare_exchange_strong(value_type &expected, value_type desired,
695  EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT {
696 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
698  typedef typename int_opr_t::opr_t opr_t;
699  if (expected == static_cast<value_type>(
700  int_opr_t::cas(&data_, static_cast<opr_t>(desired), static_cast<opr_t>(expected), success))) {
701  return true;
702  } else {
703  expected = data_;
704  return false;
705  }
706 
707 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
708  return __atomic_compare_exchange_n(&data_, &expected, desired, false, success, failure);
709 #else
710  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
711  return true;
712  } else {
713  expected = data_;
714  return false;
715  }
716 #endif
717  }
718 
719  inline bool compare_exchange_strong(value_type &expected, value_type desired,
721  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
722 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
724  typedef typename int_opr_t::opr_t opr_t;
725  if (expected ==
726  static_cast<value_type>(int_opr_t::cas(&data_, static_cast<opr_t>(desired), static_cast<opr_t>(expected), order))) {
727  return true;
728  } else {
729  expected = static_cast<value_type>(data_);
730  return false;
731  }
732 
733 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
734  return __atomic_compare_exchange_n(&data_, &expected, desired, false, order, order);
735 #else
736  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
737  return true;
738  } else {
739  expected = data_;
740  return false;
741  }
742 #endif
743  }
744 
745  inline bool compare_exchange_strong(value_type &expected, value_type desired,
747  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
748 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
750  typedef typename int_opr_t::opr_t opr_t;
751  if (expected ==
752  static_cast<value_type>(int_opr_t::cas(&data_, static_cast<opr_t>(desired), static_cast<opr_t>(expected), order))) {
753  return true;
754  } else {
755  expected = static_cast<value_type>(data_);
756  return false;
757  }
758 
759 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
760  return __atomic_compare_exchange_n(&data_, &expected, desired, false, order, order);
761 #else
762  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
763  return true;
764  } else {
765  expected = data_;
766  return false;
767  }
768 #endif
769  }
770 
771  inline value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
772  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
773 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
775  typedef typename int_opr_t::opr_t opr_t;
776  return static_cast<value_type>(int_opr_t::add(&data_, static_cast<opr_t>(arg), order)) - arg;
777 
778 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
779  return __atomic_fetch_add(&data_, arg, order);
780 #else
781  return __sync_fetch_and_add(&data_, arg);
782 #endif
783  }
784  inline value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
785  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
786 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
788  typedef typename int_opr_t::opr_t opr_t;
789  return static_cast<value_type>(int_opr_t::add(&data_, static_cast<opr_t>(arg), order)) - arg;
790 
791 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
792  return __atomic_fetch_add(&data_, arg, order);
793 #else
794  return __sync_fetch_and_add(&data_, arg);
795 #endif
796  }
797 
798  inline value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
799  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
800 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
802  typedef typename int_opr_t::opr_t opr_t;
803  return static_cast<value_type>(int_opr_t::sub(&data_, static_cast<opr_t>(arg), order)) + arg;
804 
805 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
806  return __atomic_fetch_sub(&data_, arg, order);
807 #else
808  return __sync_fetch_and_sub(&data_, arg);
809 #endif
810  }
811  inline value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
812  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
813 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
815  typedef typename int_opr_t::opr_t opr_t;
816  return static_cast<value_type>(int_opr_t::sub(&data_, static_cast<opr_t>(arg), order)) + arg;
817 
818 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
819  return __atomic_fetch_sub(&data_, arg, order);
820 #else
821  return __sync_fetch_and_sub(&data_, arg);
822 #endif
823  }
824 
825  inline value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
826  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
827 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
829  typedef typename int_opr_t::opr_t opr_t;
830  return static_cast<value_type>(int_opr_t::and(&data_, static_cast<opr_t>(arg), order));
831 
832 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
833  return __atomic_fetch_and(&data_, arg, order);
834 #else
835  return __sync_fetch_and_and(&data_, arg);
836 #endif
837  }
838  inline value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
839  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
840 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
842  typedef typename int_opr_t::opr_t opr_t;
843  return static_cast<value_type>(int_opr_t::and(&data_, static_cast<opr_t>(arg), order));
844 
845 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
846  return __atomic_fetch_and(&data_, arg, order);
847 #else
848  return __sync_fetch_and_and(&data_, arg);
849 #endif
850  }
851 
852  inline value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
853  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
854 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
856  typedef typename int_opr_t::opr_t opr_t;
857  return static_cast<value_type>(int_opr_t:: or (&data_, static_cast<opr_t>(arg), order));
858 
859 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
860  return __atomic_fetch_or(&data_, arg, order);
861 #else
862  return __sync_fetch_and_or(&data_, arg);
863 #endif
864  }
865  inline value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
866  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
867 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
869  typedef typename int_opr_t::opr_t opr_t;
870  return static_cast<value_type>(int_opr_t:: or (&data_, static_cast<opr_t>(arg), order));
871 
872 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
873  return __atomic_fetch_or(&data_, arg, order);
874 #else
875  return __sync_fetch_and_or(&data_, arg);
876 #endif
877  }
878 
879  inline value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
880  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
881 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
883  typedef typename int_opr_t::opr_t opr_t;
884  return static_cast<value_type>(int_opr_t:: xor (&data_, static_cast<opr_t>(arg), order));
885 
886 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
887  return __atomic_fetch_xor(&data_, arg, order);
888 #else
889  return __sync_fetch_and_xor(&data_, arg);
890 #endif
891  }
892  inline value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
893  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
894 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC
896  typedef typename int_opr_t::opr_t opr_t;
897  return static_cast<value_type>(int_opr_t:: xor (&data_, static_cast<opr_t>(arg), order));
898 
899 #elif defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
900  return __atomic_fetch_xor(&data_, arg, order);
901 #else
902  return __sync_fetch_and_xor(&data_, arg);
903 #endif
904  }
905  };
906 
907 #endif
908 
909  // used for unsafe (not multi-thread safe)
910  template <typename Ty = int>
912  typedef Ty value_type;
913  };
914 
915  template <typename Ty>
916  class LIBCOPP_COPP_API_HEAD_ONLY atomic_int_type<unsafe_int_type<Ty> > {
917  public:
919 
920  private:
921  value_type data_;
922  atomic_int_type(const atomic_int_type &) UTIL_CONFIG_DELETED_FUNCTION;
923 #ifndef _MSC_VER
924  atomic_int_type &operator=(const atomic_int_type &) UTIL_CONFIG_DELETED_FUNCTION;
925  atomic_int_type &operator=(const atomic_int_type &) volatile UTIL_CONFIG_DELETED_FUNCTION;
926 #endif
927 
928  public:
929  atomic_int_type() : data_() {}
930  atomic_int_type(value_type desired) : data_(desired) {}
931 
932  inline void store(value_type desired, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
933  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
934  data_ = desired;
935  }
936  inline void store(value_type desired, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
937  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
938  data_ = desired;
939  }
940 
942  ::libcopp::util::lock::memory_order_seq_cst) const UTIL_CONFIG_NOEXCEPT {
943  return data_;
944  }
945  inline value_type
947  volatile UTIL_CONFIG_NOEXCEPT {
948  return data_;
949  }
950 
951  inline operator value_type() const UTIL_CONFIG_NOEXCEPT { return load(); }
952  inline operator value_type() const volatile UTIL_CONFIG_NOEXCEPT { return load(); }
953 
954  inline value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT {
955  store(desired);
956  return desired;
957  }
958  inline value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT {
959  store(desired);
960  return desired;
961  }
962 
963  inline value_type operator++() UTIL_CONFIG_NOEXCEPT { return ++data_; }
964  inline value_type operator++() volatile UTIL_CONFIG_NOEXCEPT { return ++data_; }
965  inline value_type operator++(int) UTIL_CONFIG_NOEXCEPT { return data_++; }
966  inline value_type operator++(int) volatile UTIL_CONFIG_NOEXCEPT { return data_++; }
967  inline value_type operator--() UTIL_CONFIG_NOEXCEPT { return --data_; }
968  inline value_type operator--() volatile UTIL_CONFIG_NOEXCEPT { return --data_; }
969  inline value_type operator--(int) UTIL_CONFIG_NOEXCEPT { return data_--; }
970  inline value_type operator--(int) volatile UTIL_CONFIG_NOEXCEPT { return data_--; }
971 
972  inline value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
973  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
974  value_type ret = data_;
975  data_ = desired;
976  return ret;
977  }
978  inline value_type exchange(value_type desired,
980  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
981  value_type ret = data_;
982  data_ = desired;
983  return ret;
984  }
985 
986  private:
987  inline bool cas(value_type &expected, value_type desired) UTIL_CONFIG_NOEXCEPT {
988  if (likely(data_ == expected)) {
989  data_ = desired;
990  return true;
991  } else {
992  expected = data_;
993  return false;
994  }
995  }
996 
997  public:
998  inline bool compare_exchange_weak(value_type &expected, value_type desired,
1000  EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT {
1001  return cas(expected, desired);
1002  }
1003  inline bool
1004  compare_exchange_weak(value_type &expected, value_type desired,
1006  EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT {
1007  return cas(expected, desired);
1008  }
1009 
1010  inline bool compare_exchange_weak(value_type &expected, value_type desired,
1012  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
1013  return cas(expected, desired);
1014  }
1015  inline bool compare_exchange_weak(value_type &expected, value_type desired,
1017  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
1018  return cas(expected, desired);
1019  }
1020 
1021  inline bool compare_exchange_strong(value_type &expected, value_type desired,
1023  EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT {
1024  return cas(expected, desired);
1025  }
1026  inline bool
1027  compare_exchange_strong(value_type &expected, value_type desired,
1029  EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT {
1030  return cas(expected, desired);
1031  }
1032 
1033  inline bool compare_exchange_strong(value_type &expected, value_type desired,
1035  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
1036  return cas(expected, desired);
1037  }
1038  inline bool compare_exchange_strong(value_type &expected, value_type desired,
1040  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
1041  return cas(expected, desired);
1042  }
1043 
1045  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
1046  value_type ret = data_;
1047  data_ += arg;
1048  return ret;
1049  }
1051  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
1052  value_type ret = data_;
1053  data_ += arg;
1054  return ret;
1055  }
1056 
1058  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
1059  value_type ret = data_;
1060  data_ -= arg;
1061  return ret;
1062  }
1064  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
1065  value_type ret = data_;
1066  data_ -= arg;
1067  return ret;
1068  }
1069 
1071  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
1072  value_type ret = data_;
1073  data_ &= arg;
1074  return ret;
1075  }
1077  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
1078  value_type ret = data_;
1079  data_ &= arg;
1080  return ret;
1081  }
1082 
1083  inline value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
1084  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
1085  value_type ret = data_;
1086  data_ |= arg;
1087  return ret;
1088  }
1089  inline value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR ::libcopp::util::lock::memory_order order =
1090  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
1091  value_type ret = data_;
1092  data_ |= arg;
1093  return ret;
1094  }
1095 
1097  ::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT {
1098  value_type ret = data_;
1099  data_ ^= arg;
1100  return ret;
1101  }
1103  ::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT {
1104  value_type ret = data_;
1105  data_ ^= arg;
1106  return ret;
1107  }
1108  };
1109  } // namespace lock
1110  } // namespace util
1111 } // namespace libcopp
1112 
1113 #endif /* _LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_H_ */
value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT
value_type operator--() UTIL_CONFIG_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT
导入继承关系约束 Licensed under the MIT licenses.
#define LIBCOPP_COPP_API_HEAD_ONLY
value_type operator++() UTIL_CONFIG_NOEXCEPT
value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT
atomic_int_type(value_type desired) UTIL_CONFIG_NOEXCEPT
value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
atomic_int_type() UTIL_CONFIG_NOEXCEPT
value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
value_type operator++(int) volatile UTIL_CONFIG_NOEXCEPT
value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
#define likely(x)
value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
value_type operator--() volatile UTIL_CONFIG_NOEXCEPT
value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT
value_type load(EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) const volatile UTIL_CONFIG_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
value_type operator++(int) volatile UTIL_CONFIG_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT
value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT
value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT
value_type operator++(int) UTIL_CONFIG_NOEXCEPT
value_type operator--(int) UTIL_CONFIG_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT
value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT
value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
void store(value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
bool cas(value_type &expected, value_type desired) UTIL_CONFIG_NOEXCEPT
void store(value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT
value_type load(EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) const UTIL_CONFIG_NOEXCEPT
void store(value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type operator++() volatile UTIL_CONFIG_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
value_type load(EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) const volatile UTIL_CONFIG_NOEXCEPT
value_type operator--() volatile UTIL_CONFIG_NOEXCEPT
std::shared_ptr< cli::cmd_option_value > value_type
Definition: cmd_option.h:53
整数类型的原子操作-MSVC统一接口 Licensed under the MIT licenses.
value_type load(EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) const UTIL_CONFIG_NOEXCEPT
value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
value_type operator--(int) volatile UTIL_CONFIG_NOEXCEPT
void store(value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
value_type operator--(int) volatile UTIL_CONFIG_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order order=::libcopp::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR::libcopp::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT
value_type operator++() volatile UTIL_CONFIG_NOEXCEPT