libstdc++
atomic
Go to the documentation of this file.
1 // -*- C++ -*- header.
2 
3 // Copyright (C) 2008-2015 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 #else
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  template<typename _Tp>
53  struct atomic;
54 
55  /// atomic<bool>
56  // NB: No operators or fetch-operations for this type.
57  template<>
58  struct atomic<bool>
59  {
60  private:
61  __atomic_base<bool> _M_base;
62 
63  public:
64  atomic() noexcept = default;
65  ~atomic() noexcept = default;
66  atomic(const atomic&) = delete;
67  atomic& operator=(const atomic&) = delete;
68  atomic& operator=(const atomic&) volatile = delete;
69 
70  constexpr atomic(bool __i) noexcept : _M_base(__i) { }
71 
72  bool
73  operator=(bool __i) noexcept
74  { return _M_base.operator=(__i); }
75 
76  bool
77  operator=(bool __i) volatile noexcept
78  { return _M_base.operator=(__i); }
79 
80  operator bool() const noexcept
81  { return _M_base.load(); }
82 
83  operator bool() const volatile noexcept
84  { return _M_base.load(); }
85 
86  bool
87  is_lock_free() const noexcept { return _M_base.is_lock_free(); }
88 
89  bool
90  is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
91 
92  void
93  store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
94  { _M_base.store(__i, __m); }
95 
96  void
97  store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
98  { _M_base.store(__i, __m); }
99 
100  bool
101  load(memory_order __m = memory_order_seq_cst) const noexcept
102  { return _M_base.load(__m); }
103 
104  bool
105  load(memory_order __m = memory_order_seq_cst) const volatile noexcept
106  { return _M_base.load(__m); }
107 
108  bool
109  exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
110  { return _M_base.exchange(__i, __m); }
111 
112  bool
113  exchange(bool __i,
114  memory_order __m = memory_order_seq_cst) volatile noexcept
115  { return _M_base.exchange(__i, __m); }
116 
117  bool
118  compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
119  memory_order __m2) noexcept
120  { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
121 
122  bool
123  compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
124  memory_order __m2) volatile noexcept
125  { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
126 
127  bool
128  compare_exchange_weak(bool& __i1, bool __i2,
129  memory_order __m = memory_order_seq_cst) noexcept
130  { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
131 
132  bool
133  compare_exchange_weak(bool& __i1, bool __i2,
134  memory_order __m = memory_order_seq_cst) volatile noexcept
135  { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
136 
137  bool
138  compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
139  memory_order __m2) noexcept
140  { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
141 
142  bool
143  compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
144  memory_order __m2) volatile noexcept
145  { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
146 
147  bool
148  compare_exchange_strong(bool& __i1, bool __i2,
149  memory_order __m = memory_order_seq_cst) noexcept
150  { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
151 
152  bool
153  compare_exchange_strong(bool& __i1, bool __i2,
154  memory_order __m = memory_order_seq_cst) volatile noexcept
155  { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
156  };
157 
158 
159  /**
160  * @brief Generic atomic type, primary class template.
161  *
162  * @tparam _Tp Type to be made atomic, must be trivally copyable.
163  */
164  template<typename _Tp>
165  struct atomic
166  {
167  private:
168  // Align 1/2/4/8/16-byte types to at least their size.
169  static constexpr int _S_min_alignment
170  = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
171  ? 0 : sizeof(_Tp);
172 
173  static constexpr int _S_alignment
174  = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
175 
176  alignas(_S_alignment) _Tp _M_i;
177 
178  static_assert(__is_trivially_copyable(_Tp),
179  "std::atomic requires a trivially copyable type");
180 
181  static_assert(sizeof(_Tp) > 0,
182  "Incomplete or zero-sized types are not supported");
183 
184  public:
185  atomic() noexcept = default;
186  ~atomic() noexcept = default;
187  atomic(const atomic&) = delete;
188  atomic& operator=(const atomic&) = delete;
189  atomic& operator=(const atomic&) volatile = delete;
190 
191  constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
192 
193  operator _Tp() const noexcept
194  { return load(); }
195 
196  operator _Tp() const volatile noexcept
197  { return load(); }
198 
199  _Tp
200  operator=(_Tp __i) noexcept
201  { store(__i); return __i; }
202 
203  _Tp
204  operator=(_Tp __i) volatile noexcept
205  { store(__i); return __i; }
206 
207  bool
208  is_lock_free() const noexcept
209  {
210  // Produce a fake, minimally aligned pointer.
211  return __atomic_is_lock_free(sizeof(_M_i),
212  reinterpret_cast<void *>(-__alignof(_M_i)));
213  }
214 
215  bool
216  is_lock_free() const volatile noexcept
217  {
218  // Produce a fake, minimally aligned pointer.
219  return __atomic_is_lock_free(sizeof(_M_i),
220  reinterpret_cast<void *>(-__alignof(_M_i)));
221  }
222 
223  void
224  store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
225  { __atomic_store(&_M_i, &__i, __m); }
226 
227  void
228  store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
229  { __atomic_store(&_M_i, &__i, __m); }
230 
231  _Tp
232  load(memory_order __m = memory_order_seq_cst) const noexcept
233  {
234  alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
235  _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
236  __atomic_load(&_M_i, __ptr, __m);
237  return *__ptr;
238  }
239 
240  _Tp
241  load(memory_order __m = memory_order_seq_cst) const volatile noexcept
242  {
243  alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
244  _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
245  __atomic_load(&_M_i, __ptr, __m);
246  return *__ptr;
247  }
248 
249  _Tp
250  exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
251  {
252  alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
253  _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
254  __atomic_exchange(&_M_i, &__i, __ptr, __m);
255  return *__ptr;
256  }
257 
258  _Tp
259  exchange(_Tp __i,
260  memory_order __m = memory_order_seq_cst) volatile noexcept
261  {
262  alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
263  _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
264  __atomic_exchange(&_M_i, &__i, __ptr, __m);
265  return *__ptr;
266  }
267 
268  bool
269  compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
270  memory_order __f) noexcept
271  {
272  return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
273  }
274 
275  bool
276  compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
277  memory_order __f) volatile noexcept
278  {
279  return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
280  }
281 
282  bool
283  compare_exchange_weak(_Tp& __e, _Tp __i,
284  memory_order __m = memory_order_seq_cst) noexcept
285  { return compare_exchange_weak(__e, __i, __m,
286  __cmpexch_failure_order(__m)); }
287 
288  bool
289  compare_exchange_weak(_Tp& __e, _Tp __i,
290  memory_order __m = memory_order_seq_cst) volatile noexcept
291  { return compare_exchange_weak(__e, __i, __m,
292  __cmpexch_failure_order(__m)); }
293 
294  bool
295  compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
296  memory_order __f) noexcept
297  {
298  return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
299  }
300 
301  bool
302  compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
303  memory_order __f) volatile noexcept
304  {
305  return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
306  }
307 
308  bool
309  compare_exchange_strong(_Tp& __e, _Tp __i,
310  memory_order __m = memory_order_seq_cst) noexcept
311  { return compare_exchange_strong(__e, __i, __m,
312  __cmpexch_failure_order(__m)); }
313 
314  bool
315  compare_exchange_strong(_Tp& __e, _Tp __i,
316  memory_order __m = memory_order_seq_cst) volatile noexcept
317  { return compare_exchange_strong(__e, __i, __m,
318  __cmpexch_failure_order(__m)); }
319  };
320 
321 
322  /// Partial specialization for pointer types.
323  template<typename _Tp>
324  struct atomic<_Tp*>
325  {
326  typedef _Tp* __pointer_type;
327  typedef __atomic_base<_Tp*> __base_type;
328  __base_type _M_b;
329 
330  atomic() noexcept = default;
331  ~atomic() noexcept = default;
332  atomic(const atomic&) = delete;
333  atomic& operator=(const atomic&) = delete;
334  atomic& operator=(const atomic&) volatile = delete;
335 
336  constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
337 
338  operator __pointer_type() const noexcept
339  { return __pointer_type(_M_b); }
340 
341  operator __pointer_type() const volatile noexcept
342  { return __pointer_type(_M_b); }
343 
344  __pointer_type
345  operator=(__pointer_type __p) noexcept
346  { return _M_b.operator=(__p); }
347 
348  __pointer_type
349  operator=(__pointer_type __p) volatile noexcept
350  { return _M_b.operator=(__p); }
351 
352  __pointer_type
353  operator++(int) noexcept
354  { return _M_b++; }
355 
356  __pointer_type
357  operator++(int) volatile noexcept
358  { return _M_b++; }
359 
360  __pointer_type
361  operator--(int) noexcept
362  { return _M_b--; }
363 
364  __pointer_type
365  operator--(int) volatile noexcept
366  { return _M_b--; }
367 
368  __pointer_type
369  operator++() noexcept
370  { return ++_M_b; }
371 
372  __pointer_type
373  operator++() volatile noexcept
374  { return ++_M_b; }
375 
376  __pointer_type
377  operator--() noexcept
378  { return --_M_b; }
379 
380  __pointer_type
381  operator--() volatile noexcept
382  { return --_M_b; }
383 
384  __pointer_type
385  operator+=(ptrdiff_t __d) noexcept
386  { return _M_b.operator+=(__d); }
387 
388  __pointer_type
389  operator+=(ptrdiff_t __d) volatile noexcept
390  { return _M_b.operator+=(__d); }
391 
392  __pointer_type
393  operator-=(ptrdiff_t __d) noexcept
394  { return _M_b.operator-=(__d); }
395 
396  __pointer_type
397  operator-=(ptrdiff_t __d) volatile noexcept
398  { return _M_b.operator-=(__d); }
399 
400  bool
401  is_lock_free() const noexcept
402  { return _M_b.is_lock_free(); }
403 
404  bool
405  is_lock_free() const volatile noexcept
406  { return _M_b.is_lock_free(); }
407 
408  void
409  store(__pointer_type __p,
410  memory_order __m = memory_order_seq_cst) noexcept
411  { return _M_b.store(__p, __m); }
412 
413  void
414  store(__pointer_type __p,
415  memory_order __m = memory_order_seq_cst) volatile noexcept
416  { return _M_b.store(__p, __m); }
417 
418  __pointer_type
419  load(memory_order __m = memory_order_seq_cst) const noexcept
420  { return _M_b.load(__m); }
421 
422  __pointer_type
423  load(memory_order __m = memory_order_seq_cst) const volatile noexcept
424  { return _M_b.load(__m); }
425 
426  __pointer_type
427  exchange(__pointer_type __p,
428  memory_order __m = memory_order_seq_cst) noexcept
429  { return _M_b.exchange(__p, __m); }
430 
431  __pointer_type
432  exchange(__pointer_type __p,
433  memory_order __m = memory_order_seq_cst) volatile noexcept
434  { return _M_b.exchange(__p, __m); }
435 
436  bool
437  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
438  memory_order __m1, memory_order __m2) noexcept
439  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
440 
441  bool
442  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
443  memory_order __m1,
444  memory_order __m2) volatile noexcept
445  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
446 
447  bool
448  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
449  memory_order __m = memory_order_seq_cst) noexcept
450  {
451  return compare_exchange_weak(__p1, __p2, __m,
452  __cmpexch_failure_order(__m));
453  }
454 
455  bool
456  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
457  memory_order __m = memory_order_seq_cst) volatile noexcept
458  {
459  return compare_exchange_weak(__p1, __p2, __m,
460  __cmpexch_failure_order(__m));
461  }
462 
463  bool
464  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
465  memory_order __m1, memory_order __m2) noexcept
466  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
467 
468  bool
469  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
470  memory_order __m1,
471  memory_order __m2) volatile noexcept
472  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
473 
474  bool
475  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
476  memory_order __m = memory_order_seq_cst) noexcept
477  {
478  return _M_b.compare_exchange_strong(__p1, __p2, __m,
479  __cmpexch_failure_order(__m));
480  }
481 
482  bool
483  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
484  memory_order __m = memory_order_seq_cst) volatile noexcept
485  {
486  return _M_b.compare_exchange_strong(__p1, __p2, __m,
487  __cmpexch_failure_order(__m));
488  }
489 
490  __pointer_type
491  fetch_add(ptrdiff_t __d,
492  memory_order __m = memory_order_seq_cst) noexcept
493  { return _M_b.fetch_add(__d, __m); }
494 
495  __pointer_type
496  fetch_add(ptrdiff_t __d,
497  memory_order __m = memory_order_seq_cst) volatile noexcept
498  { return _M_b.fetch_add(__d, __m); }
499 
500  __pointer_type
501  fetch_sub(ptrdiff_t __d,
502  memory_order __m = memory_order_seq_cst) noexcept
503  { return _M_b.fetch_sub(__d, __m); }
504 
505  __pointer_type
506  fetch_sub(ptrdiff_t __d,
507  memory_order __m = memory_order_seq_cst) volatile noexcept
508  { return _M_b.fetch_sub(__d, __m); }
509  };
510 
511 
512  /// Explicit specialization for char.
513  template<>
514  struct atomic<char> : __atomic_base<char>
515  {
516  typedef char __integral_type;
517  typedef __atomic_base<char> __base_type;
518 
519  atomic() noexcept = default;
520  ~atomic() noexcept = default;
521  atomic(const atomic&) = delete;
522  atomic& operator=(const atomic&) = delete;
523  atomic& operator=(const atomic&) volatile = delete;
524 
525  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
526 
527  using __base_type::operator __integral_type;
528  using __base_type::operator=;
529  };
530 
531  /// Explicit specialization for signed char.
532  template<>
533  struct atomic<signed char> : __atomic_base<signed char>
534  {
535  typedef signed char __integral_type;
536  typedef __atomic_base<signed char> __base_type;
537 
538  atomic() noexcept= default;
539  ~atomic() noexcept = default;
540  atomic(const atomic&) = delete;
541  atomic& operator=(const atomic&) = delete;
542  atomic& operator=(const atomic&) volatile = delete;
543 
544  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
545 
546  using __base_type::operator __integral_type;
547  using __base_type::operator=;
548  };
549 
550  /// Explicit specialization for unsigned char.
551  template<>
552  struct atomic<unsigned char> : __atomic_base<unsigned char>
553  {
554  typedef unsigned char __integral_type;
555  typedef __atomic_base<unsigned char> __base_type;
556 
557  atomic() noexcept= default;
558  ~atomic() noexcept = default;
559  atomic(const atomic&) = delete;
560  atomic& operator=(const atomic&) = delete;
561  atomic& operator=(const atomic&) volatile = delete;
562 
563  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
564 
565  using __base_type::operator __integral_type;
566  using __base_type::operator=;
567  };
568 
569  /// Explicit specialization for short.
570  template<>
571  struct atomic<short> : __atomic_base<short>
572  {
573  typedef short __integral_type;
574  typedef __atomic_base<short> __base_type;
575 
576  atomic() noexcept = default;
577  ~atomic() noexcept = default;
578  atomic(const atomic&) = delete;
579  atomic& operator=(const atomic&) = delete;
580  atomic& operator=(const atomic&) volatile = delete;
581 
582  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
583 
584  using __base_type::operator __integral_type;
585  using __base_type::operator=;
586  };
587 
588  /// Explicit specialization for unsigned short.
589  template<>
590  struct atomic<unsigned short> : __atomic_base<unsigned short>
591  {
592  typedef unsigned short __integral_type;
593  typedef __atomic_base<unsigned short> __base_type;
594 
595  atomic() noexcept = default;
596  ~atomic() noexcept = default;
597  atomic(const atomic&) = delete;
598  atomic& operator=(const atomic&) = delete;
599  atomic& operator=(const atomic&) volatile = delete;
600 
601  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
602 
603  using __base_type::operator __integral_type;
604  using __base_type::operator=;
605  };
606 
607  /// Explicit specialization for int.
608  template<>
609  struct atomic<int> : __atomic_base<int>
610  {
611  typedef int __integral_type;
612  typedef __atomic_base<int> __base_type;
613 
614  atomic() noexcept = default;
615  ~atomic() noexcept = default;
616  atomic(const atomic&) = delete;
617  atomic& operator=(const atomic&) = delete;
618  atomic& operator=(const atomic&) volatile = delete;
619 
620  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
621 
622  using __base_type::operator __integral_type;
623  using __base_type::operator=;
624  };
625 
626  /// Explicit specialization for unsigned int.
627  template<>
628  struct atomic<unsigned int> : __atomic_base<unsigned int>
629  {
630  typedef unsigned int __integral_type;
631  typedef __atomic_base<unsigned int> __base_type;
632 
633  atomic() noexcept = default;
634  ~atomic() noexcept = default;
635  atomic(const atomic&) = delete;
636  atomic& operator=(const atomic&) = delete;
637  atomic& operator=(const atomic&) volatile = delete;
638 
639  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
640 
641  using __base_type::operator __integral_type;
642  using __base_type::operator=;
643  };
644 
645  /// Explicit specialization for long.
646  template<>
647  struct atomic<long> : __atomic_base<long>
648  {
649  typedef long __integral_type;
650  typedef __atomic_base<long> __base_type;
651 
652  atomic() noexcept = default;
653  ~atomic() noexcept = default;
654  atomic(const atomic&) = delete;
655  atomic& operator=(const atomic&) = delete;
656  atomic& operator=(const atomic&) volatile = delete;
657 
658  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
659 
660  using __base_type::operator __integral_type;
661  using __base_type::operator=;
662  };
663 
664  /// Explicit specialization for unsigned long.
665  template<>
666  struct atomic<unsigned long> : __atomic_base<unsigned long>
667  {
668  typedef unsigned long __integral_type;
669  typedef __atomic_base<unsigned long> __base_type;
670 
671  atomic() noexcept = default;
672  ~atomic() noexcept = default;
673  atomic(const atomic&) = delete;
674  atomic& operator=(const atomic&) = delete;
675  atomic& operator=(const atomic&) volatile = delete;
676 
677  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
678 
679  using __base_type::operator __integral_type;
680  using __base_type::operator=;
681  };
682 
683  /// Explicit specialization for long long.
684  template<>
685  struct atomic<long long> : __atomic_base<long long>
686  {
687  typedef long long __integral_type;
688  typedef __atomic_base<long long> __base_type;
689 
690  atomic() noexcept = default;
691  ~atomic() noexcept = default;
692  atomic(const atomic&) = delete;
693  atomic& operator=(const atomic&) = delete;
694  atomic& operator=(const atomic&) volatile = delete;
695 
696  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
697 
698  using __base_type::operator __integral_type;
699  using __base_type::operator=;
700  };
701 
702  /// Explicit specialization for unsigned long long.
703  template<>
704  struct atomic<unsigned long long> : __atomic_base<unsigned long long>
705  {
706  typedef unsigned long long __integral_type;
707  typedef __atomic_base<unsigned long long> __base_type;
708 
709  atomic() noexcept = default;
710  ~atomic() noexcept = default;
711  atomic(const atomic&) = delete;
712  atomic& operator=(const atomic&) = delete;
713  atomic& operator=(const atomic&) volatile = delete;
714 
715  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
716 
717  using __base_type::operator __integral_type;
718  using __base_type::operator=;
719  };
720 
721  /// Explicit specialization for wchar_t.
722  template<>
723  struct atomic<wchar_t> : __atomic_base<wchar_t>
724  {
725  typedef wchar_t __integral_type;
726  typedef __atomic_base<wchar_t> __base_type;
727 
728  atomic() noexcept = default;
729  ~atomic() noexcept = default;
730  atomic(const atomic&) = delete;
731  atomic& operator=(const atomic&) = delete;
732  atomic& operator=(const atomic&) volatile = delete;
733 
734  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
735 
736  using __base_type::operator __integral_type;
737  using __base_type::operator=;
738  };
739 
740  /// Explicit specialization for char16_t.
741  template<>
742  struct atomic<char16_t> : __atomic_base<char16_t>
743  {
744  typedef char16_t __integral_type;
745  typedef __atomic_base<char16_t> __base_type;
746 
747  atomic() noexcept = default;
748  ~atomic() noexcept = default;
749  atomic(const atomic&) = delete;
750  atomic& operator=(const atomic&) = delete;
751  atomic& operator=(const atomic&) volatile = delete;
752 
753  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
754 
755  using __base_type::operator __integral_type;
756  using __base_type::operator=;
757  };
758 
759  /// Explicit specialization for char32_t.
760  template<>
761  struct atomic<char32_t> : __atomic_base<char32_t>
762  {
763  typedef char32_t __integral_type;
764  typedef __atomic_base<char32_t> __base_type;
765 
766  atomic() noexcept = default;
767  ~atomic() noexcept = default;
768  atomic(const atomic&) = delete;
769  atomic& operator=(const atomic&) = delete;
770  atomic& operator=(const atomic&) volatile = delete;
771 
772  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
773 
774  using __base_type::operator __integral_type;
775  using __base_type::operator=;
776  };
777 
778 
779  /// atomic_bool
780  typedef atomic<bool> atomic_bool;
781 
782  /// atomic_char
783  typedef atomic<char> atomic_char;
784 
785  /// atomic_schar
786  typedef atomic<signed char> atomic_schar;
787 
788  /// atomic_uchar
789  typedef atomic<unsigned char> atomic_uchar;
790 
791  /// atomic_short
792  typedef atomic<short> atomic_short;
793 
794  /// atomic_ushort
795  typedef atomic<unsigned short> atomic_ushort;
796 
797  /// atomic_int
798  typedef atomic<int> atomic_int;
799 
800  /// atomic_uint
801  typedef atomic<unsigned int> atomic_uint;
802 
803  /// atomic_long
804  typedef atomic<long> atomic_long;
805 
806  /// atomic_ulong
807  typedef atomic<unsigned long> atomic_ulong;
808 
809  /// atomic_llong
810  typedef atomic<long long> atomic_llong;
811 
812  /// atomic_ullong
813  typedef atomic<unsigned long long> atomic_ullong;
814 
815  /// atomic_wchar_t
816  typedef atomic<wchar_t> atomic_wchar_t;
817 
818  /// atomic_char16_t
819  typedef atomic<char16_t> atomic_char16_t;
820 
821  /// atomic_char32_t
822  typedef atomic<char32_t> atomic_char32_t;
823 
824 
825  /// atomic_int_least8_t
826  typedef atomic<int_least8_t> atomic_int_least8_t;
827 
828  /// atomic_uint_least8_t
829  typedef atomic<uint_least8_t> atomic_uint_least8_t;
830 
831  /// atomic_int_least16_t
832  typedef atomic<int_least16_t> atomic_int_least16_t;
833 
834  /// atomic_uint_least16_t
835  typedef atomic<uint_least16_t> atomic_uint_least16_t;
836 
837  /// atomic_int_least32_t
838  typedef atomic<int_least32_t> atomic_int_least32_t;
839 
840  /// atomic_uint_least32_t
841  typedef atomic<uint_least32_t> atomic_uint_least32_t;
842 
843  /// atomic_int_least64_t
844  typedef atomic<int_least64_t> atomic_int_least64_t;
845 
846  /// atomic_uint_least64_t
847  typedef atomic<uint_least64_t> atomic_uint_least64_t;
848 
849 
850  /// atomic_int_fast8_t
851  typedef atomic<int_fast8_t> atomic_int_fast8_t;
852 
853  /// atomic_uint_fast8_t
854  typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
855 
856  /// atomic_int_fast16_t
857  typedef atomic<int_fast16_t> atomic_int_fast16_t;
858 
859  /// atomic_uint_fast16_t
860  typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
861 
862  /// atomic_int_fast32_t
863  typedef atomic<int_fast32_t> atomic_int_fast32_t;
864 
865  /// atomic_uint_fast32_t
866  typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
867 
868  /// atomic_int_fast64_t
869  typedef atomic<int_fast64_t> atomic_int_fast64_t;
870 
871  /// atomic_uint_fast64_t
872  typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
873 
874 
875  /// atomic_intptr_t
876  typedef atomic<intptr_t> atomic_intptr_t;
877 
878  /// atomic_uintptr_t
879  typedef atomic<uintptr_t> atomic_uintptr_t;
880 
881  /// atomic_size_t
882  typedef atomic<size_t> atomic_size_t;
883 
884  /// atomic_intmax_t
885  typedef atomic<intmax_t> atomic_intmax_t;
886 
887  /// atomic_uintmax_t
888  typedef atomic<uintmax_t> atomic_uintmax_t;
889 
890  /// atomic_ptrdiff_t
891  typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
892 
893 
894  // Function definitions, atomic_flag operations.
895  inline bool
896  atomic_flag_test_and_set_explicit(atomic_flag* __a,
897  memory_order __m) noexcept
898  { return __a->test_and_set(__m); }
899 
900  inline bool
901  atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
902  memory_order __m) noexcept
903  { return __a->test_and_set(__m); }
904 
905  inline void
906  atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
907  { __a->clear(__m); }
908 
909  inline void
910  atomic_flag_clear_explicit(volatile atomic_flag* __a,
911  memory_order __m) noexcept
912  { __a->clear(__m); }
913 
914  inline bool
915  atomic_flag_test_and_set(atomic_flag* __a) noexcept
916  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
917 
918  inline bool
919  atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
920  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
921 
922  inline void
923  atomic_flag_clear(atomic_flag* __a) noexcept
924  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
925 
926  inline void
927  atomic_flag_clear(volatile atomic_flag* __a) noexcept
928  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
929 
930 
931  // Function templates generally applicable to atomic types.
932  template<typename _ITp>
933  inline bool
934  atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
935  { return __a->is_lock_free(); }
936 
937  template<typename _ITp>
938  inline bool
939  atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
940  { return __a->is_lock_free(); }
941 
942  template<typename _ITp>
943  inline void
944  atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept
945  { __a->store(__i, memory_order_relaxed); }
946 
947  template<typename _ITp>
948  inline void
949  atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept
950  { __a->store(__i, memory_order_relaxed); }
951 
952  template<typename _ITp>
953  inline void
954  atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
955  memory_order __m) noexcept
956  { __a->store(__i, __m); }
957 
958  template<typename _ITp>
959  inline void
960  atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
961  memory_order __m) noexcept
962  { __a->store(__i, __m); }
963 
964  template<typename _ITp>
965  inline _ITp
966  atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
967  { return __a->load(__m); }
968 
969  template<typename _ITp>
970  inline _ITp
971  atomic_load_explicit(const volatile atomic<_ITp>* __a,
972  memory_order __m) noexcept
973  { return __a->load(__m); }
974 
975  template<typename _ITp>
976  inline _ITp
977  atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
978  memory_order __m) noexcept
979  { return __a->exchange(__i, __m); }
980 
981  template<typename _ITp>
982  inline _ITp
983  atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
984  memory_order __m) noexcept
985  { return __a->exchange(__i, __m); }
986 
987  template<typename _ITp>
988  inline bool
989  atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
990  _ITp* __i1, _ITp __i2,
991  memory_order __m1,
992  memory_order __m2) noexcept
993  { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
994 
995  template<typename _ITp>
996  inline bool
997  atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
998  _ITp* __i1, _ITp __i2,
999  memory_order __m1,
1000  memory_order __m2) noexcept
1001  { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1002 
1003  template<typename _ITp>
1004  inline bool
1005  atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
1006  _ITp* __i1, _ITp __i2,
1007  memory_order __m1,
1008  memory_order __m2) noexcept
1009  { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1010 
1011  template<typename _ITp>
1012  inline bool
1013  atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
1014  _ITp* __i1, _ITp __i2,
1015  memory_order __m1,
1016  memory_order __m2) noexcept
1017  { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1018 
1019 
1020  template<typename _ITp>
1021  inline void
1022  atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
1023  { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1024 
1025  template<typename _ITp>
1026  inline void
1027  atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1028  { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1029 
1030  template<typename _ITp>
1031  inline _ITp
1032  atomic_load(const atomic<_ITp>* __a) noexcept
1033  { return atomic_load_explicit(__a, memory_order_seq_cst); }
1034 
1035  template<typename _ITp>
1036  inline _ITp
1037  atomic_load(const volatile atomic<_ITp>* __a) noexcept
1038  { return atomic_load_explicit(__a, memory_order_seq_cst); }
1039 
1040  template<typename _ITp>
1041  inline _ITp
1042  atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
1043  { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1044 
1045  template<typename _ITp>
1046  inline _ITp
1047  atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1048  { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1049 
1050  template<typename _ITp>
1051  inline bool
1052  atomic_compare_exchange_weak(atomic<_ITp>* __a,
1053  _ITp* __i1, _ITp __i2) noexcept
1054  {
1055  return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1056  memory_order_seq_cst,
1057  memory_order_seq_cst);
1058  }
1059 
1060  template<typename _ITp>
1061  inline bool
1062  atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
1063  _ITp* __i1, _ITp __i2) noexcept
1064  {
1065  return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1066  memory_order_seq_cst,
1067  memory_order_seq_cst);
1068  }
1069 
1070  template<typename _ITp>
1071  inline bool
1072  atomic_compare_exchange_strong(atomic<_ITp>* __a,
1073  _ITp* __i1, _ITp __i2) noexcept
1074  {
1075  return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1076  memory_order_seq_cst,
1077  memory_order_seq_cst);
1078  }
1079 
1080  template<typename _ITp>
1081  inline bool
1082  atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
1083  _ITp* __i1, _ITp __i2) noexcept
1084  {
1085  return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1086  memory_order_seq_cst,
1087  memory_order_seq_cst);
1088  }
1089 
1090  // Function templates for atomic_integral operations only, using
1091  // __atomic_base. Template argument should be constricted to
1092  // intergral types as specified in the standard, excluding address
1093  // types.
1094  template<typename _ITp>
1095  inline _ITp
1096  atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1097  memory_order __m) noexcept
1098  { return __a->fetch_add(__i, __m); }
1099 
1100  template<typename _ITp>
1101  inline _ITp
1102  atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1103  memory_order __m) noexcept
1104  { return __a->fetch_add(__i, __m); }
1105 
1106  template<typename _ITp>
1107  inline _ITp
1108  atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1109  memory_order __m) noexcept
1110  { return __a->fetch_sub(__i, __m); }
1111 
1112  template<typename _ITp>
1113  inline _ITp
1114  atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1115  memory_order __m) noexcept
1116  { return __a->fetch_sub(__i, __m); }
1117 
1118  template<typename _ITp>
1119  inline _ITp
1120  atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1121  memory_order __m) noexcept
1122  { return __a->fetch_and(__i, __m); }
1123 
1124  template<typename _ITp>
1125  inline _ITp
1126  atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1127  memory_order __m) noexcept
1128  { return __a->fetch_and(__i, __m); }
1129 
1130  template<typename _ITp>
1131  inline _ITp
1132  atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1133  memory_order __m) noexcept
1134  { return __a->fetch_or(__i, __m); }
1135 
1136  template<typename _ITp>
1137  inline _ITp
1138  atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1139  memory_order __m) noexcept
1140  { return __a->fetch_or(__i, __m); }
1141 
1142  template<typename _ITp>
1143  inline _ITp
1144  atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1145  memory_order __m) noexcept
1146  { return __a->fetch_xor(__i, __m); }
1147 
1148  template<typename _ITp>
1149  inline _ITp
1150  atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1151  memory_order __m) noexcept
1152  { return __a->fetch_xor(__i, __m); }
1153 
1154  template<typename _ITp>
1155  inline _ITp
1156  atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1157  { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1158 
1159  template<typename _ITp>
1160  inline _ITp
1161  atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1162  { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1163 
1164  template<typename _ITp>
1165  inline _ITp
1166  atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1167  { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1168 
1169  template<typename _ITp>
1170  inline _ITp
1171  atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1172  { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1173 
1174  template<typename _ITp>
1175  inline _ITp
1176  atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1177  { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1178 
1179  template<typename _ITp>
1180  inline _ITp
1181  atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1182  { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1183 
1184  template<typename _ITp>
1185  inline _ITp
1186  atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1187  { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1188 
1189  template<typename _ITp>
1190  inline _ITp
1191  atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1192  { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1193 
1194  template<typename _ITp>
1195  inline _ITp
1196  atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1197  { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1198 
1199  template<typename _ITp>
1200  inline _ITp
1201  atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1202  { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1203 
1204 
1205  // Partial specializations for pointers.
1206  template<typename _ITp>
1207  inline _ITp*
1208  atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1209  memory_order __m) noexcept
1210  { return __a->fetch_add(__d, __m); }
1211 
1212  template<typename _ITp>
1213  inline _ITp*
1214  atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1215  memory_order __m) noexcept
1216  { return __a->fetch_add(__d, __m); }
1217 
1218  template<typename _ITp>
1219  inline _ITp*
1220  atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1221  { return __a->fetch_add(__d); }
1222 
1223  template<typename _ITp>
1224  inline _ITp*
1225  atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1226  { return __a->fetch_add(__d); }
1227 
1228  template<typename _ITp>
1229  inline _ITp*
1230  atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1231  ptrdiff_t __d, memory_order __m) noexcept
1232  { return __a->fetch_sub(__d, __m); }
1233 
1234  template<typename _ITp>
1235  inline _ITp*
1236  atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1237  memory_order __m) noexcept
1238  { return __a->fetch_sub(__d, __m); }
1239 
1240  template<typename _ITp>
1241  inline _ITp*
1242  atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1243  { return __a->fetch_sub(__d); }
1244 
1245  template<typename _ITp>
1246  inline _ITp*
1247  atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1248  { return __a->fetch_sub(__d); }
1249  // @} group atomics
1250 
1251 _GLIBCXX_END_NAMESPACE_VERSION
1252 } // namespace
1253 
1254 #endif // C++11
1255 
1256 #endif // _GLIBCXX_ATOMIC