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