libstdc++
atomic
1 // -*- C++ -*- header.
2 
3 // Copyright (C) 2008-2013 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 #if __cplusplus < 201103L
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  /**
156  * @brief Generic atomic type, primary class template.
157  *
158  * @tparam _Tp Type to be made atomic, must be trivally copyable.
159  */
160  template<typename _Tp>
161  struct atomic
162  {
163  private:
164  _Tp _M_i;
165 
166  public:
167  atomic() noexcept = default;
168  ~atomic() noexcept = default;
169  atomic(const atomic&) = delete;
170  atomic& operator=(const atomic&) = delete;
171  atomic& operator=(const atomic&) volatile = delete;
172 
173  constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
174 
175  operator _Tp() const noexcept
176  { return load(); }
177 
178  operator _Tp() const volatile noexcept
179  { return load(); }
180 
181  _Tp
182  operator=(_Tp __i) noexcept
183  { store(__i); return __i; }
184 
185  _Tp
186  operator=(_Tp __i) volatile noexcept
187  { store(__i); return __i; }
188 
189  bool
190  is_lock_free() const noexcept
191  { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
192 
193  bool
194  is_lock_free() const volatile noexcept
195  { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
196 
197  void
198  store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
199  { __atomic_store(&_M_i, &__i, _m); }
200 
201  void
202  store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept
203  { __atomic_store(&_M_i, &__i, _m); }
204 
205  _Tp
206  load(memory_order _m = memory_order_seq_cst) const noexcept
207  {
208  _Tp tmp;
209  __atomic_load(&_M_i, &tmp, _m);
210  return tmp;
211  }
212 
213  _Tp
214  load(memory_order _m = memory_order_seq_cst) const volatile noexcept
215  {
216  _Tp tmp;
217  __atomic_load(&_M_i, &tmp, _m);
218  return tmp;
219  }
220 
221  _Tp
222  exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
223  {
224  _Tp tmp;
225  __atomic_exchange(&_M_i, &__i, &tmp, _m);
226  return tmp;
227  }
228 
229  _Tp
230  exchange(_Tp __i,
231  memory_order _m = memory_order_seq_cst) volatile noexcept
232  {
233  _Tp tmp;
234  __atomic_exchange(&_M_i, &__i, &tmp, _m);
235  return tmp;
236  }
237 
238  bool
239  compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
240  memory_order __f) noexcept
241  {
242  return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
243  }
244 
245  bool
246  compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
247  memory_order __f) volatile noexcept
248  {
249  return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
250  }
251 
252  bool
253  compare_exchange_weak(_Tp& __e, _Tp __i,
254  memory_order __m = memory_order_seq_cst) noexcept
255  { return compare_exchange_weak(__e, __i, __m, __m); }
256 
257  bool
258  compare_exchange_weak(_Tp& __e, _Tp __i,
259  memory_order __m = memory_order_seq_cst) volatile noexcept
260  { return compare_exchange_weak(__e, __i, __m, __m); }
261 
262  bool
263  compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
264  memory_order __f) noexcept
265  {
266  return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
267  }
268 
269  bool
270  compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
271  memory_order __f) volatile noexcept
272  {
273  return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
274  }
275 
276  bool
277  compare_exchange_strong(_Tp& __e, _Tp __i,
278  memory_order __m = memory_order_seq_cst) noexcept
279  { return compare_exchange_strong(__e, __i, __m, __m); }
280 
281  bool
282  compare_exchange_strong(_Tp& __e, _Tp __i,
283  memory_order __m = memory_order_seq_cst) volatile noexcept
284  { return compare_exchange_strong(__e, __i, __m, __m); }
285  };
286 
287 
288  /// Partial specialization for pointer types.
289  template<typename _Tp>
290  struct atomic<_Tp*>
291  {
292  typedef _Tp* __pointer_type;
293  typedef __atomic_base<_Tp*> __base_type;
294  __base_type _M_b;
295 
296  atomic() noexcept = default;
297  ~atomic() noexcept = default;
298  atomic(const atomic&) = delete;
299  atomic& operator=(const atomic&) = delete;
300  atomic& operator=(const atomic&) volatile = delete;
301 
302  constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
303 
304  operator __pointer_type() const noexcept
305  { return __pointer_type(_M_b); }
306 
307  operator __pointer_type() const volatile noexcept
308  { return __pointer_type(_M_b); }
309 
310  __pointer_type
311  operator=(__pointer_type __p) noexcept
312  { return _M_b.operator=(__p); }
313 
314  __pointer_type
315  operator=(__pointer_type __p) volatile noexcept
316  { return _M_b.operator=(__p); }
317 
318  __pointer_type
319  operator++(int) noexcept
320  { return _M_b++; }
321 
322  __pointer_type
323  operator++(int) volatile noexcept
324  { return _M_b++; }
325 
326  __pointer_type
327  operator--(int) noexcept
328  { return _M_b--; }
329 
330  __pointer_type
331  operator--(int) volatile noexcept
332  { return _M_b--; }
333 
334  __pointer_type
335  operator++() noexcept
336  { return ++_M_b; }
337 
338  __pointer_type
339  operator++() volatile noexcept
340  { return ++_M_b; }
341 
342  __pointer_type
343  operator--() noexcept
344  { return --_M_b; }
345 
346  __pointer_type
347  operator--() volatile noexcept
348  { return --_M_b; }
349 
350  __pointer_type
351  operator+=(ptrdiff_t __d) noexcept
352  { return _M_b.operator+=(__d); }
353 
354  __pointer_type
355  operator+=(ptrdiff_t __d) volatile noexcept
356  { return _M_b.operator+=(__d); }
357 
358  __pointer_type
359  operator-=(ptrdiff_t __d) noexcept
360  { return _M_b.operator-=(__d); }
361 
362  __pointer_type
363  operator-=(ptrdiff_t __d) volatile noexcept
364  { return _M_b.operator-=(__d); }
365 
366  bool
367  is_lock_free() const noexcept
368  { return _M_b.is_lock_free(); }
369 
370  bool
371  is_lock_free() const volatile noexcept
372  { return _M_b.is_lock_free(); }
373 
374  void
375  store(__pointer_type __p,
376  memory_order __m = memory_order_seq_cst) noexcept
377  { return _M_b.store(__p, __m); }
378 
379  void
380  store(__pointer_type __p,
381  memory_order __m = memory_order_seq_cst) volatile noexcept
382  { return _M_b.store(__p, __m); }
383 
384  __pointer_type
385  load(memory_order __m = memory_order_seq_cst) const noexcept
386  { return _M_b.load(__m); }
387 
388  __pointer_type
389  load(memory_order __m = memory_order_seq_cst) const volatile noexcept
390  { return _M_b.load(__m); }
391 
392  __pointer_type
393  exchange(__pointer_type __p,
394  memory_order __m = memory_order_seq_cst) noexcept
395  { return _M_b.exchange(__p, __m); }
396 
397  __pointer_type
398  exchange(__pointer_type __p,
399  memory_order __m = memory_order_seq_cst) volatile noexcept
400  { return _M_b.exchange(__p, __m); }
401 
402  bool
403  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
404  memory_order __m1, memory_order __m2) noexcept
405  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
406 
407  bool
408  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
409  memory_order __m1,
410  memory_order __m2) volatile noexcept
411  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
412 
413  bool
414  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
415  memory_order __m = memory_order_seq_cst) noexcept
416  {
417  return compare_exchange_weak(__p1, __p2, __m,
418  __cmpexch_failure_order(__m));
419  }
420 
421  bool
422  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
423  memory_order __m = memory_order_seq_cst) volatile noexcept
424  {
425  return compare_exchange_weak(__p1, __p2, __m,
426  __cmpexch_failure_order(__m));
427  }
428 
429  bool
430  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
431  memory_order __m1, memory_order __m2) noexcept
432  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
433 
434  bool
435  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
436  memory_order __m1,
437  memory_order __m2) volatile noexcept
438  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
439 
440  bool
441  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
442  memory_order __m = memory_order_seq_cst) noexcept
443  {
444  return _M_b.compare_exchange_strong(__p1, __p2, __m,
445  __cmpexch_failure_order(__m));
446  }
447 
448  bool
449  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
450  memory_order __m = memory_order_seq_cst) volatile noexcept
451  {
452  return _M_b.compare_exchange_strong(__p1, __p2, __m,
453  __cmpexch_failure_order(__m));
454  }
455 
456  __pointer_type
457  fetch_add(ptrdiff_t __d,
458  memory_order __m = memory_order_seq_cst) noexcept
459  { return _M_b.fetch_add(__d, __m); }
460 
461  __pointer_type
462  fetch_add(ptrdiff_t __d,
463  memory_order __m = memory_order_seq_cst) volatile noexcept
464  { return _M_b.fetch_add(__d, __m); }
465 
466  __pointer_type
467  fetch_sub(ptrdiff_t __d,
468  memory_order __m = memory_order_seq_cst) noexcept
469  { return _M_b.fetch_sub(__d, __m); }
470 
471  __pointer_type
472  fetch_sub(ptrdiff_t __d,
473  memory_order __m = memory_order_seq_cst) volatile noexcept
474  { return _M_b.fetch_sub(__d, __m); }
475  };
476 
477 
478  /// Explicit specialization for bool.
479  template<>
480  struct atomic<bool> : public atomic_bool
481  {
482  typedef bool __integral_type;
483  typedef atomic_bool __base_type;
484 
485  atomic() noexcept = default;
486  ~atomic() noexcept = default;
487  atomic(const atomic&) = delete;
488  atomic& operator=(const atomic&) = delete;
489  atomic& operator=(const atomic&) volatile = delete;
490 
491  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
492 
493  using __base_type::operator __integral_type;
494  using __base_type::operator=;
495  };
496 
497  /// Explicit specialization for char.
498  template<>
499  struct atomic<char> : public atomic_char
500  {
501  typedef char __integral_type;
502  typedef atomic_char __base_type;
503 
504  atomic() noexcept = default;
505  ~atomic() noexcept = default;
506  atomic(const atomic&) = delete;
507  atomic& operator=(const atomic&) = delete;
508  atomic& operator=(const atomic&) volatile = delete;
509 
510  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
511 
512  using __base_type::operator __integral_type;
513  using __base_type::operator=;
514  };
515 
516  /// Explicit specialization for signed char.
517  template<>
518  struct atomic<signed char> : public atomic_schar
519  {
520  typedef signed char __integral_type;
521  typedef atomic_schar __base_type;
522 
523  atomic() noexcept= default;
524  ~atomic() noexcept = default;
525  atomic(const atomic&) = delete;
526  atomic& operator=(const atomic&) = delete;
527  atomic& operator=(const atomic&) volatile = delete;
528 
529  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
530 
531  using __base_type::operator __integral_type;
532  using __base_type::operator=;
533  };
534 
535  /// Explicit specialization for unsigned char.
536  template<>
537  struct atomic<unsigned char> : public atomic_uchar
538  {
539  typedef unsigned char __integral_type;
540  typedef atomic_uchar __base_type;
541 
542  atomic() noexcept= default;
543  ~atomic() noexcept = default;
544  atomic(const atomic&) = delete;
545  atomic& operator=(const atomic&) = delete;
546  atomic& operator=(const atomic&) volatile = delete;
547 
548  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
549 
550  using __base_type::operator __integral_type;
551  using __base_type::operator=;
552  };
553 
554  /// Explicit specialization for short.
555  template<>
556  struct atomic<short> : public atomic_short
557  {
558  typedef short __integral_type;
559  typedef atomic_short __base_type;
560 
561  atomic() noexcept = default;
562  ~atomic() noexcept = default;
563  atomic(const atomic&) = delete;
564  atomic& operator=(const atomic&) = delete;
565  atomic& operator=(const atomic&) volatile = delete;
566 
567  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
568 
569  using __base_type::operator __integral_type;
570  using __base_type::operator=;
571  };
572 
573  /// Explicit specialization for unsigned short.
574  template<>
575  struct atomic<unsigned short> : public atomic_ushort
576  {
577  typedef unsigned short __integral_type;
578  typedef atomic_ushort __base_type;
579 
580  atomic() noexcept = default;
581  ~atomic() noexcept = default;
582  atomic(const atomic&) = delete;
583  atomic& operator=(const atomic&) = delete;
584  atomic& operator=(const atomic&) volatile = delete;
585 
586  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
587 
588  using __base_type::operator __integral_type;
589  using __base_type::operator=;
590  };
591 
592  /// Explicit specialization for int.
593  template<>
594  struct atomic<int> : atomic_int
595  {
596  typedef int __integral_type;
597  typedef atomic_int __base_type;
598 
599  atomic() noexcept = default;
600  ~atomic() noexcept = default;
601  atomic(const atomic&) = delete;
602  atomic& operator=(const atomic&) = delete;
603  atomic& operator=(const atomic&) volatile = delete;
604 
605  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
606 
607  using __base_type::operator __integral_type;
608  using __base_type::operator=;
609  };
610 
611  /// Explicit specialization for unsigned int.
612  template<>
613  struct atomic<unsigned int> : public atomic_uint
614  {
615  typedef unsigned int __integral_type;
616  typedef atomic_uint __base_type;
617 
618  atomic() noexcept = default;
619  ~atomic() noexcept = default;
620  atomic(const atomic&) = delete;
621  atomic& operator=(const atomic&) = delete;
622  atomic& operator=(const atomic&) volatile = delete;
623 
624  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
625 
626  using __base_type::operator __integral_type;
627  using __base_type::operator=;
628  };
629 
630  /// Explicit specialization for long.
631  template<>
632  struct atomic<long> : public atomic_long
633  {
634  typedef long __integral_type;
635  typedef atomic_long __base_type;
636 
637  atomic() noexcept = default;
638  ~atomic() noexcept = default;
639  atomic(const atomic&) = delete;
640  atomic& operator=(const atomic&) = delete;
641  atomic& operator=(const atomic&) volatile = delete;
642 
643  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
644 
645  using __base_type::operator __integral_type;
646  using __base_type::operator=;
647  };
648 
649  /// Explicit specialization for unsigned long.
650  template<>
651  struct atomic<unsigned long> : public atomic_ulong
652  {
653  typedef unsigned long __integral_type;
654  typedef atomic_ulong __base_type;
655 
656  atomic() noexcept = default;
657  ~atomic() noexcept = default;
658  atomic(const atomic&) = delete;
659  atomic& operator=(const atomic&) = delete;
660  atomic& operator=(const atomic&) volatile = delete;
661 
662  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
663 
664  using __base_type::operator __integral_type;
665  using __base_type::operator=;
666  };
667 
668  /// Explicit specialization for long long.
669  template<>
670  struct atomic<long long> : public atomic_llong
671  {
672  typedef long long __integral_type;
673  typedef atomic_llong __base_type;
674 
675  atomic() noexcept = default;
676  ~atomic() noexcept = default;
677  atomic(const atomic&) = delete;
678  atomic& operator=(const atomic&) = delete;
679  atomic& operator=(const atomic&) volatile = delete;
680 
681  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
682 
683  using __base_type::operator __integral_type;
684  using __base_type::operator=;
685  };
686 
687  /// Explicit specialization for unsigned long long.
688  template<>
689  struct atomic<unsigned long long> : public atomic_ullong
690  {
691  typedef unsigned long long __integral_type;
692  typedef atomic_ullong __base_type;
693 
694  atomic() noexcept = default;
695  ~atomic() noexcept = default;
696  atomic(const atomic&) = delete;
697  atomic& operator=(const atomic&) = delete;
698  atomic& operator=(const atomic&) volatile = delete;
699 
700  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
701 
702  using __base_type::operator __integral_type;
703  using __base_type::operator=;
704  };
705 
706  /// Explicit specialization for wchar_t.
707  template<>
708  struct atomic<wchar_t> : public atomic_wchar_t
709  {
710  typedef wchar_t __integral_type;
711  typedef atomic_wchar_t __base_type;
712 
713  atomic() noexcept = default;
714  ~atomic() noexcept = default;
715  atomic(const atomic&) = delete;
716  atomic& operator=(const atomic&) = delete;
717  atomic& operator=(const atomic&) volatile = delete;
718 
719  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
720 
721  using __base_type::operator __integral_type;
722  using __base_type::operator=;
723  };
724 
725  /// Explicit specialization for char16_t.
726  template<>
727  struct atomic<char16_t> : public atomic_char16_t
728  {
729  typedef char16_t __integral_type;
730  typedef atomic_char16_t __base_type;
731 
732  atomic() noexcept = default;
733  ~atomic() noexcept = default;
734  atomic(const atomic&) = delete;
735  atomic& operator=(const atomic&) = delete;
736  atomic& operator=(const atomic&) volatile = delete;
737 
738  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
739 
740  using __base_type::operator __integral_type;
741  using __base_type::operator=;
742  };
743 
744  /// Explicit specialization for char32_t.
745  template<>
746  struct atomic<char32_t> : public atomic_char32_t
747  {
748  typedef char32_t __integral_type;
749  typedef atomic_char32_t __base_type;
750 
751  atomic() noexcept = default;
752  ~atomic() noexcept = default;
753  atomic(const atomic&) = delete;
754  atomic& operator=(const atomic&) = delete;
755  atomic& operator=(const atomic&) volatile = delete;
756 
757  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
758 
759  using __base_type::operator __integral_type;
760  using __base_type::operator=;
761  };
762 
763 
764  // Function definitions, atomic_flag operations.
765  inline bool
766  atomic_flag_test_and_set_explicit(atomic_flag* __a,
767  memory_order __m) noexcept
768  { return __a->test_and_set(__m); }
769 
770  inline bool
771  atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
772  memory_order __m) noexcept
773  { return __a->test_and_set(__m); }
774 
775  inline void
776  atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
777  { __a->clear(__m); }
778 
779  inline void
780  atomic_flag_clear_explicit(volatile atomic_flag* __a,
781  memory_order __m) noexcept
782  { __a->clear(__m); }
783 
784  inline bool
785  atomic_flag_test_and_set(atomic_flag* __a) noexcept
786  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
787 
788  inline bool
789  atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
790  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
791 
792  inline void
793  atomic_flag_clear(atomic_flag* __a) noexcept
794  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
795 
796  inline void
797  atomic_flag_clear(volatile atomic_flag* __a) noexcept
798  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
799 
800 
801  // Function templates generally applicable to atomic types.
802  template<typename _ITp>
803  inline bool
804  atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
805  { return __a->is_lock_free(); }
806 
807  template<typename _ITp>
808  inline bool
809  atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
810  { return __a->is_lock_free(); }
811 
812  template<typename _ITp>
813  inline void
814  atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
815 
816  template<typename _ITp>
817  inline void
818  atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
819 
820  template<typename _ITp>
821  inline void
822  atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
823  memory_order __m) noexcept
824  { __a->store(__i, __m); }
825 
826  template<typename _ITp>
827  inline void
828  atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
829  memory_order __m) noexcept
830  { __a->store(__i, __m); }
831 
832  template<typename _ITp>
833  inline _ITp
834  atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
835  { return __a->load(__m); }
836 
837  template<typename _ITp>
838  inline _ITp
839  atomic_load_explicit(const volatile atomic<_ITp>* __a,
840  memory_order __m) noexcept
841  { return __a->load(__m); }
842 
843  template<typename _ITp>
844  inline _ITp
845  atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
846  memory_order __m) noexcept
847  { return __a->exchange(__i, __m); }
848 
849  template<typename _ITp>
850  inline _ITp
851  atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
852  memory_order __m) noexcept
853  { return __a->exchange(__i, __m); }
854 
855  template<typename _ITp>
856  inline bool
857  atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
858  _ITp* __i1, _ITp __i2,
859  memory_order __m1,
860  memory_order __m2) noexcept
861  { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
862 
863  template<typename _ITp>
864  inline bool
865  atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
866  _ITp* __i1, _ITp __i2,
867  memory_order __m1,
868  memory_order __m2) noexcept
869  { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
870 
871  template<typename _ITp>
872  inline bool
873  atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
874  _ITp* __i1, _ITp __i2,
875  memory_order __m1,
876  memory_order __m2) noexcept
877  { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
878 
879  template<typename _ITp>
880  inline bool
881  atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
882  _ITp* __i1, _ITp __i2,
883  memory_order __m1,
884  memory_order __m2) noexcept
885  { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
886 
887 
888  template<typename _ITp>
889  inline void
890  atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
891  { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
892 
893  template<typename _ITp>
894  inline void
895  atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
896  { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
897 
898  template<typename _ITp>
899  inline _ITp
900  atomic_load(const atomic<_ITp>* __a) noexcept
901  { return atomic_load_explicit(__a, memory_order_seq_cst); }
902 
903  template<typename _ITp>
904  inline _ITp
905  atomic_load(const volatile atomic<_ITp>* __a) noexcept
906  { return atomic_load_explicit(__a, memory_order_seq_cst); }
907 
908  template<typename _ITp>
909  inline _ITp
910  atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
911  { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
912 
913  template<typename _ITp>
914  inline _ITp
915  atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
916  { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
917 
918  template<typename _ITp>
919  inline bool
920  atomic_compare_exchange_weak(atomic<_ITp>* __a,
921  _ITp* __i1, _ITp __i2) noexcept
922  {
923  return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
924  memory_order_seq_cst,
925  memory_order_seq_cst);
926  }
927 
928  template<typename _ITp>
929  inline bool
930  atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
931  _ITp* __i1, _ITp __i2) noexcept
932  {
933  return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
934  memory_order_seq_cst,
935  memory_order_seq_cst);
936  }
937 
938  template<typename _ITp>
939  inline bool
940  atomic_compare_exchange_strong(atomic<_ITp>* __a,
941  _ITp* __i1, _ITp __i2) noexcept
942  {
943  return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
944  memory_order_seq_cst,
945  memory_order_seq_cst);
946  }
947 
948  template<typename _ITp>
949  inline bool
950  atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
951  _ITp* __i1, _ITp __i2) noexcept
952  {
953  return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
954  memory_order_seq_cst,
955  memory_order_seq_cst);
956  }
957 
958  // Function templates for atomic_integral operations only, using
959  // __atomic_base. Template argument should be constricted to
960  // intergral types as specified in the standard, excluding address
961  // types.
962  template<typename _ITp>
963  inline _ITp
964  atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
965  memory_order __m) noexcept
966  { return __a->fetch_add(__i, __m); }
967 
968  template<typename _ITp>
969  inline _ITp
970  atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
971  memory_order __m) noexcept
972  { return __a->fetch_add(__i, __m); }
973 
974  template<typename _ITp>
975  inline _ITp
976  atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
977  memory_order __m) noexcept
978  { return __a->fetch_sub(__i, __m); }
979 
980  template<typename _ITp>
981  inline _ITp
982  atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
983  memory_order __m) noexcept
984  { return __a->fetch_sub(__i, __m); }
985 
986  template<typename _ITp>
987  inline _ITp
988  atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
989  memory_order __m) noexcept
990  { return __a->fetch_and(__i, __m); }
991 
992  template<typename _ITp>
993  inline _ITp
994  atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
995  memory_order __m) noexcept
996  { return __a->fetch_and(__i, __m); }
997 
998  template<typename _ITp>
999  inline _ITp
1000  atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1001  memory_order __m) noexcept
1002  { return __a->fetch_or(__i, __m); }
1003 
1004  template<typename _ITp>
1005  inline _ITp
1006  atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1007  memory_order __m) noexcept
1008  { return __a->fetch_or(__i, __m); }
1009 
1010  template<typename _ITp>
1011  inline _ITp
1012  atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1013  memory_order __m) noexcept
1014  { return __a->fetch_xor(__i, __m); }
1015 
1016  template<typename _ITp>
1017  inline _ITp
1018  atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1019  memory_order __m) noexcept
1020  { return __a->fetch_xor(__i, __m); }
1021 
1022  template<typename _ITp>
1023  inline _ITp
1024  atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1025  { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1026 
1027  template<typename _ITp>
1028  inline _ITp
1029  atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1030  { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1031 
1032  template<typename _ITp>
1033  inline _ITp
1034  atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1035  { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1036 
1037  template<typename _ITp>
1038  inline _ITp
1039  atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1040  { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1041 
1042  template<typename _ITp>
1043  inline _ITp
1044  atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1045  { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1046 
1047  template<typename _ITp>
1048  inline _ITp
1049  atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1050  { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1051 
1052  template<typename _ITp>
1053  inline _ITp
1054  atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1055  { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1056 
1057  template<typename _ITp>
1058  inline _ITp
1059  atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1060  { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1061 
1062  template<typename _ITp>
1063  inline _ITp
1064  atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1065  { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1066 
1067  template<typename _ITp>
1068  inline _ITp
1069  atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1070  { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1071 
1072 
1073  // Partial specializations for pointers.
1074  template<typename _ITp>
1075  inline _ITp*
1076  atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1077  memory_order __m) noexcept
1078  { return __a->fetch_add(__d, __m); }
1079 
1080  template<typename _ITp>
1081  inline _ITp*
1082  atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1083  memory_order __m) noexcept
1084  { return __a->fetch_add(__d, __m); }
1085 
1086  template<typename _ITp>
1087  inline _ITp*
1088  atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1089  { return __a->fetch_add(__d); }
1090 
1091  template<typename _ITp>
1092  inline _ITp*
1093  atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1094  { return __a->fetch_add(__d); }
1095 
1096  template<typename _ITp>
1097  inline _ITp*
1098  atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1099  ptrdiff_t __d, memory_order __m) noexcept
1100  { return __a->fetch_sub(__d, __m); }
1101 
1102  template<typename _ITp>
1103  inline _ITp*
1104  atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1105  memory_order __m) noexcept
1106  { return __a->fetch_sub(__d, __m); }
1107 
1108  template<typename _ITp>
1109  inline _ITp*
1110  atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1111  { return __a->fetch_sub(__d); }
1112 
1113  template<typename _ITp>
1114  inline _ITp*
1115  atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1116  { return __a->fetch_sub(__d); }
1117  // @} group atomics
1118 
1119 _GLIBCXX_END_NAMESPACE_VERSION
1120 } // namespace
1121 
1122 #endif