libcopp  2.2.0
atomic_int_type.h
Go to the documentation of this file.
1 
16 #pragma once
17 
18 #include <libcopp/utils/config/libcopp_build_features.h>
19 #include <libcopp/utils/features.h>
21 
22 // clang-format off
23 #include <libcopp/utils/config/stl_include_prefix.h> // NOLINT(build/include_order)
24 // clang-format on
25 // patch for old gcc
26 #ifndef __STDC_LIMIT_MACROS
27 # define _UNDEF__STDC_LIMIT_MACROS
28 # define __STDC_LIMIT_MACROS
29 #endif
30 #ifndef __STDC_CONSTANT_MACROS
31 # define _UNDEF__STDC_CONSTANT_MACROS
32 # define __STDC_CONSTANT_MACROS
33 #endif
34 #include <limits.h>
35 #include <stdint.h>
36 #ifdef _UNDEF__STDC_LIMIT_MACROS
37 # undef __STDC_LIMIT_MACROS
38 # undef _UNDEF__STDC_LIMIT_MACROS
39 #endif
40 #ifdef _UNDEF__STDC_CONSTANT_MACROS
41 # undef __STDC_CONSTANT_MACROS
42 # undef _UNDEF__STDC_CONSTANT_MACROS
43 #endif
44 
45 #if (defined(__cplusplus) && __cplusplus >= 201103L)
46 # include <cstdint>
47 #elif defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
48 # include <cstdint>
49 #endif
50 
51 #if (defined(__cplusplus) && __cplusplus >= 201103L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
52 
53 # include <atomic>
54 # define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD
55 
56 #elif defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 1)) && \
57  __cplusplus >= 201103L
58 
59 # include <atomic>
60 # define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD
61 
62 #elif defined(_MSC_VER) && \
63  (_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) &&
72 // defined(__GXX_EXPERIMENTAL_CXX0X__)
73 //
74 // #include <atomic>
75 // #define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD
76 
77 #endif
78 
79 #include <cstddef>
80 
81 // clang-format off
82 #include <libcopp/utils/config/stl_include_suffix.h> // NOLINT(build/include_order)
83 // clang-format on
84 
85 LIBCOPP_COPP_NAMESPACE_BEGIN
86 namespace util {
87 namespace lock {
88 #ifdef __LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD
96 
97 # define LIBCOPP_UTIL_LOCK_ATOMIC_THREAD_FENCE(order) ::std::atomic_thread_fence(order)
98 # define LIBCOPP_UTIL_LOCK_ATOMIC_SIGNAL_FENCE(order) ::std::atomic_signal_fence(order)
99 
106 template <typename Ty = int>
107 class LIBCOPP_COPP_API_HEAD_ONLY atomic_int_type {
108  public:
109  using value_type = Ty;
110 
111  private:
112  ::std::atomic<value_type> data_;
113  atomic_int_type(const atomic_int_type &) = delete;
114 # ifndef _MSC_VER
115  atomic_int_type &operator=(const atomic_int_type &) = delete;
116  atomic_int_type &operator=(const atomic_int_type &) volatile = delete;
117 # endif
118 
119  public:
120  atomic_int_type() LIBCOPP_MACRO_NOEXCEPT : data_() {}
121  atomic_int_type(value_type desired) LIBCOPP_MACRO_NOEXCEPT : data_(desired) {}
122 
123  inline void store(value_type desired,
126  data_.store(desired, order);
127  }
128  inline void store(value_type desired,
130  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
131  data_.store(desired, order);
132  }
133 
136  return data_.load(order);
137  }
140  volatile LIBCOPP_MACRO_NOEXCEPT {
141  return data_.load(order);
142  }
143 
144  inline operator value_type() const LIBCOPP_MACRO_NOEXCEPT { return load(); }
145  inline operator value_type() const volatile LIBCOPP_MACRO_NOEXCEPT { return load(); }
146 
147  inline value_type operator=(value_type desired) LIBCOPP_MACRO_NOEXCEPT {
148  store(desired);
149  return desired;
150  }
151  inline value_type operator=(value_type desired) volatile LIBCOPP_MACRO_NOEXCEPT {
152  store(desired);
153  return desired;
154  }
155 
156  inline value_type operator++() LIBCOPP_MACRO_NOEXCEPT { return ++data_; }
157  inline value_type operator++() volatile LIBCOPP_MACRO_NOEXCEPT { return ++data_; }
158  inline value_type operator++(int) LIBCOPP_MACRO_NOEXCEPT { return data_++; }
159  inline value_type operator++(int) volatile LIBCOPP_MACRO_NOEXCEPT { return data_++; }
160  inline value_type operator--() LIBCOPP_MACRO_NOEXCEPT { return --data_; }
161  inline value_type operator--() volatile LIBCOPP_MACRO_NOEXCEPT { return --data_; }
162  inline value_type operator--(int) LIBCOPP_MACRO_NOEXCEPT { return data_--; }
163  inline value_type operator--(int) volatile LIBCOPP_MACRO_NOEXCEPT { return data_--; }
164 
165  inline value_type exchange(value_type desired,
168  return data_.exchange(desired, order);
169  }
170  inline value_type exchange(
171  value_type desired,
173  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
174  return data_.exchange(desired, order);
175  }
176 
177  inline bool compare_exchange_weak(
179  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) LIBCOPP_MACRO_NOEXCEPT {
180  return data_.compare_exchange_weak(expected, desired, success, failure);
181  }
182  inline bool compare_exchange_weak(
184  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) volatile LIBCOPP_MACRO_NOEXCEPT {
185  return data_.compare_exchange_weak(expected, desired, success, failure);
186  }
187 
188  inline bool compare_exchange_weak(value_type &expected, value_type desired,
191  LIBCOPP_MACRO_NOEXCEPT {
192  return data_.compare_exchange_weak(expected, desired, order);
193  }
194  inline bool compare_exchange_weak(
195  value_type &expected, value_type desired,
197  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
198  return data_.compare_exchange_weak(expected, desired, order);
199  }
200 
201  inline bool compare_exchange_strong(
203  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) LIBCOPP_MACRO_NOEXCEPT {
204  return data_.compare_exchange_strong(expected, desired, success, failure);
205  }
206  inline bool compare_exchange_strong(
208  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) volatile LIBCOPP_MACRO_NOEXCEPT {
209  return data_.compare_exchange_strong(expected, desired, success, failure);
210  }
211 
212  inline bool compare_exchange_strong(value_type &expected, value_type desired,
215  LIBCOPP_MACRO_NOEXCEPT {
216  return data_.compare_exchange_strong(expected, desired, order);
217  }
218  inline bool compare_exchange_strong(
219  value_type &expected, value_type desired,
221  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
222  return data_.compare_exchange_strong(expected, desired, order);
223  }
224 
225  inline value_type fetch_add(value_type arg,
228  return data_.fetch_add(arg, order);
229  }
230  inline value_type fetch_add(
232  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
233  return data_.fetch_add(arg, order);
234  }
235 
236  inline value_type fetch_sub(value_type arg,
239  return data_.fetch_sub(arg, order);
240  }
241  inline value_type fetch_sub(
243  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
244  return data_.fetch_sub(arg, order);
245  }
246 
247  inline value_type fetch_and(value_type arg,
250  return data_.fetch_and(arg, order);
251  }
252  inline value_type fetch_and(
254  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
255  return data_.fetch_and(arg, order);
256  }
257 
258  inline value_type fetch_or(value_type arg,
261  return data_.fetch_or(arg, order);
262  }
263  inline value_type fetch_or(
265  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
266  return data_.fetch_or(arg, order);
267  }
268 
269  inline value_type fetch_xor(value_type arg,
272  return data_.fetch_xor(arg, order);
273  }
274  inline value_type fetch_xor(
276  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
277  return data_.fetch_xor(arg, order);
278  }
279 };
280 #else
281 
282 # if defined(__clang__)
283 # if !defined(__GCC_ATOMIC_INT_LOCK_FREE) && \
284  (!defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1))
285 # error clang version is too old
286 # endif
287 # if defined(__GCC_ATOMIC_INT_LOCK_FREE)
288 // @see https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
289 # define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC 1
290 # else
291 // @see https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html
292 # define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC 1
293 # endif
294 # elif defined(__GNUC__) || defined(__INTEL_COMPILER)
295 # if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1))
296 # error gcc version must be greater or equal than 4.1
297 # endif
298 # if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1100
299 # error intel compiler version must be greater or equal than 11.0
300 # endif
301 # if defined(__GCC_ATOMIC_INT_LOCK_FREE)
302 // @see https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
303 # define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC 1
304 # else
305 // @see https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html
306 # define __LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC 1
307 # endif
308 # else
309 # error currently only gcc, msvc, intel compiler & llvm-clang are supported
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 # else // 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  using value_type = Ty;
348 
349  private:
350  volatile value_type data_;
351  atomic_int_type(const atomic_int_type &) = delete;
352 # ifndef _MSC_VER
354  atomic_int_type &operator=(const atomic_int_type &) volatile = delete;
355 # endif
356 
357  public:
358  atomic_int_type() LIBCOPP_MACRO_NOEXCEPT : data_() {}
359 
360  atomic_int_type(value_type desired) LIBCOPP_MACRO_NOEXCEPT : data_(desired) {}
361 
362  inline void store(value_type desired,
365 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
366  __atomic_store_n(&data_, desired, order);
367 # else
368  __sync_lock_test_and_set(&data_, desired);
369 # endif
370  }
371 
372  inline void store(value_type desired,
374  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
375 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
376  __atomic_store_n(&data_, desired, order);
377 # else
378  __sync_lock_test_and_set(&data_, desired);
379 # endif
380  }
381 
384 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
385  return __atomic_load_n(&data_, order);
386 # else
387  __sync_synchronize();
388  return data_;
389 # endif
390  }
391 
394  volatile LIBCOPP_MACRO_NOEXCEPT {
395 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
396  return __atomic_load_n(&data_, order);
397 # else
398  __sync_synchronize();
399  return data_;
400 # endif
401  }
402 
403  inline operator value_type() const LIBCOPP_MACRO_NOEXCEPT { return load(); }
404  inline operator value_type() const volatile LIBCOPP_MACRO_NOEXCEPT { return load(); }
405 
406  inline value_type operator=(value_type desired) LIBCOPP_MACRO_NOEXCEPT {
407  store(desired);
408  return desired;
409  }
410  inline value_type operator=(value_type desired) volatile LIBCOPP_MACRO_NOEXCEPT {
411  store(desired);
412  return desired;
413  }
414 
415  inline value_type operator++() LIBCOPP_MACRO_NOEXCEPT { return fetch_add(1) + 1; }
416  inline value_type operator++() volatile LIBCOPP_MACRO_NOEXCEPT { return fetch_add(1) + 1; }
417  inline value_type operator++(int) LIBCOPP_MACRO_NOEXCEPT { return fetch_add(1); }
418  inline value_type operator++(int) volatile LIBCOPP_MACRO_NOEXCEPT { return fetch_add(1); }
419  inline value_type operator--() LIBCOPP_MACRO_NOEXCEPT { return fetch_sub(1) - 1; }
420  inline value_type operator--() volatile LIBCOPP_MACRO_NOEXCEPT { return fetch_sub(1) - 1; }
421  inline value_type operator--(int) LIBCOPP_MACRO_NOEXCEPT { return fetch_sub(1); }
422  inline value_type operator--(int) volatile LIBCOPP_MACRO_NOEXCEPT { return fetch_sub(1); }
423 
427 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
428  return __atomic_exchange_n(&data_, desired, order);
429 # else
430  value_type old_value = data_;
431  while (!__sync_bool_compare_and_swap(&data_, old_value, desired)) {
432  old_value = data_;
433  }
434  return old_value;
435 # endif
436  }
437 
439  value_type desired,
441  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
442 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
443  return __atomic_exchange_n(&data_, desired, order);
444 # else
445  value_type old_value = data_;
446  while (!__sync_bool_compare_and_swap(&data_, old_value, desired)) {
447  old_value = data_;
448  }
449  return old_value;
450 # endif
451  }
452 
453  inline bool compare_exchange_weak(value_type &expected, value_type desired,
456  LIBCOPP_MACRO_NOEXCEPT {
457 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
458  return __atomic_compare_exchange_n(&data_, &expected, desired, true, success, failure);
459 # else
460  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
461  return true;
462  } else {
463  expected = data_;
464  return false;
465  }
466 # endif
467  }
468 
469  inline bool compare_exchange_weak(value_type &expected, value_type desired,
472  failure) volatile LIBCOPP_MACRO_NOEXCEPT {
473 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
474  return __atomic_compare_exchange_n(&data_, &expected, desired, true, success, failure);
475 # else
476  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
477  return true;
478  } else {
479  expected = data_;
480  return false;
481  }
482 # endif
483  }
484 
485  inline bool compare_exchange_weak(value_type &expected, value_type desired,
488  LIBCOPP_MACRO_NOEXCEPT {
489 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
490  return __atomic_compare_exchange_n(&data_, &expected, desired, true, order, order);
491 # else
492  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
493  return true;
494  } else {
495  expected = data_;
496  return false;
497  }
498 # endif
499  }
500 
502  value_type &expected, value_type desired,
504  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
505 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
506  return __atomic_compare_exchange_n(&data_, &expected, desired, true, order, order);
507 # else
508  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
509  return true;
510  } else {
511  expected = data_;
512  return false;
513  }
514 # endif
515  }
516 
517  inline bool compare_exchange_strong(value_type &expected, value_type desired,
520  LIBCOPP_MACRO_NOEXCEPT {
521 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
522  return __atomic_compare_exchange_n(&data_, &expected, desired, false, success, failure);
523 # else
524  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
525  return true;
526  } else {
527  expected = data_;
528  return false;
529  }
530 # endif
531  }
532 
533  inline bool compare_exchange_strong(value_type &expected, value_type desired,
536  failure) volatile LIBCOPP_MACRO_NOEXCEPT {
537 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
538  return __atomic_compare_exchange_n(&data_, &expected, desired, false, success, failure);
539 # else
540  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
541  return true;
542  } else {
543  expected = data_;
544  return false;
545  }
546 # endif
547  }
548 
549  inline bool compare_exchange_strong(value_type &expected, value_type desired,
552  LIBCOPP_MACRO_NOEXCEPT {
553 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
554  return __atomic_compare_exchange_n(&data_, &expected, desired, false, order, order);
555 # else
556  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
557  return true;
558  } else {
559  expected = data_;
560  return false;
561  }
562 # endif
563  }
564 
566  value_type &expected, value_type desired,
568  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
569 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
570  return __atomic_compare_exchange_n(&data_, &expected, desired, false, order, order);
571 # else
572  if (__sync_bool_compare_and_swap(&data_, expected, desired)) {
573  return true;
574  } else {
575  expected = data_;
576  return false;
577  }
578 # endif
579  }
580 
584 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
585  return __atomic_fetch_add(&data_, arg, order);
586 # else
587  return __sync_fetch_and_add(&data_, arg);
588 # endif
589  }
592  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
593 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
594  return __atomic_fetch_add(&data_, arg, order);
595 # else
596  return __sync_fetch_and_add(&data_, arg);
597 # endif
598  }
599 
603 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
604  return __atomic_fetch_sub(&data_, arg, order);
605 # else
606  return __sync_fetch_and_sub(&data_, arg);
607 # endif
608  }
611  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
612 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
613  return __atomic_fetch_sub(&data_, arg, order);
614 # else
615  return __sync_fetch_and_sub(&data_, arg);
616 # endif
617  }
618 
622 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
623  return __atomic_fetch_and(&data_, arg, order);
624 # else
625  return __sync_fetch_and_and(&data_, arg);
626 # endif
627  }
630  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
631 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
632  return __atomic_fetch_and(&data_, arg, order);
633 # else
634  return __sync_fetch_and_and(&data_, arg);
635 # endif
636  }
637 
641 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
642  return __atomic_fetch_or(&data_, arg, order);
643 # else
644  return __sync_fetch_and_or(&data_, arg);
645 # endif
646  }
649  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
650 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
651  return __atomic_fetch_or(&data_, arg, order);
652 # else
653  return __sync_fetch_and_or(&data_, arg);
654 # endif
655  }
656 
660 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
661  return __atomic_fetch_xor(&data_, arg, order);
662 # else
663  return __sync_fetch_and_xor(&data_, arg);
664 # endif
665  }
668  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
669 # if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC)
670  return __atomic_fetch_xor(&data_, arg, order);
671 # else
672  return __sync_fetch_and_xor(&data_, arg);
673 # endif
674  }
675 };
676 
677 #endif
678 
679 // used for unsafe (not multi-thread safe)
680 template <typename Ty = int>
681 struct LIBCOPP_COPP_API_HEAD_ONLY unsafe_int_type {
682  using value_type = Ty;
683 };
684 
685 template <typename Ty>
686 class LIBCOPP_COPP_API_HEAD_ONLY atomic_int_type<unsafe_int_type<Ty> > {
687  public:
689 
690  private:
692  atomic_int_type(const atomic_int_type &) = delete;
693 #ifndef _MSC_VER
695  atomic_int_type &operator=(const atomic_int_type &) volatile = delete;
696 #endif
697 
698  public:
699  atomic_int_type() : data_() {}
700  atomic_int_type(value_type desired) : data_(desired) {}
701 
702  inline void store(value_type desired,
705  data_ = desired;
706  }
707  inline void store(value_type desired,
709  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
710  data_ = desired;
711  }
712 
715  return data_;
716  }
719  volatile LIBCOPP_MACRO_NOEXCEPT {
720  return data_;
721  }
722 
723  inline operator value_type() const LIBCOPP_MACRO_NOEXCEPT { return load(); }
724  inline operator value_type() const volatile LIBCOPP_MACRO_NOEXCEPT { return load(); }
725 
726  inline value_type operator=(value_type desired) LIBCOPP_MACRO_NOEXCEPT {
727  store(desired);
728  return desired;
729  }
730  inline value_type operator=(value_type desired) volatile LIBCOPP_MACRO_NOEXCEPT {
731  store(desired);
732  return desired;
733  }
734 
735  inline value_type operator++() LIBCOPP_MACRO_NOEXCEPT { return ++data_; }
736  inline value_type operator++() volatile LIBCOPP_MACRO_NOEXCEPT { return ++data_; }
737  inline value_type operator++(int) LIBCOPP_MACRO_NOEXCEPT { return data_++; }
738  inline value_type operator++(int) volatile LIBCOPP_MACRO_NOEXCEPT { return data_++; }
739  inline value_type operator--() LIBCOPP_MACRO_NOEXCEPT { return --data_; }
740  inline value_type operator--() volatile LIBCOPP_MACRO_NOEXCEPT { return --data_; }
741  inline value_type operator--(int) LIBCOPP_MACRO_NOEXCEPT { return data_--; }
742  inline value_type operator--(int) volatile LIBCOPP_MACRO_NOEXCEPT { return data_--; }
743 
747  value_type ret = data_;
748  data_ = desired;
749  return ret;
750  }
752  value_type desired,
754  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
755  value_type ret = data_;
756  data_ = desired;
757  return ret;
758  }
759 
760  private:
761  inline bool cas(value_type &expected, value_type desired) LIBCOPP_MACRO_NOEXCEPT {
762  COPP_LIKELY_IF (data_ == expected) {
763  data_ = desired;
764  return true;
765  } else {
766  expected = data_;
767  return false;
768  }
769  }
770 
771  public:
772  inline bool compare_exchange_weak(value_type &expected, value_type desired,
775  LIBCOPP_MACRO_NOEXCEPT {
776  return cas(expected, desired);
777  }
778  inline bool compare_exchange_weak(value_type &expected, value_type desired,
781  failure) volatile LIBCOPP_MACRO_NOEXCEPT {
782  return cas(expected, desired);
783  }
784 
785  inline bool compare_exchange_weak(value_type &expected, value_type desired,
788  LIBCOPP_MACRO_NOEXCEPT {
789  return cas(expected, desired);
790  }
792  value_type &expected, value_type desired,
794  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
795  return cas(expected, desired);
796  }
797 
798  inline bool compare_exchange_strong(value_type &expected, value_type desired,
801  LIBCOPP_MACRO_NOEXCEPT {
802  return cas(expected, desired);
803  }
804  inline bool compare_exchange_strong(value_type &expected, value_type desired,
807  failure) volatile LIBCOPP_MACRO_NOEXCEPT {
808  return cas(expected, desired);
809  }
810 
811  inline bool compare_exchange_strong(value_type &expected, value_type desired,
814  LIBCOPP_MACRO_NOEXCEPT {
815  return cas(expected, desired);
816  }
818  value_type &expected, value_type desired,
820  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
821  return cas(expected, desired);
822  }
823 
827  value_type ret = data_;
828  data_ += arg;
829  return ret;
830  }
833  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
834  value_type ret = data_;
835  data_ += arg;
836  return ret;
837  }
838 
842  value_type ret = data_;
843  data_ -= arg;
844  return ret;
845  }
848  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
849  value_type ret = data_;
850  data_ -= arg;
851  return ret;
852  }
853 
857  value_type ret = data_;
858  data_ &= arg;
859  return ret;
860  }
863  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
864  value_type ret = data_;
865  data_ &= arg;
866  return ret;
867  }
868 
872  value_type ret = data_;
873  data_ |= arg;
874  return ret;
875  }
878  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
879  value_type ret = data_;
880  data_ |= arg;
881  return ret;
882  }
883 
887  value_type ret = data_;
888  data_ ^= arg;
889  return ret;
890  }
893  LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT {
894  value_type ret = data_;
895  data_ ^= arg;
896  return ret;
897  }
898 };
899 } // namespace lock
900 } // namespace util
901 LIBCOPP_COPP_NAMESPACE_END
value_type operator++() volatile LIBCOPP_MACRO_NOEXCEPT
atomic_int_type(const atomic_int_type &)=delete
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type operator--() LIBCOPP_MACRO_NOEXCEPT
value_type operator=(value_type desired) LIBCOPP_MACRO_NOEXCEPT
value_type operator++(int) LIBCOPP_MACRO_NOEXCEPT
value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
bool cas(value_type &expected, value_type desired) LIBCOPP_MACRO_NOEXCEPT
value_type operator--() volatile LIBCOPP_MACRO_NOEXCEPT
value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
atomic_int_type & operator=(const atomic_int_type &) volatile=delete
value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
void store(value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type operator++() LIBCOPP_MACRO_NOEXCEPT
atomic_int_type & operator=(const atomic_int_type &)=delete
value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
value_type operator--(int) volatile LIBCOPP_MACRO_NOEXCEPT
value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
value_type operator--(int) LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) LIBCOPP_MACRO_NOEXCEPT
value_type load(EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) const volatile LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) volatile LIBCOPP_MACRO_NOEXCEPT
value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) volatile LIBCOPP_MACRO_NOEXCEPT
value_type operator=(value_type desired) volatile LIBCOPP_MACRO_NOEXCEPT
value_type operator++(int) volatile LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
void store(value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
typename unsafe_int_type< Ty >::value_type value_type
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) LIBCOPP_MACRO_NOEXCEPT
value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type load(EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) const LIBCOPP_MACRO_NOEXCEPT
value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
value_type operator++(int) LIBCOPP_MACRO_NOEXCEPT
value_type load(EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) const LIBCOPP_MACRO_NOEXCEPT
atomic_int_type & operator=(const atomic_int_type &)=delete
value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
void store(value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) volatile LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) LIBCOPP_MACRO_NOEXCEPT
value_type operator=(value_type desired) LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type operator++(int) volatile LIBCOPP_MACRO_NOEXCEPT
atomic_int_type(value_type desired) LIBCOPP_MACRO_NOEXCEPT
atomic_int_type() LIBCOPP_MACRO_NOEXCEPT
value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type operator++() volatile LIBCOPP_MACRO_NOEXCEPT
value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
atomic_int_type & operator=(const atomic_int_type &) volatile=delete
value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
value_type operator--() volatile LIBCOPP_MACRO_NOEXCEPT
value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) LIBCOPP_MACRO_NOEXCEPT
value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
atomic_int_type(const atomic_int_type &)=delete
value_type operator--() LIBCOPP_MACRO_NOEXCEPT
value_type operator--(int) LIBCOPP_MACRO_NOEXCEPT
void store(value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
value_type operator++() LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) volatile LIBCOPP_MACRO_NOEXCEPT
volatile value_type data_
value_type operator--(int) volatile LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order success, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order failure) volatile LIBCOPP_MACRO_NOEXCEPT
value_type operator=(value_type desired) volatile LIBCOPP_MACRO_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired, EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) LIBCOPP_MACRO_NOEXCEPT
value_type load(EXPLICIT_UNUSED_ATTR LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order order=LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_seq_cst) const volatile LIBCOPP_MACRO_NOEXCEPT
导入继承关系约束 Licensed under the MIT licenses.
#define EXPLICIT_UNUSED_ATTR
maybe_unused, 标记忽略unused警告 usage: EXPLICIT_UNUSED_ATTR int a; class EXPLICIT_UNUSED_ATTR a; EXPLICIT_...
#define COPP_LIKELY_IF(...)
Definition: features.h:102
std::shared_ptr< cli::cmd_option_value > value_type
Definition: cmd_option.h:50