Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libstdc++-v3 / include / bits / atomic_base.h
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 bits/atomic_base.h
26  *  This is an internal header file, included by other library headers.
27  *  Do not attempt to use it directly. @headername{atomic}
28  */
29
30 #ifndef _GLIBCXX_ATOMIC_BASE_H
31 #define _GLIBCXX_ATOMIC_BASE_H 1
32
33 #pragma GCC system_header
34
35 #include <bits/c++config.h>
36 #include <stdbool.h>
37 #include <stdint.h>
38 #include <bits/atomic_lockfree_defines.h>
39
40 namespace std _GLIBCXX_VISIBILITY(default)
41 {
42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43
44   /**
45    * @defgroup atomics Atomics
46    *
47    * Components for performing atomic operations.
48    * @{
49    */
50
51   /// Enumeration for memory_order
52   typedef enum memory_order
53     {
54       memory_order_relaxed,
55       memory_order_consume,
56       memory_order_acquire,
57       memory_order_release,
58       memory_order_acq_rel,
59       memory_order_seq_cst
60     } memory_order;
61
62   enum __memory_order_modifier
63     {
64       __memory_order_mask          = 0x0ffff,
65       __memory_order_modifier_mask = 0xffff0000,
66       __memory_order_hle_acquire   = 0x10000,
67       __memory_order_hle_release   = 0x20000
68     };
69
70   constexpr memory_order
71   operator|(memory_order __m, __memory_order_modifier __mod)
72   {
73     return memory_order(__m | int(__mod));
74   }
75
76   constexpr memory_order
77   operator&(memory_order __m, __memory_order_modifier __mod)
78   {
79     return memory_order(__m & int(__mod));
80   }
81
82   // Drop release ordering as per [atomics.types.operations.req]/21
83   constexpr memory_order
84   __cmpexch_failure_order2(memory_order __m) noexcept
85   {
86     return __m == memory_order_acq_rel ? memory_order_acquire
87       : __m == memory_order_release ? memory_order_relaxed : __m;
88   }
89
90   constexpr memory_order
91   __cmpexch_failure_order(memory_order __m) noexcept
92   {
93     return memory_order(__cmpexch_failure_order2(__m & __memory_order_mask)
94       | (__m & __memory_order_modifier_mask));
95   }
96
97   inline void
98   atomic_thread_fence(memory_order __m) noexcept
99   { __atomic_thread_fence(__m); }
100
101   inline void
102   atomic_signal_fence(memory_order __m) noexcept
103   { __atomic_signal_fence(__m); }
104
105   /// kill_dependency
106   template<typename _Tp>
107     inline _Tp
108     kill_dependency(_Tp __y) noexcept
109     {
110       _Tp __ret(__y);
111       return __ret;
112     }
113
114
115   // Base types for atomics.
116   template<typename _IntTp>
117     struct __atomic_base;
118
119   /// atomic_char
120   typedef __atomic_base<char>                   atomic_char;
121
122   /// atomic_schar
123   typedef __atomic_base<signed char>            atomic_schar;
124
125   /// atomic_uchar
126   typedef __atomic_base<unsigned char>          atomic_uchar;
127
128   /// atomic_short
129   typedef __atomic_base<short>                  atomic_short;
130
131   /// atomic_ushort
132   typedef __atomic_base<unsigned short>         atomic_ushort;
133
134   /// atomic_int
135   typedef __atomic_base<int>                    atomic_int;
136
137   /// atomic_uint
138   typedef __atomic_base<unsigned int>           atomic_uint;
139
140   /// atomic_long
141   typedef __atomic_base<long>                   atomic_long;
142
143   /// atomic_ulong
144   typedef __atomic_base<unsigned long>          atomic_ulong;
145
146   /// atomic_llong
147   typedef __atomic_base<long long>              atomic_llong;
148
149   /// atomic_ullong
150   typedef __atomic_base<unsigned long long>     atomic_ullong;
151
152   /// atomic_wchar_t
153   typedef __atomic_base<wchar_t>                atomic_wchar_t;
154
155   /// atomic_char16_t
156   typedef __atomic_base<char16_t>               atomic_char16_t;
157
158   /// atomic_char32_t
159   typedef __atomic_base<char32_t>               atomic_char32_t;
160
161   /// atomic_char32_t
162   typedef __atomic_base<char32_t>               atomic_char32_t;
163
164
165   /// atomic_int_least8_t
166   typedef __atomic_base<int_least8_t>           atomic_int_least8_t;
167
168   /// atomic_uint_least8_t
169   typedef __atomic_base<uint_least8_t>          atomic_uint_least8_t;
170
171   /// atomic_int_least16_t
172   typedef __atomic_base<int_least16_t>          atomic_int_least16_t;
173
174   /// atomic_uint_least16_t
175   typedef __atomic_base<uint_least16_t>         atomic_uint_least16_t;
176
177   /// atomic_int_least32_t
178   typedef __atomic_base<int_least32_t>          atomic_int_least32_t;
179
180   /// atomic_uint_least32_t
181   typedef __atomic_base<uint_least32_t>         atomic_uint_least32_t;
182
183   /// atomic_int_least64_t
184   typedef __atomic_base<int_least64_t>          atomic_int_least64_t;
185
186   /// atomic_uint_least64_t
187   typedef __atomic_base<uint_least64_t>         atomic_uint_least64_t;
188
189
190   /// atomic_int_fast8_t
191   typedef __atomic_base<int_fast8_t>            atomic_int_fast8_t;
192
193   /// atomic_uint_fast8_t
194   typedef __atomic_base<uint_fast8_t>           atomic_uint_fast8_t;
195
196   /// atomic_int_fast16_t
197   typedef __atomic_base<int_fast16_t>           atomic_int_fast16_t;
198
199   /// atomic_uint_fast16_t
200   typedef __atomic_base<uint_fast16_t>          atomic_uint_fast16_t;
201
202   /// atomic_int_fast32_t
203   typedef __atomic_base<int_fast32_t>           atomic_int_fast32_t;
204
205   /// atomic_uint_fast32_t
206   typedef __atomic_base<uint_fast32_t>          atomic_uint_fast32_t;
207
208   /// atomic_int_fast64_t
209   typedef __atomic_base<int_fast64_t>           atomic_int_fast64_t;
210
211   /// atomic_uint_fast64_t
212   typedef __atomic_base<uint_fast64_t>          atomic_uint_fast64_t;
213
214
215   /// atomic_intptr_t
216   typedef __atomic_base<intptr_t>               atomic_intptr_t;
217
218   /// atomic_uintptr_t
219   typedef __atomic_base<uintptr_t>              atomic_uintptr_t;
220
221   /// atomic_size_t
222   typedef __atomic_base<size_t>                 atomic_size_t;
223
224   /// atomic_intmax_t
225   typedef __atomic_base<intmax_t>               atomic_intmax_t;
226
227   /// atomic_uintmax_t
228   typedef __atomic_base<uintmax_t>              atomic_uintmax_t;
229
230   /// atomic_ptrdiff_t
231   typedef __atomic_base<ptrdiff_t>              atomic_ptrdiff_t;
232
233
234 #define ATOMIC_VAR_INIT(_VI) { _VI }
235
236   template<typename _Tp>
237     struct atomic;
238
239   template<typename _Tp>
240     struct atomic<_Tp*>;
241
242     /* The target's "set" value for test-and-set may not be exactly 1.  */
243 #if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1
244     typedef bool __atomic_flag_data_type;
245 #else
246     typedef unsigned char __atomic_flag_data_type;
247 #endif
248
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
260
261   struct __atomic_flag_base
262   {
263     __atomic_flag_data_type _M_i;
264   };
265
266   _GLIBCXX_END_EXTERN_C
267
268 #define ATOMIC_FLAG_INIT { 0 }
269
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;
278
279     // Conversion to ATOMIC_FLAG_INIT.
280     constexpr atomic_flag(bool __i) noexcept
281       : __atomic_flag_base{ _S_init(__i) }
282     { }
283
284     bool
285     test_and_set(memory_order __m = memory_order_seq_cst) noexcept
286     {
287       return __atomic_test_and_set (&_M_i, __m);
288     }
289
290     bool
291     test_and_set(memory_order __m = memory_order_seq_cst) volatile noexcept
292     {
293       return __atomic_test_and_set (&_M_i, __m);
294     }
295
296     void
297     clear(memory_order __m = memory_order_seq_cst) noexcept
298     {
299       memory_order __b = __m & __memory_order_mask;
300       __glibcxx_assert(__b != memory_order_consume);
301       __glibcxx_assert(__b != memory_order_acquire);
302       __glibcxx_assert(__b != memory_order_acq_rel);
303
304       __atomic_clear (&_M_i, __m);
305     }
306
307     void
308     clear(memory_order __m = memory_order_seq_cst) volatile noexcept
309     {
310       memory_order __b = __m & __memory_order_mask;
311       __glibcxx_assert(__b != memory_order_consume);
312       __glibcxx_assert(__b != memory_order_acquire);
313       __glibcxx_assert(__b != memory_order_acq_rel);
314
315       __atomic_clear (&_M_i, __m);
316     }
317
318   private:
319     static constexpr __atomic_flag_data_type
320     _S_init(bool __i)
321     { return __i ? __GCC_ATOMIC_TEST_AND_SET_TRUEVAL : 0; }
322   };
323
324
325   /// Base class for atomic integrals.
326   //
327   // For each of the integral types, define atomic_[integral type] struct
328   //
329   // atomic_bool     bool
330   // atomic_char     char
331   // atomic_schar    signed char
332   // atomic_uchar    unsigned char
333   // atomic_short    short
334   // atomic_ushort   unsigned short
335   // atomic_int      int
336   // atomic_uint     unsigned int
337   // atomic_long     long
338   // atomic_ulong    unsigned long
339   // atomic_llong    long long
340   // atomic_ullong   unsigned long long
341   // atomic_char16_t char16_t
342   // atomic_char32_t char32_t
343   // atomic_wchar_t  wchar_t
344   //
345   // NB: Assuming _ITp is an integral scalar type that is 1, 2, 4, or
346   // 8 bytes, since that is what GCC built-in functions for atomic
347   // memory access expect.
348   template<typename _ITp>
349     struct __atomic_base
350     {
351     private:
352       typedef _ITp      __int_type;
353
354       __int_type        _M_i;
355
356     public:
357       __atomic_base() noexcept = default;
358       ~__atomic_base() noexcept = default;
359       __atomic_base(const __atomic_base&) = delete;
360       __atomic_base& operator=(const __atomic_base&) = delete;
361       __atomic_base& operator=(const __atomic_base&) volatile = delete;
362
363       // Requires __int_type convertible to _M_i.
364       constexpr __atomic_base(__int_type __i) noexcept : _M_i (__i) { }
365
366       operator __int_type() const noexcept
367       { return load(); }
368
369       operator __int_type() const volatile noexcept
370       { return load(); }
371
372       __int_type
373       operator=(__int_type __i) noexcept
374       {
375         store(__i);
376         return __i;
377       }
378
379       __int_type
380       operator=(__int_type __i) volatile noexcept
381       {
382         store(__i);
383         return __i;
384       }
385
386       __int_type
387       operator++(int) noexcept
388       { return fetch_add(1); }
389
390       __int_type
391       operator++(int) volatile noexcept
392       { return fetch_add(1); }
393
394       __int_type
395       operator--(int) noexcept
396       { return fetch_sub(1); }
397
398       __int_type
399       operator--(int) volatile noexcept
400       { return fetch_sub(1); }
401
402       __int_type
403       operator++() noexcept
404       { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
405
406       __int_type
407       operator++() volatile noexcept
408       { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
409
410       __int_type
411       operator--() noexcept
412       { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
413
414       __int_type
415       operator--() volatile noexcept
416       { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
417
418       __int_type
419       operator+=(__int_type __i) noexcept
420       { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
421
422       __int_type
423       operator+=(__int_type __i) volatile noexcept
424       { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
425
426       __int_type
427       operator-=(__int_type __i) noexcept
428       { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
429
430       __int_type
431       operator-=(__int_type __i) volatile noexcept
432       { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
433
434       __int_type
435       operator&=(__int_type __i) noexcept
436       { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
437
438       __int_type
439       operator&=(__int_type __i) volatile noexcept
440       { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
441
442       __int_type
443       operator|=(__int_type __i) noexcept
444       { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
445
446       __int_type
447       operator|=(__int_type __i) volatile noexcept
448       { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
449
450       __int_type
451       operator^=(__int_type __i) noexcept
452       { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
453
454       __int_type
455       operator^=(__int_type __i) volatile noexcept
456       { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
457
458       bool
459       is_lock_free() const noexcept
460       { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
461
462       bool
463       is_lock_free() const volatile noexcept
464       { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
465
466       void
467       store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept
468       {
469         memory_order __b = __m & __memory_order_mask;
470         __glibcxx_assert(__b != memory_order_acquire);
471         __glibcxx_assert(__b != memory_order_acq_rel);
472         __glibcxx_assert(__b != memory_order_consume);
473
474         __atomic_store_n(&_M_i, __i, __m);
475       }
476
477       void
478       store(__int_type __i,
479             memory_order __m = memory_order_seq_cst) volatile noexcept
480       {
481         memory_order __b = __m & __memory_order_mask;
482         __glibcxx_assert(__b != memory_order_acquire);
483         __glibcxx_assert(__b != memory_order_acq_rel);
484         __glibcxx_assert(__b != memory_order_consume);
485
486         __atomic_store_n(&_M_i, __i, __m);
487       }
488
489       __int_type
490       load(memory_order __m = memory_order_seq_cst) const noexcept
491       {
492        memory_order __b = __m & __memory_order_mask;
493         __glibcxx_assert(__b != memory_order_release);
494         __glibcxx_assert(__b != memory_order_acq_rel);
495
496         return __atomic_load_n(&_M_i, __m);
497       }
498
499       __int_type
500       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
501       {
502         memory_order __b = __m & __memory_order_mask;
503         __glibcxx_assert(__b != memory_order_release);
504         __glibcxx_assert(__b != memory_order_acq_rel);
505
506         return __atomic_load_n(&_M_i, __m);
507       }
508
509       __int_type
510       exchange(__int_type __i,
511                memory_order __m = memory_order_seq_cst) noexcept
512       {
513         return __atomic_exchange_n(&_M_i, __i, __m);
514       }
515
516
517       __int_type
518       exchange(__int_type __i,
519                memory_order __m = memory_order_seq_cst) volatile noexcept
520       {
521         return __atomic_exchange_n(&_M_i, __i, __m);
522       }
523
524       bool
525       compare_exchange_weak(__int_type& __i1, __int_type __i2,
526                             memory_order __m1, memory_order __m2) noexcept
527       {
528        memory_order __b2 = __m2 & __memory_order_mask;
529        memory_order __b1 = __m1 & __memory_order_mask;
530         __glibcxx_assert(__b2 != memory_order_release);
531         __glibcxx_assert(__b2 != memory_order_acq_rel);
532         __glibcxx_assert(__b2 <= __b1);
533
534         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
535       }
536
537       bool
538       compare_exchange_weak(__int_type& __i1, __int_type __i2,
539                             memory_order __m1,
540                             memory_order __m2) volatile noexcept
541       {
542        memory_order __b2 = __m2 & __memory_order_mask;
543        memory_order __b1 = __m1 & __memory_order_mask;
544         __glibcxx_assert(__b2 != memory_order_release);
545         __glibcxx_assert(__b2 != memory_order_acq_rel);
546         __glibcxx_assert(__b2 <= __b1);
547
548         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
549       }
550
551       bool
552       compare_exchange_weak(__int_type& __i1, __int_type __i2,
553                             memory_order __m = memory_order_seq_cst) noexcept
554       {
555         return compare_exchange_weak(__i1, __i2, __m,
556                                      __cmpexch_failure_order(__m));
557       }
558
559       bool
560       compare_exchange_weak(__int_type& __i1, __int_type __i2,
561                    memory_order __m = memory_order_seq_cst) volatile noexcept
562       {
563         return compare_exchange_weak(__i1, __i2, __m,
564                                      __cmpexch_failure_order(__m));
565       }
566
567       bool
568       compare_exchange_strong(__int_type& __i1, __int_type __i2,
569                               memory_order __m1, memory_order __m2) noexcept
570       {
571         memory_order __b2 = __m2 & __memory_order_mask;
572         memory_order __b1 = __m1 & __memory_order_mask;
573         __glibcxx_assert(__b2 != memory_order_release);
574         __glibcxx_assert(__b2 != memory_order_acq_rel);
575         __glibcxx_assert(__b2 <= __b1);
576
577         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
578       }
579
580       bool
581       compare_exchange_strong(__int_type& __i1, __int_type __i2,
582                               memory_order __m1,
583                               memory_order __m2) volatile noexcept
584       {
585         memory_order __b2 = __m2 & __memory_order_mask;
586         memory_order __b1 = __m1 & __memory_order_mask;
587
588         __glibcxx_assert(__b2 != memory_order_release);
589         __glibcxx_assert(__b2 != memory_order_acq_rel);
590         __glibcxx_assert(__b2 <= __b1);
591
592         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
593       }
594
595       bool
596       compare_exchange_strong(__int_type& __i1, __int_type __i2,
597                               memory_order __m = memory_order_seq_cst) noexcept
598       {
599         return compare_exchange_strong(__i1, __i2, __m,
600                                        __cmpexch_failure_order(__m));
601       }
602
603       bool
604       compare_exchange_strong(__int_type& __i1, __int_type __i2,
605                  memory_order __m = memory_order_seq_cst) volatile noexcept
606       {
607         return compare_exchange_strong(__i1, __i2, __m,
608                                        __cmpexch_failure_order(__m));
609       }
610
611       __int_type
612       fetch_add(__int_type __i,
613                 memory_order __m = memory_order_seq_cst) noexcept
614       { return __atomic_fetch_add(&_M_i, __i, __m); }
615
616       __int_type
617       fetch_add(__int_type __i,
618                 memory_order __m = memory_order_seq_cst) volatile noexcept
619       { return __atomic_fetch_add(&_M_i, __i, __m); }
620
621       __int_type
622       fetch_sub(__int_type __i,
623                 memory_order __m = memory_order_seq_cst) noexcept
624       { return __atomic_fetch_sub(&_M_i, __i, __m); }
625
626       __int_type
627       fetch_sub(__int_type __i,
628                 memory_order __m = memory_order_seq_cst) volatile noexcept
629       { return __atomic_fetch_sub(&_M_i, __i, __m); }
630
631       __int_type
632       fetch_and(__int_type __i,
633                 memory_order __m = memory_order_seq_cst) noexcept
634       { return __atomic_fetch_and(&_M_i, __i, __m); }
635
636       __int_type
637       fetch_and(__int_type __i,
638                 memory_order __m = memory_order_seq_cst) volatile noexcept
639       { return __atomic_fetch_and(&_M_i, __i, __m); }
640
641       __int_type
642       fetch_or(__int_type __i,
643                memory_order __m = memory_order_seq_cst) noexcept
644       { return __atomic_fetch_or(&_M_i, __i, __m); }
645
646       __int_type
647       fetch_or(__int_type __i,
648                memory_order __m = memory_order_seq_cst) volatile noexcept
649       { return __atomic_fetch_or(&_M_i, __i, __m); }
650
651       __int_type
652       fetch_xor(__int_type __i,
653                 memory_order __m = memory_order_seq_cst) noexcept
654       { return __atomic_fetch_xor(&_M_i, __i, __m); }
655
656       __int_type
657       fetch_xor(__int_type __i,
658                 memory_order __m = memory_order_seq_cst) volatile noexcept
659       { return __atomic_fetch_xor(&_M_i, __i, __m); }
660     };
661
662
663   /// Partial specialization for pointer types.
664   template<typename _PTp>
665     struct __atomic_base<_PTp*>
666     {
667     private:
668       typedef _PTp*     __pointer_type;
669
670       __pointer_type    _M_p;
671
672       // Factored out to facilitate explicit specialization.
673       constexpr ptrdiff_t
674       _M_type_size(ptrdiff_t __d) { return __d * sizeof(_PTp); }
675
676       constexpr ptrdiff_t
677       _M_type_size(ptrdiff_t __d) volatile { return __d * sizeof(_PTp); }
678
679     public:
680       __atomic_base() noexcept = default;
681       ~__atomic_base() noexcept = default;
682       __atomic_base(const __atomic_base&) = delete;
683       __atomic_base& operator=(const __atomic_base&) = delete;
684       __atomic_base& operator=(const __atomic_base&) volatile = delete;
685
686       // Requires __pointer_type convertible to _M_p.
687       constexpr __atomic_base(__pointer_type __p) noexcept : _M_p (__p) { }
688
689       operator __pointer_type() const noexcept
690       { return load(); }
691
692       operator __pointer_type() const volatile noexcept
693       { return load(); }
694
695       __pointer_type
696       operator=(__pointer_type __p) noexcept
697       {
698         store(__p);
699         return __p;
700       }
701
702       __pointer_type
703       operator=(__pointer_type __p) volatile noexcept
704       {
705         store(__p);
706         return __p;
707       }
708
709       __pointer_type
710       operator++(int) noexcept
711       { return fetch_add(1); }
712
713       __pointer_type
714       operator++(int) volatile noexcept
715       { return fetch_add(1); }
716
717       __pointer_type
718       operator--(int) noexcept
719       { return fetch_sub(1); }
720
721       __pointer_type
722       operator--(int) volatile noexcept
723       { return fetch_sub(1); }
724
725       __pointer_type
726       operator++() noexcept
727       { return __atomic_add_fetch(&_M_p, _M_type_size(1),
728                                   memory_order_seq_cst); }
729
730       __pointer_type
731       operator++() volatile noexcept
732       { return __atomic_add_fetch(&_M_p, _M_type_size(1),
733                                   memory_order_seq_cst); }
734
735       __pointer_type
736       operator--() noexcept
737       { return __atomic_sub_fetch(&_M_p, _M_type_size(1),
738                                   memory_order_seq_cst); }
739
740       __pointer_type
741       operator--() volatile noexcept
742       { return __atomic_sub_fetch(&_M_p, _M_type_size(1),
743                                   memory_order_seq_cst); }
744
745       __pointer_type
746       operator+=(ptrdiff_t __d) noexcept
747       { return __atomic_add_fetch(&_M_p, _M_type_size(__d),
748                                   memory_order_seq_cst); }
749
750       __pointer_type
751       operator+=(ptrdiff_t __d) volatile noexcept
752       { return __atomic_add_fetch(&_M_p, _M_type_size(__d),
753                                   memory_order_seq_cst); }
754
755       __pointer_type
756       operator-=(ptrdiff_t __d) noexcept
757       { return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
758                                   memory_order_seq_cst); }
759
760       __pointer_type
761       operator-=(ptrdiff_t __d) volatile noexcept
762       { return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
763                                   memory_order_seq_cst); }
764
765       bool
766       is_lock_free() const noexcept
767       { return __atomic_is_lock_free(_M_type_size(1), nullptr); }
768
769       bool
770       is_lock_free() const volatile noexcept
771       { return __atomic_is_lock_free(_M_type_size(1), nullptr); }
772
773       void
774       store(__pointer_type __p,
775             memory_order __m = memory_order_seq_cst) noexcept
776       {
777         memory_order __b = __m & __memory_order_mask;
778
779         __glibcxx_assert(__b != memory_order_acquire);
780         __glibcxx_assert(__b != memory_order_acq_rel);
781         __glibcxx_assert(__b != memory_order_consume);
782
783         __atomic_store_n(&_M_p, __p, __m);
784       }
785
786       void
787       store(__pointer_type __p,
788             memory_order __m = memory_order_seq_cst) volatile noexcept
789       {
790         memory_order __b = __m & __memory_order_mask;
791         __glibcxx_assert(__b != memory_order_acquire);
792         __glibcxx_assert(__b != memory_order_acq_rel);
793         __glibcxx_assert(__b != memory_order_consume);
794
795         __atomic_store_n(&_M_p, __p, __m);
796       }
797
798       __pointer_type
799       load(memory_order __m = memory_order_seq_cst) const noexcept
800       {
801         memory_order __b = __m & __memory_order_mask;
802         __glibcxx_assert(__b != memory_order_release);
803         __glibcxx_assert(__b != memory_order_acq_rel);
804
805         return __atomic_load_n(&_M_p, __m);
806       }
807
808       __pointer_type
809       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
810       {
811         memory_order __b = __m & __memory_order_mask;
812         __glibcxx_assert(__b != memory_order_release);
813         __glibcxx_assert(__b != memory_order_acq_rel);
814
815         return __atomic_load_n(&_M_p, __m);
816       }
817
818       __pointer_type
819       exchange(__pointer_type __p,
820                memory_order __m = memory_order_seq_cst) noexcept
821       {
822         return __atomic_exchange_n(&_M_p, __p, __m);
823       }
824
825
826       __pointer_type
827       exchange(__pointer_type __p,
828                memory_order __m = memory_order_seq_cst) volatile noexcept
829       {
830         return __atomic_exchange_n(&_M_p, __p, __m);
831       }
832
833       bool
834       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
835                               memory_order __m1,
836                               memory_order __m2) noexcept
837       {
838         memory_order __b2 = __m2 & __memory_order_mask;
839         memory_order __b1 = __m1 & __memory_order_mask;
840         __glibcxx_assert(__b2 != memory_order_release);
841         __glibcxx_assert(__b2 != memory_order_acq_rel);
842         __glibcxx_assert(__b2 <= __b1);
843
844         return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
845       }
846
847       bool
848       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
849                               memory_order __m1,
850                               memory_order __m2) volatile noexcept
851       {
852         memory_order __b2 = __m2 & __memory_order_mask;
853         memory_order __b1 = __m1 & __memory_order_mask;
854
855         __glibcxx_assert(__b2 != memory_order_release);
856         __glibcxx_assert(__b2 != memory_order_acq_rel);
857         __glibcxx_assert(__b2 <= __b1);
858
859         return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
860       }
861
862       __pointer_type
863       fetch_add(ptrdiff_t __d,
864                 memory_order __m = memory_order_seq_cst) noexcept
865       { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
866
867       __pointer_type
868       fetch_add(ptrdiff_t __d,
869                 memory_order __m = memory_order_seq_cst) volatile noexcept
870       { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
871
872       __pointer_type
873       fetch_sub(ptrdiff_t __d,
874                 memory_order __m = memory_order_seq_cst) noexcept
875       { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
876
877       __pointer_type
878       fetch_sub(ptrdiff_t __d,
879                 memory_order __m = memory_order_seq_cst) volatile noexcept
880       { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
881     };
882
883   // @} group atomics
884
885 _GLIBCXX_END_NAMESPACE_VERSION
886 } // namespace std
887
888 #endif