PR tree-optimization/81184
[official-gcc.git] / libitm / local_atomic
blob9e9719850e3660e83688f6894ade927a622cf9f5
1 // -*- C++ -*- header.
3 // Copyright (C) 2008-2018 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.
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.
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.
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/>.
25 // ????????????????????????????????????????????????????????????????????
27 // This is a copy of the libstdc++ header, with the trivial modification
28 // of ignoring the c++config.h include.  If and when the top-level build is
29 // fixed so that target libraries can be built using the newly built, we can
30 // delete this file.
32 // ????????????????????????????????????????????????????????????????????
34 /** @file include/atomic
35  *  This is a Standard C++ Library header.
36  */
38 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
39 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
41 #ifndef _GLIBCXX_ATOMIC
42 #define _GLIBCXX_ATOMIC 1
44 #define __libitm_always_inline __attribute__((always_inline))
46 // #pragma GCC system_header
48 // #ifndef __GXX_EXPERIMENTAL_CXX0X__
49 // # include <bits/c++0x_warning.h>
50 // #endif
52 // #include <bits/atomic_base.h>
54 namespace std // _GLIBCXX_VISIBILITY(default)
56 // _GLIBCXX_BEGIN_NAMESPACE_VERSION
58   /**
59    * @defgroup atomics Atomics
60    *
61    * Components for performing atomic operations.
62    * @{
63    */
65   /// Enumeration for memory_order
66   typedef enum memory_order
67     {
68       memory_order_relaxed,
69       memory_order_consume,
70       memory_order_acquire,
71       memory_order_release,
72       memory_order_acq_rel,
73       memory_order_seq_cst
74     } memory_order;
76   inline __libitm_always_inline memory_order
77   __calculate_memory_order(memory_order __m) noexcept
78   {
79     const bool __cond1 = __m == memory_order_release;
80     const bool __cond2 = __m == memory_order_acq_rel;
81     memory_order __mo1(__cond1 ? memory_order_relaxed : __m);
82     memory_order __mo2(__cond2 ? memory_order_acquire : __mo1);
83     return __mo2;
84   }
86   inline __libitm_always_inline void
87   atomic_thread_fence(memory_order __m) noexcept
88   {
89     __atomic_thread_fence (__m);
90   }
92   inline __libitm_always_inline void
93   atomic_signal_fence(memory_order __m) noexcept
94   {
95     __atomic_thread_fence (__m);
96   }
98   /// kill_dependency
99   template<typename _Tp>
100     inline _Tp
101     kill_dependency(_Tp __y) noexcept
102     {
103       _Tp __ret(__y);
104       return __ret;
105     }
107   /// Lock-free Property
110 #define ATOMIC_BOOL_LOCK_FREE           __GCC_ATOMIC_BOOL_LOCK_FREE
111 #define ATOMIC_CHAR_LOCK_FREE           __GCC_ATOMIC_CHAR_LOCK_FREE
112 #define ATOMIC_WCHAR_T_LOCK_FREE        __GCC_ATOMIC_WCHAR_T_LOCK_FREE
113 #define ATOMIC_CHAR16_T_LOCK_FREE       __GCC_ATOMIC_CHAR16_T_LOCK_FREE
114 #define ATOMIC_CHAR32_T_LOCK_FREE       __GCC_ATOMIC_CHAR32_T_LOCK_FREE
115 #define ATOMIC_SHORT_LOCK_FREE          __GCC_ATOMIC_SHORT_LOCK_FREE
116 #define ATOMIC_INT_LOCK_FREE            __GCC_ATOMIC_INT_LOCK_FREE
117 #define ATOMIC_LONG_LOCK_FREE           __GCC_ATOMIC_LONG_LOCK_FREE
118 #define ATOMIC_LLONG_LOCK_FREE          __GCC_ATOMIC_LLONG_LOCK_FREE
119 #define ATOMIC_POINTER_LOCK_FREE        __GCC_ATOMIC_POINTER_LOCK_FREE
121   // Base types for atomics.
122   template<typename _IntTp>
123     struct __atomic_base;
125   /// atomic_char
126   typedef __atomic_base<char>                   atomic_char;
128   /// atomic_schar
129   typedef __atomic_base<signed char>            atomic_schar;
131   /// atomic_uchar
132   typedef __atomic_base<unsigned char>          atomic_uchar;
134   /// atomic_short
135   typedef __atomic_base<short>                  atomic_short;
137   /// atomic_ushort
138   typedef __atomic_base<unsigned short>         atomic_ushort;
140   /// atomic_int
141   typedef __atomic_base<int>                    atomic_int;
143   /// atomic_uint
144   typedef __atomic_base<unsigned int>           atomic_uint;
146   /// atomic_long
147   typedef __atomic_base<long>                   atomic_long;
149   /// atomic_ulong
150   typedef __atomic_base<unsigned long>          atomic_ulong;
152   /// atomic_llong
153   typedef __atomic_base<long long>              atomic_llong;
155   /// atomic_ullong
156   typedef __atomic_base<unsigned long long>     atomic_ullong;
158   /// atomic_wchar_t
159   typedef __atomic_base<wchar_t>                atomic_wchar_t;
161   /// atomic_char16_t
162   typedef __atomic_base<char16_t>               atomic_char16_t;
164   /// atomic_char32_t
165   typedef __atomic_base<char32_t>               atomic_char32_t;
167   /// atomic_char32_t
168   typedef __atomic_base<char32_t>               atomic_char32_t;
171   /// atomic_int_least8_t
172   typedef __atomic_base<int_least8_t>           atomic_int_least8_t;
174   /// atomic_uint_least8_t
175   typedef __atomic_base<uint_least8_t>          atomic_uint_least8_t;
177   /// atomic_int_least16_t
178   typedef __atomic_base<int_least16_t>          atomic_int_least16_t;
180   /// atomic_uint_least16_t
181   typedef __atomic_base<uint_least16_t>         atomic_uint_least16_t;
183   /// atomic_int_least32_t
184   typedef __atomic_base<int_least32_t>          atomic_int_least32_t;
186   /// atomic_uint_least32_t
187   typedef __atomic_base<uint_least32_t>         atomic_uint_least32_t;
189   /// atomic_int_least64_t
190   typedef __atomic_base<int_least64_t>          atomic_int_least64_t;
192   /// atomic_uint_least64_t
193   typedef __atomic_base<uint_least64_t>         atomic_uint_least64_t;
196   /// atomic_int_fast8_t
197   typedef __atomic_base<int_fast8_t>            atomic_int_fast8_t;
199   /// atomic_uint_fast8_t
200   typedef __atomic_base<uint_fast8_t>           atomic_uint_fast8_t;
202   /// atomic_int_fast16_t
203   typedef __atomic_base<int_fast16_t>           atomic_int_fast16_t;
205   /// atomic_uint_fast16_t
206   typedef __atomic_base<uint_fast16_t>          atomic_uint_fast16_t;
208   /// atomic_int_fast32_t
209   typedef __atomic_base<int_fast32_t>           atomic_int_fast32_t;
211   /// atomic_uint_fast32_t
212   typedef __atomic_base<uint_fast32_t>          atomic_uint_fast32_t;
214   /// atomic_int_fast64_t
215   typedef __atomic_base<int_fast64_t>           atomic_int_fast64_t;
217   /// atomic_uint_fast64_t
218   typedef __atomic_base<uint_fast64_t>          atomic_uint_fast64_t;
221   /// atomic_intptr_t
222   typedef __atomic_base<intptr_t>               atomic_intptr_t;
224   /// atomic_uintptr_t
225   typedef __atomic_base<uintptr_t>              atomic_uintptr_t;
227   /// atomic_size_t
228   typedef __atomic_base<size_t>                 atomic_size_t;
230   /// atomic_intmax_t
231   typedef __atomic_base<intmax_t>               atomic_intmax_t;
233   /// atomic_uintmax_t
234   typedef __atomic_base<uintmax_t>              atomic_uintmax_t;
236   /// atomic_ptrdiff_t
237   typedef __atomic_base<ptrdiff_t>              atomic_ptrdiff_t;
240 #define ATOMIC_VAR_INIT(_VI) { _VI }
242   template<typename _Tp>
243     struct atomic;
245   template<typename _Tp>
246     struct atomic<_Tp*>;
249   /**
250    *  @brief Base type for atomic_flag.
251    *
252    *  Base type is POD with data, allowing atomic_flag to derive from
253    *  it and meet the standard layout type requirement. In addition to
254    *  compatibilty with a C interface, this allows different
255    *  implementations of atomic_flag to use the same atomic operation
256    *  functions, via a standard conversion to the __atomic_flag_base
257    *  argument.
258   */
259   // _GLIBCXX_BEGIN_EXTERN_C
261   struct __atomic_flag_base
262   {
263     bool _M_i;
264   };
266   // _GLIBCXX_END_EXTERN_C
268 #define ATOMIC_FLAG_INIT { false }
270   /// atomic_flag
271   struct atomic_flag : public __atomic_flag_base
272   {
273     atomic_flag() noexcept = default;
274     ~atomic_flag() noexcept = default;
275     atomic_flag(const atomic_flag&) = delete;
276     atomic_flag& operator=(const atomic_flag&) = delete;
277     atomic_flag& operator=(const atomic_flag&) volatile = delete;
279     // Conversion to ATOMIC_FLAG_INIT.
280     atomic_flag(bool __i) noexcept : __atomic_flag_base({ __i }) { }
282     __libitm_always_inline bool
283     test_and_set(memory_order __m = memory_order_seq_cst) noexcept
284     {
285       return __atomic_test_and_set (&_M_i, __m);
286     }
288     __libitm_always_inline bool
289     test_and_set(memory_order __m = memory_order_seq_cst) volatile noexcept
290     {
291       return __atomic_test_and_set (&_M_i, __m);
292     }
294     __libitm_always_inline void
295     clear(memory_order __m = memory_order_seq_cst) noexcept
296     {
297       // __glibcxx_assert(__m != memory_order_consume);
298       // __glibcxx_assert(__m != memory_order_acquire);
299       // __glibcxx_assert(__m != memory_order_acq_rel);
301       __atomic_clear (&_M_i, __m);
302     }
304     __libitm_always_inline void
305     clear(memory_order __m = memory_order_seq_cst) volatile noexcept
306     {
307       // __glibcxx_assert(__m != memory_order_consume);
308       // __glibcxx_assert(__m != memory_order_acquire);
309       // __glibcxx_assert(__m != memory_order_acq_rel);
311       __atomic_clear (&_M_i, __m);
312     }
313   };
316   /// Base class for atomic integrals.
317   //
318   // For each of the integral types, define atomic_[integral type] struct
319   //
320   // atomic_bool     bool
321   // atomic_char     char
322   // atomic_schar    signed char
323   // atomic_uchar    unsigned char
324   // atomic_short    short
325   // atomic_ushort   unsigned short
326   // atomic_int      int
327   // atomic_uint     unsigned int
328   // atomic_long     long
329   // atomic_ulong    unsigned long
330   // atomic_llong    long long
331   // atomic_ullong   unsigned long long
332   // atomic_char16_t char16_t
333   // atomic_char32_t char32_t
334   // atomic_wchar_t  wchar_t
335   //
336   // NB: Assuming _ITp is an integral scalar type that is 1, 2, 4, or
337   // 8 bytes, since that is what GCC built-in functions for atomic
338   // memory access expect.
339   template<typename _ITp>
340     struct __atomic_base
341     {
342     private:
343       typedef _ITp      __int_type;
345       __int_type        _M_i;
347     public:
348       __atomic_base() noexcept = default;
349       ~__atomic_base() noexcept = default;
350       __atomic_base(const __atomic_base&) = delete;
351       __atomic_base& operator=(const __atomic_base&) = delete;
352       __atomic_base& operator=(const __atomic_base&) volatile = delete;
354       // Requires __int_type convertible to _M_i.
355       constexpr __atomic_base(__int_type __i) noexcept : _M_i (__i) { }
357       operator __int_type() const noexcept
358       { return load(); }
360       operator __int_type() const volatile noexcept
361       { return load(); }
363       __int_type
364       operator=(__int_type __i) noexcept
365       {
366         store(__i);
367         return __i;
368       }
370       __int_type
371       operator=(__int_type __i) volatile noexcept
372       {
373         store(__i);
374         return __i;
375       }
377       __int_type
378       operator++(int) noexcept
379       { return fetch_add(1); }
381       __int_type
382       operator++(int) volatile noexcept
383       { return fetch_add(1); }
385       __int_type
386       operator--(int) noexcept
387       { return fetch_sub(1); }
389       __int_type
390       operator--(int) volatile noexcept
391       { return fetch_sub(1); }
393       __int_type
394       operator++() noexcept
395       { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
397       __int_type
398       operator++() volatile noexcept
399       { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
401       __int_type
402       operator--() noexcept
403       { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
405       __int_type
406       operator--() volatile noexcept
407       { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
409       __int_type
410       operator+=(__int_type __i) noexcept
411       { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
413       __int_type
414       operator+=(__int_type __i) volatile noexcept
415       { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
417       __int_type
418       operator-=(__int_type __i) noexcept
419       { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
421       __int_type
422       operator-=(__int_type __i) volatile noexcept
423       { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
425       __int_type
426       operator&=(__int_type __i) noexcept
427       { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
429       __int_type
430       operator&=(__int_type __i) volatile noexcept
431       { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
433       __int_type
434       operator|=(__int_type __i) noexcept
435       { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
437       __int_type
438       operator|=(__int_type __i) volatile noexcept
439       { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
441       __int_type
442       operator^=(__int_type __i) noexcept
443       { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
445       __int_type
446       operator^=(__int_type __i) volatile noexcept
447       { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
449       bool
450       is_lock_free() const noexcept
451       { return __atomic_is_lock_free (sizeof (_M_i), &_M_i); }
453       bool
454       is_lock_free() const volatile noexcept
455       { return __atomic_is_lock_free (sizeof (_M_i), &_M_i); }
457       __libitm_always_inline void
458       store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept
459       {
460         // __glibcxx_assert(__m != memory_order_acquire);
461         // __glibcxx_assert(__m != memory_order_acq_rel);
462         // __glibcxx_assert(__m != memory_order_consume);
464         __atomic_store_n(&_M_i, __i, __m);
465       }
467       __libitm_always_inline void
468       store(__int_type __i,
469             memory_order __m = memory_order_seq_cst) volatile noexcept
470       {
471         // __glibcxx_assert(__m != memory_order_acquire);
472         // __glibcxx_assert(__m != memory_order_acq_rel);
473         // __glibcxx_assert(__m != memory_order_consume);
475         __atomic_store_n(&_M_i, __i, __m);
476       }
478       __libitm_always_inline __int_type
479       load(memory_order __m = memory_order_seq_cst) const noexcept
480       {
481         // __glibcxx_assert(__m != memory_order_release);
482         // __glibcxx_assert(__m != memory_order_acq_rel);
484         return __atomic_load_n(&_M_i, __m);
485       }
487       __libitm_always_inline __int_type
488       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
489       {
490         // __glibcxx_assert(__m != memory_order_release);
491         // __glibcxx_assert(__m != memory_order_acq_rel);
493         return __atomic_load_n(&_M_i, __m);
494       }
496       __libitm_always_inline __int_type
497       exchange(__int_type __i,
498                memory_order __m = memory_order_seq_cst) noexcept
499       {
500         return __atomic_exchange_n(&_M_i, __i, __m);
501       }
503       __libitm_always_inline __int_type
504       exchange(__int_type __i,
505                memory_order __m = memory_order_seq_cst) volatile noexcept
506       {
507         return __atomic_exchange_n(&_M_i, __i, __m);
508       }
510       __libitm_always_inline bool
511       compare_exchange_weak(__int_type& __i1, __int_type __i2,
512                             memory_order __m1, memory_order __m2) noexcept
513       {
514         // __glibcxx_assert(__m2 != memory_order_release);
515         // __glibcxx_assert(__m2 != memory_order_acq_rel);
516         // __glibcxx_assert(__m2 <= __m1);
518         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
519       }
521       __libitm_always_inline bool
522       compare_exchange_weak(__int_type& __i1, __int_type __i2,
523                             memory_order __m1,
524                             memory_order __m2) volatile noexcept
525       {
526         // __glibcxx_assert(__m2 != memory_order_release);
527         // __glibcxx_assert(__m2 != memory_order_acq_rel);
528         // __glibcxx_assert(__m2 <= __m1);
530         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
531       }
533       __libitm_always_inline bool
534       compare_exchange_weak(__int_type& __i1, __int_type __i2,
535                             memory_order __m = memory_order_seq_cst) noexcept
536       {
537         return compare_exchange_weak(__i1, __i2, __m,
538                                      __calculate_memory_order(__m));
539       }
541       __libitm_always_inline bool
542       compare_exchange_weak(__int_type& __i1, __int_type __i2,
543                    memory_order __m = memory_order_seq_cst) volatile noexcept
544       {
545         return compare_exchange_weak(__i1, __i2, __m,
546                                      __calculate_memory_order(__m));
547       }
549       __libitm_always_inline bool
550       compare_exchange_strong(__int_type& __i1, __int_type __i2,
551                               memory_order __m1, memory_order __m2) noexcept
552       {
553         // __glibcxx_assert(__m2 != memory_order_release);
554         // __glibcxx_assert(__m2 != memory_order_acq_rel);
555         // __glibcxx_assert(__m2 <= __m1);
557         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
558       }
560       __libitm_always_inline bool
561       compare_exchange_strong(__int_type& __i1, __int_type __i2,
562                               memory_order __m1,
563                               memory_order __m2) volatile noexcept
564       {
565         // __glibcxx_assert(__m2 != memory_order_release);
566         // __glibcxx_assert(__m2 != memory_order_acq_rel);
567         // __glibcxx_assert(__m2 <= __m1);
569         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
570       }
572       __libitm_always_inline bool
573       compare_exchange_strong(__int_type& __i1, __int_type __i2,
574                               memory_order __m = memory_order_seq_cst) noexcept
575       {
576         return compare_exchange_strong(__i1, __i2, __m,
577                                        __calculate_memory_order(__m));
578       }
580       __libitm_always_inline bool
581       compare_exchange_strong(__int_type& __i1, __int_type __i2,
582                  memory_order __m = memory_order_seq_cst) volatile noexcept
583       {
584         return compare_exchange_strong(__i1, __i2, __m,
585                                        __calculate_memory_order(__m));
586       }
588       __libitm_always_inline __int_type
589       fetch_add(__int_type __i,
590                 memory_order __m = memory_order_seq_cst) noexcept
591       { return __atomic_fetch_add(&_M_i, __i, __m); }
593       __libitm_always_inline __int_type
594       fetch_add(__int_type __i,
595                 memory_order __m = memory_order_seq_cst) volatile noexcept
596       { return __atomic_fetch_add(&_M_i, __i, __m); }
598       __libitm_always_inline __int_type
599       fetch_sub(__int_type __i,
600                 memory_order __m = memory_order_seq_cst) noexcept
601       { return __atomic_fetch_sub(&_M_i, __i, __m); }
603       __libitm_always_inline __int_type
604       fetch_sub(__int_type __i,
605                 memory_order __m = memory_order_seq_cst) volatile noexcept
606       { return __atomic_fetch_sub(&_M_i, __i, __m); }
608       __libitm_always_inline __int_type
609       fetch_and(__int_type __i,
610                 memory_order __m = memory_order_seq_cst) noexcept
611       { return __atomic_fetch_and(&_M_i, __i, __m); }
613       __libitm_always_inline __int_type
614       fetch_and(__int_type __i,
615                 memory_order __m = memory_order_seq_cst) volatile noexcept
616       { return __atomic_fetch_and(&_M_i, __i, __m); }
618       __libitm_always_inline __int_type
619       fetch_or(__int_type __i,
620                memory_order __m = memory_order_seq_cst) noexcept
621       { return __atomic_fetch_or(&_M_i, __i, __m); }
623       __libitm_always_inline __int_type
624       fetch_or(__int_type __i,
625                memory_order __m = memory_order_seq_cst) volatile noexcept
626       { return __atomic_fetch_or(&_M_i, __i, __m); }
628       __libitm_always_inline __int_type
629       fetch_xor(__int_type __i,
630                 memory_order __m = memory_order_seq_cst) noexcept
631       { return __atomic_fetch_xor(&_M_i, __i, __m); }
633       __libitm_always_inline __int_type
634       fetch_xor(__int_type __i,
635                 memory_order __m = memory_order_seq_cst) volatile noexcept
636       { return __atomic_fetch_xor(&_M_i, __i, __m); }
637     };
640   /// Partial specialization for pointer types.
641   template<typename _PTp>
642     struct __atomic_base<_PTp*>
643     {
644     private:
645       typedef _PTp*     __pointer_type;
647       __pointer_type    _M_p;
649     public:
650       __atomic_base() noexcept = default;
651       ~__atomic_base() noexcept = default;
652       __atomic_base(const __atomic_base&) = delete;
653       __atomic_base& operator=(const __atomic_base&) = delete;
654       __atomic_base& operator=(const __atomic_base&) volatile = delete;
656       // Requires __pointer_type convertible to _M_p.
657       constexpr __atomic_base(__pointer_type __p) noexcept : _M_p (__p) { }
659       operator __pointer_type() const noexcept
660       { return load(); }
662       operator __pointer_type() const volatile noexcept
663       { return load(); }
665       __pointer_type
666       operator=(__pointer_type __p) noexcept
667       {
668         store(__p);
669         return __p;
670       }
672       __pointer_type
673       operator=(__pointer_type __p) volatile noexcept
674       {
675         store(__p);
676         return __p;
677       }
679       __pointer_type
680       operator++(int) noexcept
681       { return fetch_add(1); }
683       __pointer_type
684       operator++(int) volatile noexcept
685       { return fetch_add(1); }
687       __pointer_type
688       operator--(int) noexcept
689       { return fetch_sub(1); }
691       __pointer_type
692       operator--(int) volatile noexcept
693       { return fetch_sub(1); }
695       __pointer_type
696       operator++() noexcept
697       { return __atomic_add_fetch(&_M_p, 1, memory_order_seq_cst); }
699       __pointer_type
700       operator++() volatile noexcept
701       { return __atomic_add_fetch(&_M_p, 1, memory_order_seq_cst); }
703       __pointer_type
704       operator--() noexcept
705       { return __atomic_sub_fetch(&_M_p, 1, memory_order_seq_cst); }
707       __pointer_type
708       operator--() volatile noexcept
709       { return __atomic_sub_fetch(&_M_p, 1, memory_order_seq_cst); }
711       __pointer_type
712       operator+=(ptrdiff_t __d) noexcept
713       { return __atomic_add_fetch(&_M_p, __d, memory_order_seq_cst); }
715       __pointer_type
716       operator+=(ptrdiff_t __d) volatile noexcept
717       { return __atomic_add_fetch(&_M_p, __d, memory_order_seq_cst); }
719       __pointer_type
720       operator-=(ptrdiff_t __d) noexcept
721       { return __atomic_sub_fetch(&_M_p, __d, memory_order_seq_cst); }
723       __pointer_type
724       operator-=(ptrdiff_t __d) volatile noexcept
725       { return __atomic_sub_fetch(&_M_p, __d, memory_order_seq_cst); }
727       bool
728       is_lock_free() const noexcept
729       { return __atomic_is_lock_free (sizeof (_M_p), &_M_p); }
731       bool
732       is_lock_free() const volatile noexcept
733       { return __atomic_is_lock_free (sizeof (_M_p), &_M_p); }
735       __libitm_always_inline void
736       store(__pointer_type __p,
737             memory_order __m = memory_order_seq_cst) noexcept
738       {
739         // __glibcxx_assert(__m != memory_order_acquire);
740         // __glibcxx_assert(__m != memory_order_acq_rel);
741         // __glibcxx_assert(__m != memory_order_consume);
743         __atomic_store_n(&_M_p, __p, __m);
744       }
746       __libitm_always_inline void
747       store(__pointer_type __p,
748             memory_order __m = memory_order_seq_cst) volatile noexcept
749       {
750         // __glibcxx_assert(__m != memory_order_acquire);
751         // __glibcxx_assert(__m != memory_order_acq_rel);
752         // __glibcxx_assert(__m != memory_order_consume);
754         __atomic_store_n(&_M_p, __p, __m);
755       }
757       __libitm_always_inline __pointer_type
758       load(memory_order __m = memory_order_seq_cst) const noexcept
759       {
760         // __glibcxx_assert(__m != memory_order_release);
761         // __glibcxx_assert(__m != memory_order_acq_rel);
763         return __atomic_load_n(&_M_p, __m);
764       }
766       __libitm_always_inline __pointer_type
767       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
768       {
769         // __glibcxx_assert(__m != memory_order_release);
770         // __glibcxx_assert(__m != memory_order_acq_rel);
772         return __atomic_load_n(&_M_p, __m);
773       }
775       __libitm_always_inline __pointer_type
776       exchange(__pointer_type __p,
777                memory_order __m = memory_order_seq_cst) noexcept
778       {
779         return __atomic_exchange_n(&_M_p, __p, __m);
780       }
782       __libitm_always_inline __pointer_type
783       exchange(__pointer_type __p,
784                memory_order __m = memory_order_seq_cst) volatile noexcept
785       {
786         return __atomic_exchange_n(&_M_p, __p, __m);
787       }
789       __libitm_always_inline bool
790       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
791                               memory_order __m1,
792                               memory_order __m2) noexcept
793       {
794         // __glibcxx_assert(__m2 != memory_order_release);
795         // __glibcxx_assert(__m2 != memory_order_acq_rel);
796         // __glibcxx_assert(__m2 <= __m1);
798         return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
799       }
801       __libitm_always_inline bool
802       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
803                               memory_order __m1,
804                               memory_order __m2) volatile noexcept
805       {
806         // __glibcxx_assert(__m2 != memory_order_release);
807         // __glibcxx_assert(__m2 != memory_order_acq_rel);
808         // __glibcxx_assert(__m2 <= __m1);
810         return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
811       }
813       __libitm_always_inline __pointer_type
814       fetch_add(ptrdiff_t __d,
815                 memory_order __m = memory_order_seq_cst) noexcept
816       { return __atomic_fetch_add(&_M_p, __d, __m); }
818       __libitm_always_inline __pointer_type
819       fetch_add(ptrdiff_t __d,
820                 memory_order __m = memory_order_seq_cst) volatile noexcept
821       { return __atomic_fetch_add(&_M_p, __d, __m); }
823       __libitm_always_inline __pointer_type
824       fetch_sub(ptrdiff_t __d,
825                 memory_order __m = memory_order_seq_cst) noexcept
826       { return __atomic_fetch_sub(&_M_p, __d, __m); }
828       __libitm_always_inline __pointer_type
829       fetch_sub(ptrdiff_t __d,
830                 memory_order __m = memory_order_seq_cst) volatile noexcept
831       { return __atomic_fetch_sub(&_M_p, __d, __m); }
832     };
835   /**
836    * @addtogroup atomics
837    * @{
838    */
840   /// atomic_bool
841   // NB: No operators or fetch-operations for this type.
842   struct atomic_bool
843   {
844   private:
845     __atomic_base<bool> _M_base;
847   public:
848     atomic_bool() noexcept = default;
849     ~atomic_bool() noexcept = default;
850     atomic_bool(const atomic_bool&) = delete;
851     atomic_bool& operator=(const atomic_bool&) = delete;
852     atomic_bool& operator=(const atomic_bool&) volatile = delete;
854     constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { }
856     bool
857     operator=(bool __i) noexcept
858     { return _M_base.operator=(__i); }
860     operator bool() const noexcept
861     { return _M_base.load(); }
863     operator bool() const volatile noexcept
864     { return _M_base.load(); }
866     bool
867     is_lock_free() const noexcept { return _M_base.is_lock_free(); }
869     bool
870     is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
872     __libitm_always_inline void
873     store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
874     { _M_base.store(__i, __m); }
876     __libitm_always_inline void
877     store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
878     { _M_base.store(__i, __m); }
880     __libitm_always_inline bool
881     load(memory_order __m = memory_order_seq_cst) const noexcept
882     { return _M_base.load(__m); }
884     __libitm_always_inline bool
885     load(memory_order __m = memory_order_seq_cst) const volatile noexcept
886     { return _M_base.load(__m); }
888     __libitm_always_inline bool
889     exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
890     { return _M_base.exchange(__i, __m); }
892     __libitm_always_inline bool
893     exchange(bool __i,
894              memory_order __m = memory_order_seq_cst) volatile noexcept
895     { return _M_base.exchange(__i, __m); }
897     __libitm_always_inline bool
898     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
899                           memory_order __m2) noexcept
900     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
902     __libitm_always_inline bool
903     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
904                           memory_order __m2) volatile noexcept
905     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
907     __libitm_always_inline bool
908     compare_exchange_weak(bool& __i1, bool __i2,
909                           memory_order __m = memory_order_seq_cst) noexcept
910     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
912     __libitm_always_inline bool
913     compare_exchange_weak(bool& __i1, bool __i2,
914                      memory_order __m = memory_order_seq_cst) volatile noexcept
915     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
917     __libitm_always_inline bool
918     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
919                             memory_order __m2) noexcept
920     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
922     __libitm_always_inline bool
923     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
924                             memory_order __m2) volatile noexcept
925     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
927     __libitm_always_inline bool
928     compare_exchange_strong(bool& __i1, bool __i2,
929                             memory_order __m = memory_order_seq_cst) noexcept
930     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
932     __libitm_always_inline bool
933     compare_exchange_strong(bool& __i1, bool __i2,
934                     memory_order __m = memory_order_seq_cst) volatile noexcept
935     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
936   };
939   /// atomic
940   /// 29.4.3, Generic atomic type, primary class template.
941   template<typename _Tp>
942     struct atomic
943     {
944     private:
945       _Tp _M_i;
947     public:
948       atomic() noexcept = default;
949       ~atomic() noexcept = default;
950       atomic(const atomic&) = delete;
951       atomic& operator=(const atomic&) = delete;
952       atomic& operator=(const atomic&) volatile = delete;
954       constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
956       operator _Tp() const noexcept
957       { return load(); }
959       operator _Tp() const volatile noexcept
960       { return load(); }
962       _Tp
963       operator=(_Tp __i) noexcept 
964       { store(__i); return __i; }
966       _Tp
967       operator=(_Tp __i) volatile noexcept 
968       { store(__i); return __i; }
970       bool
971       is_lock_free() const noexcept
972       { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); }
974       bool
975       is_lock_free() const volatile noexcept
976       { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); }
978       void
979       store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
980       { __atomic_store(&_M_i, &__i, _m); }
982       __libitm_always_inline void
983       store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept
984       { __atomic_store(&_M_i, &__i, _m); }
986       __libitm_always_inline _Tp
987       load(memory_order _m = memory_order_seq_cst) const noexcept
988       { 
989         _Tp tmp;
990         __atomic_load(&_M_i, &tmp, _m); 
991         return tmp;
992       }
994       __libitm_always_inline _Tp
995       load(memory_order _m = memory_order_seq_cst) const volatile noexcept
996       { 
997         _Tp tmp;
998         __atomic_load(&_M_i, &tmp, _m); 
999         return tmp;
1000       }
1002       __libitm_always_inline _Tp
1003       exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
1004       { 
1005         _Tp tmp;
1006         __atomic_exchange(&_M_i, &__i, &tmp, _m); 
1007         return tmp;
1008       }
1010       __libitm_always_inline _Tp
1011       exchange(_Tp __i, 
1012                memory_order _m = memory_order_seq_cst) volatile noexcept
1013       { 
1014         _Tp tmp;
1015         __atomic_exchange(&_M_i, &__i, &tmp, _m); 
1016         return tmp;
1017       }
1019       __libitm_always_inline bool
1020       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 
1021                             memory_order __f) noexcept
1022       {
1023         return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 
1024       }
1026       __libitm_always_inline bool
1027       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 
1028                             memory_order __f) volatile noexcept
1029       {
1030         return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 
1031       }
1033       __libitm_always_inline bool
1034       compare_exchange_weak(_Tp& __e, _Tp __i,
1035                             memory_order __m = memory_order_seq_cst) noexcept
1036       { return compare_exchange_weak(__e, __i, __m, __m); }
1038       __libitm_always_inline bool
1039       compare_exchange_weak(_Tp& __e, _Tp __i,
1040                      memory_order __m = memory_order_seq_cst) volatile noexcept
1041       { return compare_exchange_weak(__e, __i, __m, __m); }
1043       __libitm_always_inline bool
1044       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
1045                               memory_order __f) noexcept
1046       {
1047         return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 
1048       }
1050       __libitm_always_inline bool
1051       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
1052                               memory_order __f) volatile noexcept
1053       {
1054         return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 
1055       }
1057       __libitm_always_inline bool
1058       compare_exchange_strong(_Tp& __e, _Tp __i,
1059                                memory_order __m = memory_order_seq_cst) noexcept
1060       { return compare_exchange_strong(__e, __i, __m, __m); }
1062       __libitm_always_inline bool
1063       compare_exchange_strong(_Tp& __e, _Tp __i,
1064                      memory_order __m = memory_order_seq_cst) volatile noexcept
1065       { return compare_exchange_strong(__e, __i, __m, __m); }
1066     };
1069   /// Partial specialization for pointer types.
1070   template<typename _Tp>
1071     struct atomic<_Tp*>
1072     {
1073       typedef _Tp*                      __pointer_type;
1074       typedef __atomic_base<_Tp*>       __base_type;
1075       __base_type                       _M_b;
1077       atomic() noexcept = default;
1078       ~atomic() noexcept = default;
1079       atomic(const atomic&) = delete;
1080       atomic& operator=(const atomic&) = delete;
1081       atomic& operator=(const atomic&) volatile = delete;
1083       constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
1085       operator __pointer_type() const noexcept
1086       { return __pointer_type(_M_b); }
1088       operator __pointer_type() const volatile noexcept
1089       { return __pointer_type(_M_b); }
1091       __pointer_type
1092       operator=(__pointer_type __p) noexcept
1093       { return _M_b.operator=(__p); }
1095       __pointer_type
1096       operator=(__pointer_type __p) volatile noexcept
1097       { return _M_b.operator=(__p); }
1099       __pointer_type
1100       operator++(int) noexcept
1101       { return _M_b++; }
1103       __pointer_type
1104       operator++(int) volatile noexcept
1105       { return _M_b++; }
1107       __pointer_type
1108       operator--(int) noexcept
1109       { return _M_b--; }
1111       __pointer_type
1112       operator--(int) volatile noexcept
1113       { return _M_b--; }
1115       __pointer_type
1116       operator++() noexcept
1117       { return ++_M_b; }
1119       __pointer_type
1120       operator++() volatile noexcept
1121       { return ++_M_b; }
1123       __pointer_type
1124       operator--() noexcept
1125       { return --_M_b; }
1127       __pointer_type
1128       operator--() volatile noexcept
1129       { return --_M_b; }
1131       __pointer_type
1132       operator+=(ptrdiff_t __d) noexcept
1133       { return _M_b.operator+=(__d); }
1135       __pointer_type
1136       operator+=(ptrdiff_t __d) volatile noexcept
1137       { return _M_b.operator+=(__d); }
1139       __pointer_type
1140       operator-=(ptrdiff_t __d) noexcept
1141       { return _M_b.operator-=(__d); }
1143       __pointer_type
1144       operator-=(ptrdiff_t __d) volatile noexcept
1145       { return _M_b.operator-=(__d); }
1147       bool
1148       is_lock_free() const noexcept
1149       { return _M_b.is_lock_free(); }
1151       bool
1152       is_lock_free() const volatile noexcept
1153       { return _M_b.is_lock_free(); }
1155       __libitm_always_inline void
1156       store(__pointer_type __p,
1157             memory_order __m = memory_order_seq_cst) noexcept
1158       { return _M_b.store(__p, __m); }
1160       __libitm_always_inline void
1161       store(__pointer_type __p,
1162             memory_order __m = memory_order_seq_cst) volatile noexcept
1163       { return _M_b.store(__p, __m); }
1165       __libitm_always_inline __pointer_type
1166       load(memory_order __m = memory_order_seq_cst) const noexcept
1167       { return _M_b.load(__m); }
1169       __libitm_always_inline __pointer_type
1170       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
1171       { return _M_b.load(__m); }
1173       __libitm_always_inline __pointer_type
1174       exchange(__pointer_type __p,
1175                memory_order __m = memory_order_seq_cst) noexcept
1176       { return _M_b.exchange(__p, __m); }
1178       __libitm_always_inline __pointer_type
1179       exchange(__pointer_type __p,
1180                memory_order __m = memory_order_seq_cst) volatile noexcept
1181       { return _M_b.exchange(__p, __m); }
1183       __libitm_always_inline bool
1184       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
1185                             memory_order __m1, memory_order __m2) noexcept
1186       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
1188       __libitm_always_inline bool
1189       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
1190                             memory_order __m1,
1191                             memory_order __m2) volatile noexcept
1192       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
1194       __libitm_always_inline bool
1195       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
1196                             memory_order __m = memory_order_seq_cst) noexcept
1197       {
1198         return compare_exchange_weak(__p1, __p2, __m,
1199                                      __calculate_memory_order(__m));
1200       }
1202       __libitm_always_inline bool
1203       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
1204                     memory_order __m = memory_order_seq_cst) volatile noexcept
1205       {
1206         return compare_exchange_weak(__p1, __p2, __m,
1207                                      __calculate_memory_order(__m));
1208       }
1210       __libitm_always_inline bool
1211       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
1212                               memory_order __m1, memory_order __m2) noexcept
1213       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
1215       __libitm_always_inline bool
1216       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
1217                               memory_order __m1,
1218                               memory_order __m2) volatile noexcept
1219       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
1221       __libitm_always_inline bool
1222       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
1223                               memory_order __m = memory_order_seq_cst) noexcept
1224       {
1225         return _M_b.compare_exchange_strong(__p1, __p2, __m,
1226                                             __calculate_memory_order(__m));
1227       }
1229       __libitm_always_inline bool
1230       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
1231                     memory_order __m = memory_order_seq_cst) volatile noexcept
1232       {
1233         return _M_b.compare_exchange_strong(__p1, __p2, __m,
1234                                             __calculate_memory_order(__m));
1235       }
1237       __libitm_always_inline __pointer_type
1238       fetch_add(ptrdiff_t __d,
1239                 memory_order __m = memory_order_seq_cst) noexcept
1240       { return _M_b.fetch_add(__d, __m); }
1242       __libitm_always_inline __pointer_type
1243       fetch_add(ptrdiff_t __d,
1244                 memory_order __m = memory_order_seq_cst) volatile noexcept
1245       { return _M_b.fetch_add(__d, __m); }
1247       __libitm_always_inline __pointer_type
1248       fetch_sub(ptrdiff_t __d,
1249                 memory_order __m = memory_order_seq_cst) noexcept
1250       { return _M_b.fetch_sub(__d, __m); }
1252       __libitm_always_inline __pointer_type
1253       fetch_sub(ptrdiff_t __d,
1254                 memory_order __m = memory_order_seq_cst) volatile noexcept
1255       { return _M_b.fetch_sub(__d, __m); }
1256     };
1259   /// Explicit specialization for bool.
1260   template<>
1261     struct atomic<bool> : public atomic_bool
1262     {
1263       typedef bool                      __integral_type;
1264       typedef atomic_bool               __base_type;
1266       atomic() noexcept = default;
1267       ~atomic() noexcept = default;
1268       atomic(const atomic&) = delete;
1269       atomic& operator=(const atomic&) = delete;
1270       atomic& operator=(const atomic&) volatile = delete;
1272       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1274       using __base_type::operator __integral_type;
1275       using __base_type::operator=;
1276     };
1278   /// Explicit specialization for char.
1279   template<>
1280     struct atomic<char> : public atomic_char
1281     {
1282       typedef char                      __integral_type;
1283       typedef atomic_char               __base_type;
1285       atomic() noexcept = default;
1286       ~atomic() noexcept = default;
1287       atomic(const atomic&) = delete;
1288       atomic& operator=(const atomic&) = delete;
1289       atomic& operator=(const atomic&) volatile = delete;
1291       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1293       using __base_type::operator __integral_type;
1294       using __base_type::operator=;
1295     };
1297   /// Explicit specialization for signed char.
1298   template<>
1299     struct atomic<signed char> : public atomic_schar
1300     {
1301       typedef signed char               __integral_type;
1302       typedef atomic_schar              __base_type;
1304       atomic() noexcept= default;
1305       ~atomic() noexcept = default;
1306       atomic(const atomic&) = delete;
1307       atomic& operator=(const atomic&) = delete;
1308       atomic& operator=(const atomic&) volatile = delete;
1310       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1312       using __base_type::operator __integral_type;
1313       using __base_type::operator=;
1314     };
1316   /// Explicit specialization for unsigned char.
1317   template<>
1318     struct atomic<unsigned char> : public atomic_uchar
1319     {
1320       typedef unsigned char             __integral_type;
1321       typedef atomic_uchar              __base_type;
1323       atomic() noexcept= default;
1324       ~atomic() noexcept = default;
1325       atomic(const atomic&) = delete;
1326       atomic& operator=(const atomic&) = delete;
1327       atomic& operator=(const atomic&) volatile = delete;
1329       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1331       using __base_type::operator __integral_type;
1332       using __base_type::operator=;
1333     };
1335   /// Explicit specialization for short.
1336   template<>
1337     struct atomic<short> : public atomic_short
1338     {
1339       typedef short                     __integral_type;
1340       typedef atomic_short              __base_type;
1342       atomic() noexcept = default;
1343       ~atomic() noexcept = default;
1344       atomic(const atomic&) = delete;
1345       atomic& operator=(const atomic&) = delete;
1346       atomic& operator=(const atomic&) volatile = delete;
1348       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1350       using __base_type::operator __integral_type;
1351       using __base_type::operator=;
1352     };
1354   /// Explicit specialization for unsigned short.
1355   template<>
1356     struct atomic<unsigned short> : public atomic_ushort
1357     {
1358       typedef unsigned short            __integral_type;
1359       typedef atomic_ushort             __base_type;
1361       atomic() noexcept = default;
1362       ~atomic() noexcept = default;
1363       atomic(const atomic&) = delete;
1364       atomic& operator=(const atomic&) = delete;
1365       atomic& operator=(const atomic&) volatile = delete;
1367       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1369       using __base_type::operator __integral_type;
1370       using __base_type::operator=;
1371     };
1373   /// Explicit specialization for int.
1374   template<>
1375     struct atomic<int> : atomic_int
1376     {
1377       typedef int                       __integral_type;
1378       typedef atomic_int                __base_type;
1380       atomic() noexcept = default;
1381       ~atomic() noexcept = default;
1382       atomic(const atomic&) = delete;
1383       atomic& operator=(const atomic&) = delete;
1384       atomic& operator=(const atomic&) volatile = delete;
1386       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1388       using __base_type::operator __integral_type;
1389       using __base_type::operator=;
1390     };
1392   /// Explicit specialization for unsigned int.
1393   template<>
1394     struct atomic<unsigned int> : public atomic_uint
1395     {
1396       typedef unsigned int              __integral_type;
1397       typedef atomic_uint               __base_type;
1399       atomic() noexcept = default;
1400       ~atomic() noexcept = default;
1401       atomic(const atomic&) = delete;
1402       atomic& operator=(const atomic&) = delete;
1403       atomic& operator=(const atomic&) volatile = delete;
1405       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1407       using __base_type::operator __integral_type;
1408       using __base_type::operator=;
1409     };
1411   /// Explicit specialization for long.
1412   template<>
1413     struct atomic<long> : public atomic_long
1414     {
1415       typedef long                      __integral_type;
1416       typedef atomic_long               __base_type;
1418       atomic() noexcept = default;
1419       ~atomic() noexcept = default;
1420       atomic(const atomic&) = delete;
1421       atomic& operator=(const atomic&) = delete;
1422       atomic& operator=(const atomic&) volatile = delete;
1424       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1426       using __base_type::operator __integral_type;
1427       using __base_type::operator=;
1428     };
1430   /// Explicit specialization for unsigned long.
1431   template<>
1432     struct atomic<unsigned long> : public atomic_ulong
1433     {
1434       typedef unsigned long             __integral_type;
1435       typedef atomic_ulong              __base_type;
1437       atomic() noexcept = default;
1438       ~atomic() noexcept = default;
1439       atomic(const atomic&) = delete;
1440       atomic& operator=(const atomic&) = delete;
1441       atomic& operator=(const atomic&) volatile = delete;
1443       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1445       using __base_type::operator __integral_type;
1446       using __base_type::operator=;
1447     };
1449   /// Explicit specialization for long long.
1450   template<>
1451     struct atomic<long long> : public atomic_llong
1452     {
1453       typedef long long                 __integral_type;
1454       typedef atomic_llong              __base_type;
1456       atomic() noexcept = default;
1457       ~atomic() noexcept = default;
1458       atomic(const atomic&) = delete;
1459       atomic& operator=(const atomic&) = delete;
1460       atomic& operator=(const atomic&) volatile = delete;
1462       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1464       using __base_type::operator __integral_type;
1465       using __base_type::operator=;
1466     };
1468   /// Explicit specialization for unsigned long long.
1469   template<>
1470     struct atomic<unsigned long long> : public atomic_ullong
1471     {
1472       typedef unsigned long long        __integral_type;
1473       typedef atomic_ullong             __base_type;
1475       atomic() noexcept = default;
1476       ~atomic() noexcept = default;
1477       atomic(const atomic&) = delete;
1478       atomic& operator=(const atomic&) = delete;
1479       atomic& operator=(const atomic&) volatile = delete;
1481       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1483       using __base_type::operator __integral_type;
1484       using __base_type::operator=;
1485     };
1487   /// Explicit specialization for wchar_t.
1488   template<>
1489     struct atomic<wchar_t> : public atomic_wchar_t
1490     {
1491       typedef wchar_t                   __integral_type;
1492       typedef atomic_wchar_t            __base_type;
1494       atomic() noexcept = default;
1495       ~atomic() noexcept = default;
1496       atomic(const atomic&) = delete;
1497       atomic& operator=(const atomic&) = delete;
1498       atomic& operator=(const atomic&) volatile = delete;
1500       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1502       using __base_type::operator __integral_type;
1503       using __base_type::operator=;
1504     };
1506   /// Explicit specialization for char16_t.
1507   template<>
1508     struct atomic<char16_t> : public atomic_char16_t
1509     {
1510       typedef char16_t                  __integral_type;
1511       typedef atomic_char16_t           __base_type;
1513       atomic() noexcept = default;
1514       ~atomic() noexcept = default;
1515       atomic(const atomic&) = delete;
1516       atomic& operator=(const atomic&) = delete;
1517       atomic& operator=(const atomic&) volatile = delete;
1519       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1521       using __base_type::operator __integral_type;
1522       using __base_type::operator=;
1523     };
1525   /// Explicit specialization for char32_t.
1526   template<>
1527     struct atomic<char32_t> : public atomic_char32_t
1528     {
1529       typedef char32_t                  __integral_type;
1530       typedef atomic_char32_t           __base_type;
1532       atomic() noexcept = default;
1533       ~atomic() noexcept = default;
1534       atomic(const atomic&) = delete;
1535       atomic& operator=(const atomic&) = delete;
1536       atomic& operator=(const atomic&) volatile = delete;
1538       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1540       using __base_type::operator __integral_type;
1541       using __base_type::operator=;
1542     };
1545   // Function definitions, atomic_flag operations.
1546   inline __libitm_always_inline bool
1547   atomic_flag_test_and_set_explicit(atomic_flag* __a,
1548                                     memory_order __m) noexcept
1549   { return __a->test_and_set(__m); }
1551   inline __libitm_always_inline bool
1552   atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
1553                                     memory_order __m) noexcept
1554   { return __a->test_and_set(__m); }
1556   inline __libitm_always_inline void
1557   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
1558   { __a->clear(__m); }
1560   inline __libitm_always_inline void
1561   atomic_flag_clear_explicit(volatile atomic_flag* __a,
1562                              memory_order __m) noexcept
1563   { __a->clear(__m); }
1565   inline __libitm_always_inline bool
1566   atomic_flag_test_and_set(atomic_flag* __a) noexcept
1567   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1569   inline __libitm_always_inline bool
1570   atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
1571   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1573   inline __libitm_always_inline void
1574   atomic_flag_clear(atomic_flag* __a) noexcept
1575   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1577   inline __libitm_always_inline void
1578   atomic_flag_clear(volatile atomic_flag* __a) noexcept
1579   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1582   // Function templates generally applicable to atomic types.
1583   template<typename _ITp>
1584     __libitm_always_inline bool
1585     atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
1586     { return __a->is_lock_free(); }
1588   template<typename _ITp>
1589     __libitm_always_inline bool
1590     atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
1591     { return __a->is_lock_free(); }
1593   template<typename _ITp>
1594     __libitm_always_inline void
1595     atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
1597   template<typename _ITp>
1598     __libitm_always_inline void
1599     atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
1601   template<typename _ITp>
1602     __libitm_always_inline void
1603     atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
1604                           memory_order __m) noexcept
1605     { __a->store(__i, __m); }
1607   template<typename _ITp>
1608     __libitm_always_inline void
1609     atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
1610                           memory_order __m) noexcept
1611     { __a->store(__i, __m); }
1613   template<typename _ITp>
1614     __libitm_always_inline _ITp
1615     atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
1616     { return __a->load(__m); }
1618   template<typename _ITp>
1619     __libitm_always_inline _ITp
1620     atomic_load_explicit(const volatile atomic<_ITp>* __a,
1621                          memory_order __m) noexcept
1622     { return __a->load(__m); }
1624   template<typename _ITp>
1625     __libitm_always_inline _ITp
1626     atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
1627                              memory_order __m) noexcept
1628     { return __a->exchange(__i, __m); }
1630   template<typename _ITp>
1631     __libitm_always_inline _ITp
1632     atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
1633                              memory_order __m) noexcept
1634     { return __a->exchange(__i, __m); }
1636   template<typename _ITp>
1637     __libitm_always_inline bool
1638     atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
1639                                           _ITp* __i1, _ITp __i2,
1640                                           memory_order __m1,
1641                                           memory_order __m2) noexcept
1642     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1644   template<typename _ITp>
1645     __libitm_always_inline bool
1646     atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
1647                                           _ITp* __i1, _ITp __i2,
1648                                           memory_order __m1,
1649                                           memory_order __m2) noexcept
1650     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1652   template<typename _ITp>
1653     __libitm_always_inline bool
1654     atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
1655                                             _ITp* __i1, _ITp __i2,
1656                                             memory_order __m1,
1657                                             memory_order __m2) noexcept
1658     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1660   template<typename _ITp>
1661     __libitm_always_inline bool
1662     atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
1663                                             _ITp* __i1, _ITp __i2,
1664                                             memory_order __m1,
1665                                             memory_order __m2) noexcept
1666     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1669   template<typename _ITp>
1670     __libitm_always_inline void
1671     atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
1672     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1674   template<typename _ITp>
1675     __libitm_always_inline void
1676     atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1677     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1679   template<typename _ITp>
1680     __libitm_always_inline _ITp
1681     atomic_load(const atomic<_ITp>* __a) noexcept
1682     { return atomic_load_explicit(__a, memory_order_seq_cst); }
1684   template<typename _ITp>
1685     __libitm_always_inline _ITp
1686     atomic_load(const volatile atomic<_ITp>* __a) noexcept
1687     { return atomic_load_explicit(__a, memory_order_seq_cst); }
1689   template<typename _ITp>
1690     __libitm_always_inline _ITp
1691     atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
1692     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1694   template<typename _ITp>
1695     __libitm_always_inline _ITp
1696     atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1697     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1699   template<typename _ITp>
1700     __libitm_always_inline bool
1701     atomic_compare_exchange_weak(atomic<_ITp>* __a,
1702                                  _ITp* __i1, _ITp __i2) noexcept
1703     {
1704       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1705                                                    memory_order_seq_cst,
1706                                                    memory_order_seq_cst);
1707     }
1709   template<typename _ITp>
1710     __libitm_always_inline bool
1711     atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
1712                                  _ITp* __i1, _ITp __i2) noexcept
1713     {
1714       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1715                                                    memory_order_seq_cst,
1716                                                    memory_order_seq_cst);
1717     }
1719   template<typename _ITp>
1720     __libitm_always_inline bool
1721     atomic_compare_exchange_strong(atomic<_ITp>* __a,
1722                                    _ITp* __i1, _ITp __i2) noexcept
1723     {
1724       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1725                                                      memory_order_seq_cst,
1726                                                      memory_order_seq_cst);
1727     }
1729   template<typename _ITp>
1730     __libitm_always_inline bool
1731     atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
1732                                    _ITp* __i1, _ITp __i2) noexcept
1733     {
1734       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1735                                                      memory_order_seq_cst,
1736                                                      memory_order_seq_cst);
1737     }
1739   // Function templates for atomic_integral operations only, using
1740   // __atomic_base. Template argument should be constricted to
1741   // intergral types as specified in the standard, excluding address
1742   // types.
1743   template<typename _ITp>
1744     __libitm_always_inline _ITp
1745     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1746                               memory_order __m) noexcept
1747     { return __a->fetch_add(__i, __m); }
1749   template<typename _ITp>
1750     __libitm_always_inline _ITp
1751     atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1752                               memory_order __m) noexcept
1753     { return __a->fetch_add(__i, __m); }
1755   template<typename _ITp>
1756     __libitm_always_inline _ITp
1757     atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1758                               memory_order __m) noexcept
1759     { return __a->fetch_sub(__i, __m); }
1761   template<typename _ITp>
1762     __libitm_always_inline _ITp
1763     atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1764                               memory_order __m) noexcept
1765     { return __a->fetch_sub(__i, __m); }
1767   template<typename _ITp>
1768     __libitm_always_inline _ITp
1769     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1770                               memory_order __m) noexcept
1771     { return __a->fetch_and(__i, __m); }
1773   template<typename _ITp>
1774     __libitm_always_inline _ITp
1775     atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1776                               memory_order __m) noexcept
1777     { return __a->fetch_and(__i, __m); }
1779   template<typename _ITp>
1780     __libitm_always_inline _ITp
1781     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1782                              memory_order __m) noexcept
1783     { return __a->fetch_or(__i, __m); }
1785   template<typename _ITp>
1786     __libitm_always_inline _ITp
1787     atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1788                              memory_order __m) noexcept
1789     { return __a->fetch_or(__i, __m); }
1791   template<typename _ITp>
1792     __libitm_always_inline _ITp
1793     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1794                               memory_order __m) noexcept
1795     { return __a->fetch_xor(__i, __m); }
1797   template<typename _ITp>
1798     __libitm_always_inline _ITp
1799     atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1800                               memory_order __m) noexcept
1801     { return __a->fetch_xor(__i, __m); }
1803   template<typename _ITp>
1804     __libitm_always_inline _ITp
1805     atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1806     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1808   template<typename _ITp>
1809     __libitm_always_inline _ITp
1810     atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1811     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1813   template<typename _ITp>
1814     __libitm_always_inline _ITp
1815     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1816     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1818   template<typename _ITp>
1819     __libitm_always_inline _ITp
1820     atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1821     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1823   template<typename _ITp>
1824     __libitm_always_inline _ITp
1825     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1826     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1828   template<typename _ITp>
1829     __libitm_always_inline _ITp
1830     atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1831     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1833   template<typename _ITp>
1834     __libitm_always_inline _ITp
1835     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1836     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1838   template<typename _ITp>
1839     __libitm_always_inline _ITp
1840     atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1841     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1843   template<typename _ITp>
1844     __libitm_always_inline _ITp
1845     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1846     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1848   template<typename _ITp>
1849     __libitm_always_inline _ITp
1850     atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1851     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1854   // Partial specializations for pointers.
1855   template<typename _ITp>
1856     __libitm_always_inline _ITp*
1857     atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1858                               memory_order __m) noexcept
1859     { return __a->fetch_add(__d, __m); }
1861   template<typename _ITp>
1862     __libitm_always_inline _ITp*
1863     atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1864                               memory_order __m) noexcept
1865     { return __a->fetch_add(__d, __m); }
1867   template<typename _ITp>
1868     __libitm_always_inline _ITp*
1869     atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1870     { return __a->fetch_add(__d); }
1872   template<typename _ITp>
1873     __libitm_always_inline _ITp*
1874     atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1875     { return __a->fetch_add(__d); }
1877   template<typename _ITp>
1878     __libitm_always_inline _ITp*
1879     atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1880                               ptrdiff_t __d, memory_order __m) noexcept
1881     { return __a->fetch_sub(__d, __m); }
1883   template<typename _ITp>
1884     __libitm_always_inline _ITp*
1885     atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1886                               memory_order __m) noexcept
1887     { return __a->fetch_sub(__d, __m); }
1889   template<typename _ITp>
1890     __libitm_always_inline _ITp*
1891     atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1892     { return __a->fetch_sub(__d); }
1894   template<typename _ITp>
1895     __libitm_always_inline _ITp*
1896     atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1897     { return __a->fetch_sub(__d); }
1898   // @} group atomics
1900 // _GLIBCXX_END_NAMESPACE_VERSION
1901 } // namespace
1903 #endif