xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/atomic (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
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
43namespace 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
1123