OSDN Git Service

* include/bits/atomic_base.h (__calculate_memory_order): Rename to...
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / atomic_base.h
1 // -*- C++ -*- header.
2
3 // Copyright (C) 2008, 2009, 2010, 2011 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   // Drop release ordering as per [atomics.types.operations.req]/21
63   constexpr memory_order
64   __cmpexch_failure_order(memory_order __m) noexcept
65   {
66     return __m == memory_order_acq_rel ? memory_order_acquire
67       : __m == memory_order_release ? memory_order_relaxed : __m;
68   }
69
70   inline void
71   atomic_thread_fence(memory_order __m) noexcept
72   { __atomic_thread_fence(__m); }
73
74   inline void
75   atomic_signal_fence(memory_order __m) noexcept
76   { __atomic_thread_fence(__m); }
77
78   /// kill_dependency
79   template<typename _Tp>
80     inline _Tp
81     kill_dependency(_Tp __y) noexcept
82     {
83       _Tp __ret(__y);
84       return __ret;
85     }
86
87
88   // Base types for atomics.
89   template<typename _IntTp>
90     struct __atomic_base;
91
92   /// atomic_char
93   typedef __atomic_base<char>                   atomic_char;
94
95   /// atomic_schar
96   typedef __atomic_base<signed char>            atomic_schar;
97
98   /// atomic_uchar
99   typedef __atomic_base<unsigned char>          atomic_uchar;
100
101   /// atomic_short
102   typedef __atomic_base<short>                  atomic_short;
103
104   /// atomic_ushort
105   typedef __atomic_base<unsigned short>         atomic_ushort;
106
107   /// atomic_int
108   typedef __atomic_base<int>                    atomic_int;
109
110   /// atomic_uint
111   typedef __atomic_base<unsigned int>           atomic_uint;
112
113   /// atomic_long
114   typedef __atomic_base<long>                   atomic_long;
115
116   /// atomic_ulong
117   typedef __atomic_base<unsigned long>          atomic_ulong;
118
119   /// atomic_llong
120   typedef __atomic_base<long long>              atomic_llong;
121
122   /// atomic_ullong
123   typedef __atomic_base<unsigned long long>     atomic_ullong;
124
125   /// atomic_wchar_t
126   typedef __atomic_base<wchar_t>                atomic_wchar_t;
127
128   /// atomic_char16_t
129   typedef __atomic_base<char16_t>               atomic_char16_t;
130
131   /// atomic_char32_t
132   typedef __atomic_base<char32_t>               atomic_char32_t;
133
134   /// atomic_char32_t
135   typedef __atomic_base<char32_t>               atomic_char32_t;
136
137
138   /// atomic_int_least8_t
139   typedef __atomic_base<int_least8_t>           atomic_int_least8_t;
140
141   /// atomic_uint_least8_t
142   typedef __atomic_base<uint_least8_t>          atomic_uint_least8_t;
143
144   /// atomic_int_least16_t
145   typedef __atomic_base<int_least16_t>          atomic_int_least16_t;
146
147   /// atomic_uint_least16_t
148   typedef __atomic_base<uint_least16_t>         atomic_uint_least16_t;
149
150   /// atomic_int_least32_t
151   typedef __atomic_base<int_least32_t>          atomic_int_least32_t;
152
153   /// atomic_uint_least32_t
154   typedef __atomic_base<uint_least32_t>         atomic_uint_least32_t;
155
156   /// atomic_int_least64_t
157   typedef __atomic_base<int_least64_t>          atomic_int_least64_t;
158
159   /// atomic_uint_least64_t
160   typedef __atomic_base<uint_least64_t>         atomic_uint_least64_t;
161
162
163   /// atomic_int_fast8_t
164   typedef __atomic_base<int_fast8_t>            atomic_int_fast8_t;
165
166   /// atomic_uint_fast8_t
167   typedef __atomic_base<uint_fast8_t>           atomic_uint_fast8_t;
168
169   /// atomic_int_fast16_t
170   typedef __atomic_base<int_fast16_t>           atomic_int_fast16_t;
171
172   /// atomic_uint_fast16_t
173   typedef __atomic_base<uint_fast16_t>          atomic_uint_fast16_t;
174
175   /// atomic_int_fast32_t
176   typedef __atomic_base<int_fast32_t>           atomic_int_fast32_t;
177
178   /// atomic_uint_fast32_t
179   typedef __atomic_base<uint_fast32_t>          atomic_uint_fast32_t;
180
181   /// atomic_int_fast64_t
182   typedef __atomic_base<int_fast64_t>           atomic_int_fast64_t;
183
184   /// atomic_uint_fast64_t
185   typedef __atomic_base<uint_fast64_t>          atomic_uint_fast64_t;
186
187
188   /// atomic_intptr_t
189   typedef __atomic_base<intptr_t>               atomic_intptr_t;
190
191   /// atomic_uintptr_t
192   typedef __atomic_base<uintptr_t>              atomic_uintptr_t;
193
194   /// atomic_size_t
195   typedef __atomic_base<size_t>                 atomic_size_t;
196
197   /// atomic_intmax_t
198   typedef __atomic_base<intmax_t>               atomic_intmax_t;
199
200   /// atomic_uintmax_t
201   typedef __atomic_base<uintmax_t>              atomic_uintmax_t;
202
203   /// atomic_ptrdiff_t
204   typedef __atomic_base<ptrdiff_t>              atomic_ptrdiff_t;
205
206
207 #define ATOMIC_VAR_INIT(_VI) { _VI }
208
209   template<typename _Tp>
210     struct atomic;
211
212   template<typename _Tp>
213     struct atomic<_Tp*>;
214
215
216   /**
217    *  @brief Base type for atomic_flag.
218    *
219    *  Base type is POD with data, allowing atomic_flag to derive from
220    *  it and meet the standard layout type requirement. In addition to
221    *  compatibilty with a C interface, this allows different
222    *  implementations of atomic_flag to use the same atomic operation
223    *  functions, via a standard conversion to the __atomic_flag_base
224    *  argument.
225   */
226   _GLIBCXX_BEGIN_EXTERN_C
227
228   struct __atomic_flag_base
229   {
230     bool _M_i;
231   };
232
233   _GLIBCXX_END_EXTERN_C
234
235 #define ATOMIC_FLAG_INIT { false }
236
237   /// atomic_flag
238   struct atomic_flag : public __atomic_flag_base
239   {
240     atomic_flag() noexcept = default;
241     ~atomic_flag() noexcept = default;
242     atomic_flag(const atomic_flag&) = delete;
243     atomic_flag& operator=(const atomic_flag&) = delete;
244     atomic_flag& operator=(const atomic_flag&) volatile = delete;
245
246     // Conversion to ATOMIC_FLAG_INIT.
247     atomic_flag(bool __i) noexcept : __atomic_flag_base({ __i }) { }
248
249     bool
250     test_and_set(memory_order __m = memory_order_seq_cst) noexcept
251     {
252       return __atomic_test_and_set (&_M_i, __m);
253     }
254
255     bool
256     test_and_set(memory_order __m = memory_order_seq_cst) volatile noexcept
257     {
258       return __atomic_test_and_set (&_M_i, __m);
259     }
260
261     void
262     clear(memory_order __m = memory_order_seq_cst) noexcept
263     {
264       __glibcxx_assert(__m != memory_order_consume);
265       __glibcxx_assert(__m != memory_order_acquire);
266       __glibcxx_assert(__m != memory_order_acq_rel);
267
268       __atomic_clear (&_M_i, __m);
269     }
270
271     void
272     clear(memory_order __m = memory_order_seq_cst) volatile noexcept
273     {
274       __glibcxx_assert(__m != memory_order_consume);
275       __glibcxx_assert(__m != memory_order_acquire);
276       __glibcxx_assert(__m != memory_order_acq_rel);
277
278       __atomic_clear (&_M_i, __m);
279     }
280   };
281
282
283   /// Base class for atomic integrals.
284   //
285   // For each of the integral types, define atomic_[integral type] struct
286   //
287   // atomic_bool     bool
288   // atomic_char     char
289   // atomic_schar    signed char
290   // atomic_uchar    unsigned char
291   // atomic_short    short
292   // atomic_ushort   unsigned short
293   // atomic_int      int
294   // atomic_uint     unsigned int
295   // atomic_long     long
296   // atomic_ulong    unsigned long
297   // atomic_llong    long long
298   // atomic_ullong   unsigned long long
299   // atomic_char16_t char16_t
300   // atomic_char32_t char32_t
301   // atomic_wchar_t  wchar_t
302   //
303   // NB: Assuming _ITp is an integral scalar type that is 1, 2, 4, or
304   // 8 bytes, since that is what GCC built-in functions for atomic
305   // memory access expect.
306   template<typename _ITp>
307     struct __atomic_base
308     {
309     private:
310       typedef _ITp      __int_type;
311
312       __int_type        _M_i;
313
314     public:
315       __atomic_base() noexcept = default;
316       ~__atomic_base() noexcept = default;
317       __atomic_base(const __atomic_base&) = delete;
318       __atomic_base& operator=(const __atomic_base&) = delete;
319       __atomic_base& operator=(const __atomic_base&) volatile = delete;
320
321       // Requires __int_type convertible to _M_i.
322       constexpr __atomic_base(__int_type __i) noexcept : _M_i (__i) { }
323
324       operator __int_type() const noexcept
325       { return load(); }
326
327       operator __int_type() const volatile noexcept
328       { return load(); }
329
330       __int_type
331       operator=(__int_type __i) noexcept
332       {
333         store(__i);
334         return __i;
335       }
336
337       __int_type
338       operator=(__int_type __i) volatile noexcept
339       {
340         store(__i);
341         return __i;
342       }
343
344       __int_type
345       operator++(int) noexcept
346       { return fetch_add(1); }
347
348       __int_type
349       operator++(int) volatile noexcept
350       { return fetch_add(1); }
351
352       __int_type
353       operator--(int) noexcept
354       { return fetch_sub(1); }
355
356       __int_type
357       operator--(int) volatile noexcept
358       { return fetch_sub(1); }
359
360       __int_type
361       operator++() noexcept
362       { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
363
364       __int_type
365       operator++() volatile noexcept
366       { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
367
368       __int_type
369       operator--() noexcept
370       { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
371
372       __int_type
373       operator--() volatile noexcept
374       { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
375
376       __int_type
377       operator+=(__int_type __i) noexcept
378       { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
379
380       __int_type
381       operator+=(__int_type __i) volatile noexcept
382       { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
383
384       __int_type
385       operator-=(__int_type __i) noexcept
386       { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
387
388       __int_type
389       operator-=(__int_type __i) volatile noexcept
390       { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
391
392       __int_type
393       operator&=(__int_type __i) noexcept
394       { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
395
396       __int_type
397       operator&=(__int_type __i) volatile noexcept
398       { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
399
400       __int_type
401       operator|=(__int_type __i) noexcept
402       { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
403
404       __int_type
405       operator|=(__int_type __i) volatile noexcept
406       { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
407
408       __int_type
409       operator^=(__int_type __i) noexcept
410       { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
411
412       __int_type
413       operator^=(__int_type __i) volatile noexcept
414       { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
415
416       bool
417       is_lock_free() const noexcept
418       { return __atomic_is_lock_free (sizeof (_M_i), &_M_i); }
419
420       bool
421       is_lock_free() const volatile noexcept
422       { return __atomic_is_lock_free (sizeof (_M_i), &_M_i); }
423
424       void
425       store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept
426       {
427         __glibcxx_assert(__m != memory_order_acquire);
428         __glibcxx_assert(__m != memory_order_acq_rel);
429         __glibcxx_assert(__m != memory_order_consume);
430
431         __atomic_store_n(&_M_i, __i, __m);
432       }
433
434       void
435       store(__int_type __i,
436             memory_order __m = memory_order_seq_cst) volatile noexcept
437       {
438         __glibcxx_assert(__m != memory_order_acquire);
439         __glibcxx_assert(__m != memory_order_acq_rel);
440         __glibcxx_assert(__m != memory_order_consume);
441
442         __atomic_store_n(&_M_i, __i, __m);
443       }
444
445       __int_type
446       load(memory_order __m = memory_order_seq_cst) const noexcept
447       {
448         __glibcxx_assert(__m != memory_order_release);
449         __glibcxx_assert(__m != memory_order_acq_rel);
450
451         return __atomic_load_n(&_M_i, __m);
452       }
453
454       __int_type
455       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
456       {
457         __glibcxx_assert(__m != memory_order_release);
458         __glibcxx_assert(__m != memory_order_acq_rel);
459
460         return __atomic_load_n(&_M_i, __m);
461       }
462
463       __int_type
464       exchange(__int_type __i,
465                memory_order __m = memory_order_seq_cst) noexcept
466       {
467         return __atomic_exchange_n(&_M_i, __i, __m);
468       }
469
470
471       __int_type
472       exchange(__int_type __i,
473                memory_order __m = memory_order_seq_cst) volatile noexcept
474       {
475         return __atomic_exchange_n(&_M_i, __i, __m);
476       }
477
478       bool
479       compare_exchange_weak(__int_type& __i1, __int_type __i2,
480                             memory_order __m1, memory_order __m2) noexcept
481       {
482         __glibcxx_assert(__m2 != memory_order_release);
483         __glibcxx_assert(__m2 != memory_order_acq_rel);
484         __glibcxx_assert(__m2 <= __m1);
485
486         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
487       }
488
489       bool
490       compare_exchange_weak(__int_type& __i1, __int_type __i2,
491                             memory_order __m1,
492                             memory_order __m2) volatile noexcept
493       {
494         __glibcxx_assert(__m2 != memory_order_release);
495         __glibcxx_assert(__m2 != memory_order_acq_rel);
496         __glibcxx_assert(__m2 <= __m1);
497
498         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
499       }
500
501       bool
502       compare_exchange_weak(__int_type& __i1, __int_type __i2,
503                             memory_order __m = memory_order_seq_cst) noexcept
504       {
505         return compare_exchange_weak(__i1, __i2, __m,
506                                      __cmpexch_failure_order(__m));
507       }
508
509       bool
510       compare_exchange_weak(__int_type& __i1, __int_type __i2,
511                    memory_order __m = memory_order_seq_cst) volatile noexcept
512       {
513         return compare_exchange_weak(__i1, __i2, __m,
514                                      __cmpexch_failure_order(__m));
515       }
516
517       bool
518       compare_exchange_strong(__int_type& __i1, __int_type __i2,
519                               memory_order __m1, memory_order __m2) noexcept
520       {
521         __glibcxx_assert(__m2 != memory_order_release);
522         __glibcxx_assert(__m2 != memory_order_acq_rel);
523         __glibcxx_assert(__m2 <= __m1);
524
525         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
526       }
527
528       bool
529       compare_exchange_strong(__int_type& __i1, __int_type __i2,
530                               memory_order __m1,
531                               memory_order __m2) volatile noexcept
532       {
533         __glibcxx_assert(__m2 != memory_order_release);
534         __glibcxx_assert(__m2 != memory_order_acq_rel);
535         __glibcxx_assert(__m2 <= __m1);
536
537         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
538       }
539
540       bool
541       compare_exchange_strong(__int_type& __i1, __int_type __i2,
542                               memory_order __m = memory_order_seq_cst) noexcept
543       {
544         return compare_exchange_strong(__i1, __i2, __m,
545                                        __cmpexch_failure_order(__m));
546       }
547
548       bool
549       compare_exchange_strong(__int_type& __i1, __int_type __i2,
550                  memory_order __m = memory_order_seq_cst) volatile noexcept
551       {
552         return compare_exchange_strong(__i1, __i2, __m,
553                                        __cmpexch_failure_order(__m));
554       }
555
556       __int_type
557       fetch_add(__int_type __i,
558                 memory_order __m = memory_order_seq_cst) noexcept
559       { return __atomic_fetch_add(&_M_i, __i, __m); }
560
561       __int_type
562       fetch_add(__int_type __i,
563                 memory_order __m = memory_order_seq_cst) volatile noexcept
564       { return __atomic_fetch_add(&_M_i, __i, __m); }
565
566       __int_type
567       fetch_sub(__int_type __i,
568                 memory_order __m = memory_order_seq_cst) noexcept
569       { return __atomic_fetch_sub(&_M_i, __i, __m); }
570
571       __int_type
572       fetch_sub(__int_type __i,
573                 memory_order __m = memory_order_seq_cst) volatile noexcept
574       { return __atomic_fetch_sub(&_M_i, __i, __m); }
575
576       __int_type
577       fetch_and(__int_type __i,
578                 memory_order __m = memory_order_seq_cst) noexcept
579       { return __atomic_fetch_and(&_M_i, __i, __m); }
580
581       __int_type
582       fetch_and(__int_type __i,
583                 memory_order __m = memory_order_seq_cst) volatile noexcept
584       { return __atomic_fetch_and(&_M_i, __i, __m); }
585
586       __int_type
587       fetch_or(__int_type __i,
588                memory_order __m = memory_order_seq_cst) noexcept
589       { return __atomic_fetch_or(&_M_i, __i, __m); }
590
591       __int_type
592       fetch_or(__int_type __i,
593                memory_order __m = memory_order_seq_cst) volatile noexcept
594       { return __atomic_fetch_or(&_M_i, __i, __m); }
595
596       __int_type
597       fetch_xor(__int_type __i,
598                 memory_order __m = memory_order_seq_cst) noexcept
599       { return __atomic_fetch_xor(&_M_i, __i, __m); }
600
601       __int_type
602       fetch_xor(__int_type __i,
603                 memory_order __m = memory_order_seq_cst) volatile noexcept
604       { return __atomic_fetch_xor(&_M_i, __i, __m); }
605     };
606
607
608   /// Partial specialization for pointer types.
609   template<typename _PTp>
610     struct __atomic_base<_PTp*>
611     {
612     private:
613       typedef _PTp*     __pointer_type;
614
615       __pointer_type    _M_p;
616
617     public:
618       __atomic_base() noexcept = default;
619       ~__atomic_base() noexcept = default;
620       __atomic_base(const __atomic_base&) = delete;
621       __atomic_base& operator=(const __atomic_base&) = delete;
622       __atomic_base& operator=(const __atomic_base&) volatile = delete;
623
624       // Requires __pointer_type convertible to _M_p.
625       constexpr __atomic_base(__pointer_type __p) noexcept : _M_p (__p) { }
626
627       operator __pointer_type() const noexcept
628       { return load(); }
629
630       operator __pointer_type() const volatile noexcept
631       { return load(); }
632
633       __pointer_type
634       operator=(__pointer_type __p) noexcept
635       {
636         store(__p);
637         return __p;
638       }
639
640       __pointer_type
641       operator=(__pointer_type __p) volatile noexcept
642       {
643         store(__p);
644         return __p;
645       }
646
647       __pointer_type
648       operator++(int) noexcept
649       { return fetch_add(1); }
650
651       __pointer_type
652       operator++(int) volatile noexcept
653       { return fetch_add(1); }
654
655       __pointer_type
656       operator--(int) noexcept
657       { return fetch_sub(1); }
658
659       __pointer_type
660       operator--(int) volatile noexcept
661       { return fetch_sub(1); }
662
663       __pointer_type
664       operator++() noexcept
665       { return __atomic_add_fetch(&_M_p, 1, memory_order_seq_cst); }
666
667       __pointer_type
668       operator++() volatile noexcept
669       { return __atomic_add_fetch(&_M_p, 1, memory_order_seq_cst); }
670
671       __pointer_type
672       operator--() noexcept
673       { return __atomic_sub_fetch(&_M_p, 1, memory_order_seq_cst); }
674
675       __pointer_type
676       operator--() volatile noexcept
677       { return __atomic_sub_fetch(&_M_p, 1, memory_order_seq_cst); }
678
679       __pointer_type
680       operator+=(ptrdiff_t __d) noexcept
681       { return __atomic_add_fetch(&_M_p, __d, memory_order_seq_cst); }
682
683       __pointer_type
684       operator+=(ptrdiff_t __d) volatile noexcept
685       { return __atomic_add_fetch(&_M_p, __d, memory_order_seq_cst); }
686
687       __pointer_type
688       operator-=(ptrdiff_t __d) noexcept
689       { return __atomic_sub_fetch(&_M_p, __d, memory_order_seq_cst); }
690
691       __pointer_type
692       operator-=(ptrdiff_t __d) volatile noexcept
693       { return __atomic_sub_fetch(&_M_p, __d, memory_order_seq_cst); }
694
695       bool
696       is_lock_free() const noexcept
697       { return __atomic_is_lock_free (sizeof (_M_p), &_M_p); }
698
699       bool
700       is_lock_free() const volatile noexcept
701       { return __atomic_is_lock_free (sizeof (_M_p), &_M_p); }
702
703       void
704       store(__pointer_type __p,
705             memory_order __m = memory_order_seq_cst) noexcept
706       {
707         __glibcxx_assert(__m != memory_order_acquire);
708         __glibcxx_assert(__m != memory_order_acq_rel);
709         __glibcxx_assert(__m != memory_order_consume);
710
711         __atomic_store_n(&_M_p, __p, __m);
712       }
713
714       void
715       store(__pointer_type __p,
716             memory_order __m = memory_order_seq_cst) volatile noexcept
717       {
718         __glibcxx_assert(__m != memory_order_acquire);
719         __glibcxx_assert(__m != memory_order_acq_rel);
720         __glibcxx_assert(__m != memory_order_consume);
721
722         __atomic_store_n(&_M_p, __p, __m);
723       }
724
725       __pointer_type
726       load(memory_order __m = memory_order_seq_cst) const noexcept
727       {
728         __glibcxx_assert(__m != memory_order_release);
729         __glibcxx_assert(__m != memory_order_acq_rel);
730
731         return __atomic_load_n(&_M_p, __m);
732       }
733
734       __pointer_type
735       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
736       {
737         __glibcxx_assert(__m != memory_order_release);
738         __glibcxx_assert(__m != memory_order_acq_rel);
739
740         return __atomic_load_n(&_M_p, __m);
741       }
742
743       __pointer_type
744       exchange(__pointer_type __p,
745                memory_order __m = memory_order_seq_cst) noexcept
746       {
747         return __atomic_exchange_n(&_M_p, __p, __m);
748       }
749
750
751       __pointer_type
752       exchange(__pointer_type __p,
753                memory_order __m = memory_order_seq_cst) volatile noexcept
754       {
755         return __atomic_exchange_n(&_M_p, __p, __m);
756       }
757
758       bool
759       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
760                               memory_order __m1,
761                               memory_order __m2) noexcept
762       {
763         __glibcxx_assert(__m2 != memory_order_release);
764         __glibcxx_assert(__m2 != memory_order_acq_rel);
765         __glibcxx_assert(__m2 <= __m1);
766
767         return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
768       }
769
770       bool
771       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
772                               memory_order __m1,
773                               memory_order __m2) volatile noexcept
774       {
775         __glibcxx_assert(__m2 != memory_order_release);
776         __glibcxx_assert(__m2 != memory_order_acq_rel);
777         __glibcxx_assert(__m2 <= __m1);
778
779         return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
780       }
781
782       __pointer_type
783       fetch_add(ptrdiff_t __d,
784                 memory_order __m = memory_order_seq_cst) noexcept
785       { return __atomic_fetch_add(&_M_p, __d, __m); }
786
787       __pointer_type
788       fetch_add(ptrdiff_t __d,
789                 memory_order __m = memory_order_seq_cst) volatile noexcept
790       { return __atomic_fetch_add(&_M_p, __d, __m); }
791
792       __pointer_type
793       fetch_sub(ptrdiff_t __d,
794                 memory_order __m = memory_order_seq_cst) noexcept
795       { return __atomic_fetch_sub(&_M_p, __d, __m); }
796
797       __pointer_type
798       fetch_sub(ptrdiff_t __d,
799                 memory_order __m = memory_order_seq_cst) volatile noexcept
800       { return __atomic_fetch_sub(&_M_p, __d, __m); }
801     };
802
803   // @} group atomics
804
805 _GLIBCXX_END_NAMESPACE_VERSION
806 } // namespace std
807
808 #endif