libstdc++
atomic
Go to the documentation of this file.
1 // -*- C++ -*- header.
2 
3 // Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file include/atomic
26  * This is a Standard C++ Library header.
27  */
28 
29 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
30 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
31 
32 #ifndef _GLIBCXX_ATOMIC
33 #define _GLIBCXX_ATOMIC 1
34 
35 #pragma GCC system_header
36 
37 #ifndef __GXX_EXPERIMENTAL_CXX0X__
38 # include <bits/c++0x_warning.h>
39 #endif
40 
41 #include <bits/atomic_base.h>
42 
43 namespace std _GLIBCXX_VISIBILITY(default)
44 {
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
46 
47  /**
48  * @addtogroup atomics
49  * @{
50  */
51 
52  /// atomic_bool
53  // NB: No operators or fetch-operations for this type.
54  struct atomic_bool
55  {
56  private:
57  __atomic_base<bool> _M_base;
58 
59  public:
60  atomic_bool() noexcept = default;
61  ~atomic_bool() noexcept = default;
62  atomic_bool(const atomic_bool&) = delete;
63  atomic_bool& operator=(const atomic_bool&) = delete;
64  atomic_bool& operator=(const atomic_bool&) volatile = delete;
65 
66  constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { }
67 
68  bool
69  operator=(bool __i) noexcept
70  { return _M_base.operator=(__i); }
71 
72  bool
73  operator=(bool __i) volatile noexcept
74  { return _M_base.operator=(__i); }
75 
76  operator bool() const noexcept
77  { return _M_base.load(); }
78 
79  operator bool() const volatile noexcept
80  { return _M_base.load(); }
81 
82  bool
83  is_lock_free() const noexcept { return _M_base.is_lock_free(); }
84 
85  bool
86  is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
87 
88  void
89  store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
90  { _M_base.store(__i, __m); }
91 
92  void
93  store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
94  { _M_base.store(__i, __m); }
95 
96  bool
97  load(memory_order __m = memory_order_seq_cst) const noexcept
98  { return _M_base.load(__m); }
99 
100  bool
101  load(memory_order __m = memory_order_seq_cst) const volatile noexcept
102  { return _M_base.load(__m); }
103 
104  bool
105  exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
106  { return _M_base.exchange(__i, __m); }
107 
108  bool
109  exchange(bool __i,
110  memory_order __m = memory_order_seq_cst) volatile noexcept
111  { return _M_base.exchange(__i, __m); }
112 
113  bool
114  compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
115  memory_order __m2) noexcept
116  { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
117 
118  bool
119  compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
120  memory_order __m2) volatile noexcept
121  { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
122 
123  bool
124  compare_exchange_weak(bool& __i1, bool __i2,
125  memory_order __m = memory_order_seq_cst) noexcept
126  { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
127 
128  bool
129  compare_exchange_weak(bool& __i1, bool __i2,
130  memory_order __m = memory_order_seq_cst) volatile noexcept
131  { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
132 
133  bool
134  compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
135  memory_order __m2) noexcept
136  { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
137 
138  bool
139  compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
140  memory_order __m2) volatile noexcept
141  { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
142 
143  bool
144  compare_exchange_strong(bool& __i1, bool __i2,
145  memory_order __m = memory_order_seq_cst) noexcept
146  { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
147 
148  bool
149  compare_exchange_strong(bool& __i1, bool __i2,
150  memory_order __m = memory_order_seq_cst) volatile noexcept
151  { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
152  };
153 
154 
155  /// atomic
156  /// 29.4.3, Generic atomic type, primary class template.
157  template<typename _Tp>
158  struct atomic
159  {
160  private:
161  _Tp _M_i;
162 
163  public:
164  atomic() noexcept = default;
165  ~atomic() noexcept = default;
166  atomic(const atomic&) = delete;
167  atomic& operator=(const atomic&) = delete;
168  atomic& operator=(const atomic&) volatile = delete;
169 
170  constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
171 
172  operator _Tp() const noexcept
173  { return load(); }
174 
175  operator _Tp() const volatile noexcept
176  { return load(); }
177 
178  _Tp
179  operator=(_Tp __i) noexcept
180  { store(__i); return __i; }
181 
182  _Tp
183  operator=(_Tp __i) volatile noexcept
184  { store(__i); return __i; }
185 
186  bool
187  is_lock_free() const noexcept
188  { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); }
189 
190  bool
191  is_lock_free() const volatile noexcept
192  { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); }
193 
194  void
195  store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
196  { __atomic_store(&_M_i, &__i, _m); }
197 
198  void
199  store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept
200  { __atomic_store(&_M_i, &__i, _m); }
201 
202  _Tp
203  load(memory_order _m = memory_order_seq_cst) const noexcept
204  {
205  _Tp tmp;
206  __atomic_load(&_M_i, &tmp, _m);
207  return tmp;
208  }
209 
210  _Tp
211  load(memory_order _m = memory_order_seq_cst) const volatile noexcept
212  {
213  _Tp tmp;
214  __atomic_load(&_M_i, &tmp, _m);
215  return tmp;
216  }
217 
218  _Tp
219  exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
220  {
221  _Tp tmp;
222  __atomic_exchange(&_M_i, &__i, &tmp, _m);
223  return tmp;
224  }
225 
226  _Tp
227  exchange(_Tp __i,
228  memory_order _m = memory_order_seq_cst) volatile noexcept
229  {
230  _Tp tmp;
231  __atomic_exchange(&_M_i, &__i, &tmp, _m);
232  return tmp;
233  }
234 
235  bool
236  compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
237  memory_order __f) noexcept
238  {
239  return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
240  }
241 
242  bool
243  compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
244  memory_order __f) volatile noexcept
245  {
246  return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
247  }
248 
249  bool
250  compare_exchange_weak(_Tp& __e, _Tp __i,
251  memory_order __m = memory_order_seq_cst) noexcept
252  { return compare_exchange_weak(__e, __i, __m, __m); }
253 
254  bool
255  compare_exchange_weak(_Tp& __e, _Tp __i,
256  memory_order __m = memory_order_seq_cst) volatile noexcept
257  { return compare_exchange_weak(__e, __i, __m, __m); }
258 
259  bool
260  compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
261  memory_order __f) noexcept
262  {
263  return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
264  }
265 
266  bool
267  compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
268  memory_order __f) volatile noexcept
269  {
270  return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
271  }
272 
273  bool
274  compare_exchange_strong(_Tp& __e, _Tp __i,
275  memory_order __m = memory_order_seq_cst) noexcept
276  { return compare_exchange_strong(__e, __i, __m, __m); }
277 
278  bool
279  compare_exchange_strong(_Tp& __e, _Tp __i,
280  memory_order __m = memory_order_seq_cst) volatile noexcept
281  { return compare_exchange_strong(__e, __i, __m, __m); }
282  };
283 
284 
285  /// Partial specialization for pointer types.
286  template<typename _Tp>
287  struct atomic<_Tp*>
288  {
289  typedef _Tp* __pointer_type;
291  __base_type _M_b;
292 
293  atomic() noexcept = default;
294  ~atomic() noexcept = default;
295  atomic(const atomic&) = delete;
296  atomic& operator=(const atomic&) = delete;
297  atomic& operator=(const atomic&) volatile = delete;
298 
299  constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
300 
301  operator __pointer_type() const noexcept
302  { return __pointer_type(_M_b); }
303 
304  operator __pointer_type() const volatile noexcept
305  { return __pointer_type(_M_b); }
306 
307  __pointer_type
308  operator=(__pointer_type __p) noexcept
309  { return _M_b.operator=(__p); }
310 
311  __pointer_type
312  operator=(__pointer_type __p) volatile noexcept
313  { return _M_b.operator=(__p); }
314 
315  __pointer_type
316  operator++(int) noexcept
317  { return _M_b++; }
318 
319  __pointer_type
320  operator++(int) volatile noexcept
321  { return _M_b++; }
322 
323  __pointer_type
324  operator--(int) noexcept
325  { return _M_b--; }
326 
327  __pointer_type
328  operator--(int) volatile noexcept
329  { return _M_b--; }
330 
331  __pointer_type
332  operator++() noexcept
333  { return ++_M_b; }
334 
335  __pointer_type
336  operator++() volatile noexcept
337  { return ++_M_b; }
338 
339  __pointer_type
340  operator--() noexcept
341  { return --_M_b; }
342 
343  __pointer_type
344  operator--() volatile noexcept
345  { return --_M_b; }
346 
347  __pointer_type
348  operator+=(ptrdiff_t __d) noexcept
349  { return _M_b.operator+=(__d); }
350 
351  __pointer_type
352  operator+=(ptrdiff_t __d) volatile noexcept
353  { return _M_b.operator+=(__d); }
354 
355  __pointer_type
356  operator-=(ptrdiff_t __d) noexcept
357  { return _M_b.operator-=(__d); }
358 
359  __pointer_type
360  operator-=(ptrdiff_t __d) volatile noexcept
361  { return _M_b.operator-=(__d); }
362 
363  bool
364  is_lock_free() const noexcept
365  { return _M_b.is_lock_free(); }
366 
367  bool
368  is_lock_free() const volatile noexcept
369  { return _M_b.is_lock_free(); }
370 
371  void
372  store(__pointer_type __p,
373  memory_order __m = memory_order_seq_cst) noexcept
374  { return _M_b.store(__p, __m); }
375 
376  void
377  store(__pointer_type __p,
378  memory_order __m = memory_order_seq_cst) volatile noexcept
379  { return _M_b.store(__p, __m); }
380 
381  __pointer_type
382  load(memory_order __m = memory_order_seq_cst) const noexcept
383  { return _M_b.load(__m); }
384 
385  __pointer_type
386  load(memory_order __m = memory_order_seq_cst) const volatile noexcept
387  { return _M_b.load(__m); }
388 
389  __pointer_type
390  exchange(__pointer_type __p,
391  memory_order __m = memory_order_seq_cst) noexcept
392  { return _M_b.exchange(__p, __m); }
393 
394  __pointer_type
395  exchange(__pointer_type __p,
396  memory_order __m = memory_order_seq_cst) volatile noexcept
397  { return _M_b.exchange(__p, __m); }
398 
399  bool
400  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
401  memory_order __m1, memory_order __m2) noexcept
402  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
403 
404  bool
405  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
406  memory_order __m1,
407  memory_order __m2) volatile noexcept
408  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
409 
410  bool
411  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
412  memory_order __m = memory_order_seq_cst) noexcept
413  {
414  return compare_exchange_weak(__p1, __p2, __m,
415  __cmpexch_failure_order(__m));
416  }
417 
418  bool
419  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
420  memory_order __m = memory_order_seq_cst) volatile noexcept
421  {
422  return compare_exchange_weak(__p1, __p2, __m,
423  __cmpexch_failure_order(__m));
424  }
425 
426  bool
427  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
428  memory_order __m1, memory_order __m2) noexcept
429  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
430 
431  bool
432  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
433  memory_order __m1,
434  memory_order __m2) volatile noexcept
435  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
436 
437  bool
438  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
439  memory_order __m = memory_order_seq_cst) noexcept
440  {
441  return _M_b.compare_exchange_strong(__p1, __p2, __m,
442  __cmpexch_failure_order(__m));
443  }
444 
445  bool
446  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
447  memory_order __m = memory_order_seq_cst) volatile noexcept
448  {
449  return _M_b.compare_exchange_strong(__p1, __p2, __m,
450  __cmpexch_failure_order(__m));
451  }
452 
453  __pointer_type
454  fetch_add(ptrdiff_t __d,
455  memory_order __m = memory_order_seq_cst) noexcept
456  { return _M_b.fetch_add(__d, __m); }
457 
458  __pointer_type
459  fetch_add(ptrdiff_t __d,
460  memory_order __m = memory_order_seq_cst) volatile noexcept
461  { return _M_b.fetch_add(__d, __m); }
462 
463  __pointer_type
464  fetch_sub(ptrdiff_t __d,
465  memory_order __m = memory_order_seq_cst) noexcept
466  { return _M_b.fetch_sub(__d, __m); }
467 
468  __pointer_type
469  fetch_sub(ptrdiff_t __d,
470  memory_order __m = memory_order_seq_cst) volatile noexcept
471  { return _M_b.fetch_sub(__d, __m); }
472  };
473 
474 
475  /// Explicit specialization for bool.
476  template<>
477  struct atomic<bool> : public atomic_bool
478  {
479  typedef bool __integral_type;
480  typedef atomic_bool __base_type;
481 
482  atomic() noexcept = default;
483  ~atomic() noexcept = default;
484  atomic(const atomic&) = delete;
485  atomic& operator=(const atomic&) = delete;
486  atomic& operator=(const atomic&) volatile = delete;
487 
488  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
489 
490  using __base_type::operator __integral_type;
491  using __base_type::operator=;
492  };
493 
494  /// Explicit specialization for char.
495  template<>
496  struct atomic<char> : public atomic_char
497  {
498  typedef char __integral_type;
499  typedef atomic_char __base_type;
500 
501  atomic() noexcept = default;
502  ~atomic() noexcept = default;
503  atomic(const atomic&) = delete;
504  atomic& operator=(const atomic&) = delete;
505  atomic& operator=(const atomic&) volatile = delete;
506 
507  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
508 
509  using __base_type::operator __integral_type;
510  using __base_type::operator=;
511  };
512 
513  /// Explicit specialization for signed char.
514  template<>
515  struct atomic<signed char> : public atomic_schar
516  {
517  typedef signed char __integral_type;
518  typedef atomic_schar __base_type;
519 
520  atomic() noexcept= default;
521  ~atomic() noexcept = default;
522  atomic(const atomic&) = delete;
523  atomic& operator=(const atomic&) = delete;
524  atomic& operator=(const atomic&) volatile = delete;
525 
526  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
527 
528  using __base_type::operator __integral_type;
529  using __base_type::operator=;
530  };
531 
532  /// Explicit specialization for unsigned char.
533  template<>
534  struct atomic<unsigned char> : public atomic_uchar
535  {
536  typedef unsigned char __integral_type;
537  typedef atomic_uchar __base_type;
538 
539  atomic() noexcept= default;
540  ~atomic() noexcept = default;
541  atomic(const atomic&) = delete;
542  atomic& operator=(const atomic&) = delete;
543  atomic& operator=(const atomic&) volatile = delete;
544 
545  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
546 
547  using __base_type::operator __integral_type;
548  using __base_type::operator=;
549  };
550 
551  /// Explicit specialization for short.
552  template<>
553  struct atomic<short> : public atomic_short
554  {
555  typedef short __integral_type;
556  typedef atomic_short __base_type;
557 
558  atomic() noexcept = default;
559  ~atomic() noexcept = default;
560  atomic(const atomic&) = delete;
561  atomic& operator=(const atomic&) = delete;
562  atomic& operator=(const atomic&) volatile = delete;
563 
564  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
565 
566  using __base_type::operator __integral_type;
567  using __base_type::operator=;
568  };
569 
570  /// Explicit specialization for unsigned short.
571  template<>
572  struct atomic<unsigned short> : public atomic_ushort
573  {
574  typedef unsigned short __integral_type;
575  typedef atomic_ushort __base_type;
576 
577  atomic() noexcept = default;
578  ~atomic() noexcept = default;
579  atomic(const atomic&) = delete;
580  atomic& operator=(const atomic&) = delete;
581  atomic& operator=(const atomic&) volatile = delete;
582 
583  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
584 
585  using __base_type::operator __integral_type;
586  using __base_type::operator=;
587  };
588 
589  /// Explicit specialization for int.
590  template<>
591  struct atomic<int> : atomic_int
592  {
593  typedef int __integral_type;
594  typedef atomic_int __base_type;
595 
596  atomic() noexcept = default;
597  ~atomic() noexcept = default;
598  atomic(const atomic&) = delete;
599  atomic& operator=(const atomic&) = delete;
600  atomic& operator=(const atomic&) volatile = delete;
601 
602  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
603 
604  using __base_type::operator __integral_type;
605  using __base_type::operator=;
606  };
607 
608  /// Explicit specialization for unsigned int.
609  template<>
610  struct atomic<unsigned int> : public atomic_uint
611  {
612  typedef unsigned int __integral_type;
613  typedef atomic_uint __base_type;
614 
615  atomic() noexcept = default;
616  ~atomic() noexcept = default;
617  atomic(const atomic&) = delete;
618  atomic& operator=(const atomic&) = delete;
619  atomic& operator=(const atomic&) volatile = delete;
620 
621  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
622 
623  using __base_type::operator __integral_type;
624  using __base_type::operator=;
625  };
626 
627  /// Explicit specialization for long.
628  template<>
629  struct atomic<long> : public atomic_long
630  {
631  typedef long __integral_type;
632  typedef atomic_long __base_type;
633 
634  atomic() noexcept = default;
635  ~atomic() noexcept = default;
636  atomic(const atomic&) = delete;
637  atomic& operator=(const atomic&) = delete;
638  atomic& operator=(const atomic&) volatile = delete;
639 
640  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
641 
642  using __base_type::operator __integral_type;
643  using __base_type::operator=;
644  };
645 
646  /// Explicit specialization for unsigned long.
647  template<>
648  struct atomic<unsigned long> : public atomic_ulong
649  {
650  typedef unsigned long __integral_type;
651  typedef atomic_ulong __base_type;
652 
653  atomic() noexcept = default;
654  ~atomic() noexcept = default;
655  atomic(const atomic&) = delete;
656  atomic& operator=(const atomic&) = delete;
657  atomic& operator=(const atomic&) volatile = delete;
658 
659  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
660 
661  using __base_type::operator __integral_type;
662  using __base_type::operator=;
663  };
664 
665  /// Explicit specialization for long long.
666  template<>
667  struct atomic<long long> : public atomic_llong
668  {
669  typedef long long __integral_type;
670  typedef atomic_llong __base_type;
671 
672  atomic() noexcept = default;
673  ~atomic() noexcept = default;
674  atomic(const atomic&) = delete;
675  atomic& operator=(const atomic&) = delete;
676  atomic& operator=(const atomic&) volatile = delete;
677 
678  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
679 
680  using __base_type::operator __integral_type;
681  using __base_type::operator=;
682  };
683 
684  /// Explicit specialization for unsigned long long.
685  template<>
686  struct atomic<unsigned long long> : public atomic_ullong
687  {
688  typedef unsigned long long __integral_type;
689  typedef atomic_ullong __base_type;
690 
691  atomic() noexcept = default;
692  ~atomic() noexcept = default;
693  atomic(const atomic&) = delete;
694  atomic& operator=(const atomic&) = delete;
695  atomic& operator=(const atomic&) volatile = delete;
696 
697  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
698 
699  using __base_type::operator __integral_type;
700  using __base_type::operator=;
701  };
702 
703  /// Explicit specialization for wchar_t.
704  template<>
705  struct atomic<wchar_t> : public atomic_wchar_t
706  {
707  typedef wchar_t __integral_type;
708  typedef atomic_wchar_t __base_type;
709 
710  atomic() noexcept = default;
711  ~atomic() noexcept = default;
712  atomic(const atomic&) = delete;
713  atomic& operator=(const atomic&) = delete;
714  atomic& operator=(const atomic&) volatile = delete;
715 
716  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
717 
718  using __base_type::operator __integral_type;
719  using __base_type::operator=;
720  };
721 
722  /// Explicit specialization for char16_t.
723  template<>
724  struct atomic<char16_t> : public atomic_char16_t
725  {
726  typedef char16_t __integral_type;
728 
729  atomic() noexcept = default;
730  ~atomic() noexcept = default;
731  atomic(const atomic&) = delete;
732  atomic& operator=(const atomic&) = delete;
733  atomic& operator=(const atomic&) volatile = delete;
734 
735  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
736 
737  using __base_type::operator __integral_type;
738  using __base_type::operator=;
739  };
740 
741  /// Explicit specialization for char32_t.
742  template<>
743  struct atomic<char32_t> : public atomic_char32_t
744  {
745  typedef char32_t __integral_type;
747 
748  atomic() noexcept = default;
749  ~atomic() noexcept = default;
750  atomic(const atomic&) = delete;
751  atomic& operator=(const atomic&) = delete;
752  atomic& operator=(const atomic&) volatile = delete;
753 
754  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
755 
756  using __base_type::operator __integral_type;
757  using __base_type::operator=;
758  };
759 
760 
761  // Function definitions, atomic_flag operations.
762  inline bool
763  atomic_flag_test_and_set_explicit(atomic_flag* __a,
764  memory_order __m) noexcept
765  { return __a->test_and_set(__m); }
766 
767  inline bool
768  atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
769  memory_order __m) noexcept
770  { return __a->test_and_set(__m); }
771 
772  inline void
773  atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
774  { __a->clear(__m); }
775 
776  inline void
777  atomic_flag_clear_explicit(volatile atomic_flag* __a,
778  memory_order __m) noexcept
779  { __a->clear(__m); }
780 
781  inline bool
782  atomic_flag_test_and_set(atomic_flag* __a) noexcept
783  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
784 
785  inline bool
786  atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
787  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
788 
789  inline void
790  atomic_flag_clear(atomic_flag* __a) noexcept
791  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
792 
793  inline void
794  atomic_flag_clear(volatile atomic_flag* __a) noexcept
795  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
796 
797 
798  // Function templates generally applicable to atomic types.
799  template<typename _ITp>
800  inline bool
801  atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
802  { return __a->is_lock_free(); }
803 
804  template<typename _ITp>
805  inline bool
806  atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
807  { return __a->is_lock_free(); }
808 
809  template<typename _ITp>
810  inline void
811  atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
812 
813  template<typename _ITp>
814  inline void
815  atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
816 
817  template<typename _ITp>
818  inline void
819  atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
820  memory_order __m) noexcept
821  { __a->store(__i, __m); }
822 
823  template<typename _ITp>
824  inline void
825  atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
826  memory_order __m) noexcept
827  { __a->store(__i, __m); }
828 
829  template<typename _ITp>
830  inline _ITp
831  atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
832  { return __a->load(__m); }
833 
834  template<typename _ITp>
835  inline _ITp
836  atomic_load_explicit(const volatile atomic<_ITp>* __a,
837  memory_order __m) noexcept
838  { return __a->load(__m); }
839 
840  template<typename _ITp>
841  inline _ITp
842  atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
843  memory_order __m) noexcept
844  { return __a->exchange(__i, __m); }
845 
846  template<typename _ITp>
847  inline _ITp
848  atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
849  memory_order __m) noexcept
850  { return __a->exchange(__i, __m); }
851 
852  template<typename _ITp>
853  inline bool
854  atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
855  _ITp* __i1, _ITp __i2,
856  memory_order __m1,
857  memory_order __m2) noexcept
858  { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
859 
860  template<typename _ITp>
861  inline bool
862  atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
863  _ITp* __i1, _ITp __i2,
864  memory_order __m1,
865  memory_order __m2) noexcept
866  { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
867 
868  template<typename _ITp>
869  inline bool
870  atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
871  _ITp* __i1, _ITp __i2,
872  memory_order __m1,
873  memory_order __m2) noexcept
874  { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
875 
876  template<typename _ITp>
877  inline bool
878  atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
879  _ITp* __i1, _ITp __i2,
880  memory_order __m1,
881  memory_order __m2) noexcept
882  { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
883 
884 
885  template<typename _ITp>
886  inline void
887  atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
888  { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
889 
890  template<typename _ITp>
891  inline void
892  atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
893  { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
894 
895  template<typename _ITp>
896  inline _ITp
897  atomic_load(const atomic<_ITp>* __a) noexcept
898  { return atomic_load_explicit(__a, memory_order_seq_cst); }
899 
900  template<typename _ITp>
901  inline _ITp
902  atomic_load(const volatile atomic<_ITp>* __a) noexcept
903  { return atomic_load_explicit(__a, memory_order_seq_cst); }
904 
905  template<typename _ITp>
906  inline _ITp
907  atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
908  { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
909 
910  template<typename _ITp>
911  inline _ITp
912  atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
913  { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
914 
915  template<typename _ITp>
916  inline bool
917  atomic_compare_exchange_weak(atomic<_ITp>* __a,
918  _ITp* __i1, _ITp __i2) noexcept
919  {
920  return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
921  memory_order_seq_cst,
922  memory_order_seq_cst);
923  }
924 
925  template<typename _ITp>
926  inline bool
927  atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
928  _ITp* __i1, _ITp __i2) noexcept
929  {
930  return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
931  memory_order_seq_cst,
932  memory_order_seq_cst);
933  }
934 
935  template<typename _ITp>
936  inline bool
937  atomic_compare_exchange_strong(atomic<_ITp>* __a,
938  _ITp* __i1, _ITp __i2) noexcept
939  {
940  return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
941  memory_order_seq_cst,
942  memory_order_seq_cst);
943  }
944 
945  template<typename _ITp>
946  inline bool
947  atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
948  _ITp* __i1, _ITp __i2) noexcept
949  {
950  return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
951  memory_order_seq_cst,
952  memory_order_seq_cst);
953  }
954 
955  // Function templates for atomic_integral operations only, using
956  // __atomic_base. Template argument should be constricted to
957  // intergral types as specified in the standard, excluding address
958  // types.
959  template<typename _ITp>
960  inline _ITp
961  atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
962  memory_order __m) noexcept
963  { return __a->fetch_add(__i, __m); }
964 
965  template<typename _ITp>
966  inline _ITp
967  atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
968  memory_order __m) noexcept
969  { return __a->fetch_add(__i, __m); }
970 
971  template<typename _ITp>
972  inline _ITp
973  atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
974  memory_order __m) noexcept
975  { return __a->fetch_sub(__i, __m); }
976 
977  template<typename _ITp>
978  inline _ITp
979  atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
980  memory_order __m) noexcept
981  { return __a->fetch_sub(__i, __m); }
982 
983  template<typename _ITp>
984  inline _ITp
985  atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
986  memory_order __m) noexcept
987  { return __a->fetch_and(__i, __m); }
988 
989  template<typename _ITp>
990  inline _ITp
991  atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
992  memory_order __m) noexcept
993  { return __a->fetch_and(__i, __m); }
994 
995  template<typename _ITp>
996  inline _ITp
997  atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
998  memory_order __m) noexcept
999  { return __a->fetch_or(__i, __m); }
1000 
1001  template<typename _ITp>
1002  inline _ITp
1003  atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1004  memory_order __m) noexcept
1005  { return __a->fetch_or(__i, __m); }
1006 
1007  template<typename _ITp>
1008  inline _ITp
1009  atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1010  memory_order __m) noexcept
1011  { return __a->fetch_xor(__i, __m); }
1012 
1013  template<typename _ITp>
1014  inline _ITp
1015  atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1016  memory_order __m) noexcept
1017  { return __a->fetch_xor(__i, __m); }
1018 
1019  template<typename _ITp>
1020  inline _ITp
1021  atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1022  { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1023 
1024  template<typename _ITp>
1025  inline _ITp
1026  atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1027  { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1028 
1029  template<typename _ITp>
1030  inline _ITp
1031  atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1032  { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1033 
1034  template<typename _ITp>
1035  inline _ITp
1036  atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1037  { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1038 
1039  template<typename _ITp>
1040  inline _ITp
1041  atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1042  { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1043 
1044  template<typename _ITp>
1045  inline _ITp
1046  atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1047  { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1048 
1049  template<typename _ITp>
1050  inline _ITp
1051  atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1052  { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1053 
1054  template<typename _ITp>
1055  inline _ITp
1056  atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1057  { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1058 
1059  template<typename _ITp>
1060  inline _ITp
1061  atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1062  { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1063 
1064  template<typename _ITp>
1065  inline _ITp
1066  atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1067  { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1068 
1069 
1070  // Partial specializations for pointers.
1071  template<typename _ITp>
1072  inline _ITp*
1073  atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1074  memory_order __m) noexcept
1075  { return __a->fetch_add(__d, __m); }
1076 
1077  template<typename _ITp>
1078  inline _ITp*
1079  atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1080  memory_order __m) noexcept
1081  { return __a->fetch_add(__d, __m); }
1082 
1083  template<typename _ITp>
1084  inline _ITp*
1085  atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1086  { return __a->fetch_add(__d); }
1087 
1088  template<typename _ITp>
1089  inline _ITp*
1090  atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1091  { return __a->fetch_add(__d); }
1092 
1093  template<typename _ITp>
1094  inline _ITp*
1095  atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1096  ptrdiff_t __d, memory_order __m) noexcept
1097  { return __a->fetch_sub(__d, __m); }
1098 
1099  template<typename _ITp>
1100  inline _ITp*
1101  atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1102  memory_order __m) noexcept
1103  { return __a->fetch_sub(__d, __m); }
1104 
1105  template<typename _ITp>
1106  inline _ITp*
1107  atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1108  { return __a->fetch_sub(__d); }
1109 
1110  template<typename _ITp>
1111  inline _ITp*
1112  atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1113  { return __a->fetch_sub(__d); }
1114  // @} group atomics
1115 
1116 _GLIBCXX_END_NAMESPACE_VERSION
1117 } // namespace
1118 
1119 #endif
memory_order
Enumeration for memory_order.
Definition: atomic_base.h:52
atomic 29.4.3, Generic atomic type, primary class template.
Definition: atomic:158
atomic_flag
Definition: atomic_base.h:244
atomic_bool
Definition: atomic:54