OSDN Git Service

bd14e35cd5af54866e9e8a8f5ac5e744b140ea64
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / atomic_base.h
1 // -*- C++ -*- header.
2
3 // Copyright (C) 2008, 2009, 2010, 2011, 2012 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_signal_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     /* The target's "set" value for test-and-set may not be exactly 1.  */
231 #if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1
232     bool _M_i;
233 #else
234     unsigned char _M_i;
235 #endif
236   };
237
238   _GLIBCXX_END_EXTERN_C
239
240 #define ATOMIC_FLAG_INIT { 0 }
241
242   /// atomic_flag
243   struct atomic_flag : public __atomic_flag_base
244   {
245     atomic_flag() noexcept = default;
246     ~atomic_flag() noexcept = default;
247     atomic_flag(const atomic_flag&) = delete;
248     atomic_flag& operator=(const atomic_flag&) = delete;
249     atomic_flag& operator=(const atomic_flag&) volatile = delete;
250
251     // Conversion to ATOMIC_FLAG_INIT.
252     constexpr atomic_flag(bool __i) noexcept
253       : __atomic_flag_base({ __i ? __GCC_ATOMIC_TEST_AND_SET_TRUEVAL : 0 })
254     { }
255
256     bool
257     test_and_set(memory_order __m = memory_order_seq_cst) noexcept
258     {
259       return __atomic_test_and_set (&_M_i, __m);
260     }
261
262     bool
263     test_and_set(memory_order __m = memory_order_seq_cst) volatile noexcept
264     {
265       return __atomic_test_and_set (&_M_i, __m);
266     }
267
268     void
269     clear(memory_order __m = memory_order_seq_cst) noexcept
270     {
271       __glibcxx_assert(__m != memory_order_consume);
272       __glibcxx_assert(__m != memory_order_acquire);
273       __glibcxx_assert(__m != memory_order_acq_rel);
274
275       __atomic_clear (&_M_i, __m);
276     }
277
278     void
279     clear(memory_order __m = memory_order_seq_cst) volatile noexcept
280     {
281       __glibcxx_assert(__m != memory_order_consume);
282       __glibcxx_assert(__m != memory_order_acquire);
283       __glibcxx_assert(__m != memory_order_acq_rel);
284
285       __atomic_clear (&_M_i, __m);
286     }
287   };
288
289
290   /// Base class for atomic integrals.
291   //
292   // For each of the integral types, define atomic_[integral type] struct
293   //
294   // atomic_bool     bool
295   // atomic_char     char
296   // atomic_schar    signed char
297   // atomic_uchar    unsigned char
298   // atomic_short    short
299   // atomic_ushort   unsigned short
300   // atomic_int      int
301   // atomic_uint     unsigned int
302   // atomic_long     long
303   // atomic_ulong    unsigned long
304   // atomic_llong    long long
305   // atomic_ullong   unsigned long long
306   // atomic_char16_t char16_t
307   // atomic_char32_t char32_t
308   // atomic_wchar_t  wchar_t
309   //
310   // NB: Assuming _ITp is an integral scalar type that is 1, 2, 4, or
311   // 8 bytes, since that is what GCC built-in functions for atomic
312   // memory access expect.
313   template<typename _ITp>
314     struct __atomic_base
315     {
316     private:
317       typedef _ITp      __int_type;
318
319       __int_type        _M_i;
320
321     public:
322       __atomic_base() noexcept = default;
323       ~__atomic_base() noexcept = default;
324       __atomic_base(const __atomic_base&) = delete;
325       __atomic_base& operator=(const __atomic_base&) = delete;
326       __atomic_base& operator=(const __atomic_base&) volatile = delete;
327
328       // Requires __int_type convertible to _M_i.
329       constexpr __atomic_base(__int_type __i) noexcept : _M_i (__i) { }
330
331       operator __int_type() const noexcept
332       { return load(); }
333
334       operator __int_type() const volatile noexcept
335       { return load(); }
336
337       __int_type
338       operator=(__int_type __i) noexcept
339       {
340         store(__i);
341         return __i;
342       }
343
344       __int_type
345       operator=(__int_type __i) volatile noexcept
346       {
347         store(__i);
348         return __i;
349       }
350
351       __int_type
352       operator++(int) noexcept
353       { return fetch_add(1); }
354
355       __int_type
356       operator++(int) volatile noexcept
357       { return fetch_add(1); }
358
359       __int_type
360       operator--(int) noexcept
361       { return fetch_sub(1); }
362
363       __int_type
364       operator--(int) volatile noexcept
365       { return fetch_sub(1); }
366
367       __int_type
368       operator++() noexcept
369       { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
370
371       __int_type
372       operator++() volatile noexcept
373       { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
374
375       __int_type
376       operator--() noexcept
377       { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
378
379       __int_type
380       operator--() volatile noexcept
381       { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
382
383       __int_type
384       operator+=(__int_type __i) noexcept
385       { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
386
387       __int_type
388       operator+=(__int_type __i) volatile noexcept
389       { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
390
391       __int_type
392       operator-=(__int_type __i) noexcept
393       { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
394
395       __int_type
396       operator-=(__int_type __i) volatile noexcept
397       { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
398
399       __int_type
400       operator&=(__int_type __i) noexcept
401       { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
402
403       __int_type
404       operator&=(__int_type __i) volatile noexcept
405       { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
406
407       __int_type
408       operator|=(__int_type __i) noexcept
409       { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
410
411       __int_type
412       operator|=(__int_type __i) volatile noexcept
413       { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
414
415       __int_type
416       operator^=(__int_type __i) noexcept
417       { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
418
419       __int_type
420       operator^=(__int_type __i) volatile noexcept
421       { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
422
423       bool
424       is_lock_free() const noexcept
425       { return __atomic_is_lock_free (sizeof (_M_i), &_M_i); }
426
427       bool
428       is_lock_free() const volatile noexcept
429       { return __atomic_is_lock_free (sizeof (_M_i), &_M_i); }
430
431       void
432       store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept
433       {
434         __glibcxx_assert(__m != memory_order_acquire);
435         __glibcxx_assert(__m != memory_order_acq_rel);
436         __glibcxx_assert(__m != memory_order_consume);
437
438         __atomic_store_n(&_M_i, __i, __m);
439       }
440
441       void
442       store(__int_type __i,
443             memory_order __m = memory_order_seq_cst) volatile noexcept
444       {
445         __glibcxx_assert(__m != memory_order_acquire);
446         __glibcxx_assert(__m != memory_order_acq_rel);
447         __glibcxx_assert(__m != memory_order_consume);
448
449         __atomic_store_n(&_M_i, __i, __m);
450       }
451
452       __int_type
453       load(memory_order __m = memory_order_seq_cst) const noexcept
454       {
455         __glibcxx_assert(__m != memory_order_release);
456         __glibcxx_assert(__m != memory_order_acq_rel);
457
458         return __atomic_load_n(&_M_i, __m);
459       }
460
461       __int_type
462       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
463       {
464         __glibcxx_assert(__m != memory_order_release);
465         __glibcxx_assert(__m != memory_order_acq_rel);
466
467         return __atomic_load_n(&_M_i, __m);
468       }
469
470       __int_type
471       exchange(__int_type __i,
472                memory_order __m = memory_order_seq_cst) noexcept
473       {
474         return __atomic_exchange_n(&_M_i, __i, __m);
475       }
476
477
478       __int_type
479       exchange(__int_type __i,
480                memory_order __m = memory_order_seq_cst) volatile noexcept
481       {
482         return __atomic_exchange_n(&_M_i, __i, __m);
483       }
484
485       bool
486       compare_exchange_weak(__int_type& __i1, __int_type __i2,
487                             memory_order __m1, memory_order __m2) noexcept
488       {
489         __glibcxx_assert(__m2 != memory_order_release);
490         __glibcxx_assert(__m2 != memory_order_acq_rel);
491         __glibcxx_assert(__m2 <= __m1);
492
493         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
494       }
495
496       bool
497       compare_exchange_weak(__int_type& __i1, __int_type __i2,
498                             memory_order __m1,
499                             memory_order __m2) volatile noexcept
500       {
501         __glibcxx_assert(__m2 != memory_order_release);
502         __glibcxx_assert(__m2 != memory_order_acq_rel);
503         __glibcxx_assert(__m2 <= __m1);
504
505         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
506       }
507
508       bool
509       compare_exchange_weak(__int_type& __i1, __int_type __i2,
510                             memory_order __m = memory_order_seq_cst) noexcept
511       {
512         return compare_exchange_weak(__i1, __i2, __m,
513                                      __cmpexch_failure_order(__m));
514       }
515
516       bool
517       compare_exchange_weak(__int_type& __i1, __int_type __i2,
518                    memory_order __m = memory_order_seq_cst) volatile noexcept
519       {
520         return compare_exchange_weak(__i1, __i2, __m,
521                                      __cmpexch_failure_order(__m));
522       }
523
524       bool
525       compare_exchange_strong(__int_type& __i1, __int_type __i2,
526                               memory_order __m1, memory_order __m2) noexcept
527       {
528         __glibcxx_assert(__m2 != memory_order_release);
529         __glibcxx_assert(__m2 != memory_order_acq_rel);
530         __glibcxx_assert(__m2 <= __m1);
531
532         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
533       }
534
535       bool
536       compare_exchange_strong(__int_type& __i1, __int_type __i2,
537                               memory_order __m1,
538                               memory_order __m2) volatile noexcept
539       {
540         __glibcxx_assert(__m2 != memory_order_release);
541         __glibcxx_assert(__m2 != memory_order_acq_rel);
542         __glibcxx_assert(__m2 <= __m1);
543
544         return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
545       }
546
547       bool
548       compare_exchange_strong(__int_type& __i1, __int_type __i2,
549                               memory_order __m = memory_order_seq_cst) noexcept
550       {
551         return compare_exchange_strong(__i1, __i2, __m,
552                                        __cmpexch_failure_order(__m));
553       }
554
555       bool
556       compare_exchange_strong(__int_type& __i1, __int_type __i2,
557                  memory_order __m = memory_order_seq_cst) volatile noexcept
558       {
559         return compare_exchange_strong(__i1, __i2, __m,
560                                        __cmpexch_failure_order(__m));
561       }
562
563       __int_type
564       fetch_add(__int_type __i,
565                 memory_order __m = memory_order_seq_cst) noexcept
566       { return __atomic_fetch_add(&_M_i, __i, __m); }
567
568       __int_type
569       fetch_add(__int_type __i,
570                 memory_order __m = memory_order_seq_cst) volatile noexcept
571       { return __atomic_fetch_add(&_M_i, __i, __m); }
572
573       __int_type
574       fetch_sub(__int_type __i,
575                 memory_order __m = memory_order_seq_cst) noexcept
576       { return __atomic_fetch_sub(&_M_i, __i, __m); }
577
578       __int_type
579       fetch_sub(__int_type __i,
580                 memory_order __m = memory_order_seq_cst) volatile noexcept
581       { return __atomic_fetch_sub(&_M_i, __i, __m); }
582
583       __int_type
584       fetch_and(__int_type __i,
585                 memory_order __m = memory_order_seq_cst) noexcept
586       { return __atomic_fetch_and(&_M_i, __i, __m); }
587
588       __int_type
589       fetch_and(__int_type __i,
590                 memory_order __m = memory_order_seq_cst) volatile noexcept
591       { return __atomic_fetch_and(&_M_i, __i, __m); }
592
593       __int_type
594       fetch_or(__int_type __i,
595                memory_order __m = memory_order_seq_cst) noexcept
596       { return __atomic_fetch_or(&_M_i, __i, __m); }
597
598       __int_type
599       fetch_or(__int_type __i,
600                memory_order __m = memory_order_seq_cst) volatile noexcept
601       { return __atomic_fetch_or(&_M_i, __i, __m); }
602
603       __int_type
604       fetch_xor(__int_type __i,
605                 memory_order __m = memory_order_seq_cst) noexcept
606       { return __atomic_fetch_xor(&_M_i, __i, __m); }
607
608       __int_type
609       fetch_xor(__int_type __i,
610                 memory_order __m = memory_order_seq_cst) volatile noexcept
611       { return __atomic_fetch_xor(&_M_i, __i, __m); }
612     };
613
614
615   /// Partial specialization for pointer types.
616   template<typename _PTp>
617     struct __atomic_base<_PTp*>
618     {
619     private:
620       typedef _PTp*     __pointer_type;
621
622       __pointer_type    _M_p;
623
624       // Factored out to facilitate explicit specialization.
625       constexpr ptrdiff_t
626       _M_type_size(ptrdiff_t __d) { return __d * sizeof(_PTp); }
627
628       constexpr ptrdiff_t
629       _M_type_size(ptrdiff_t __d) volatile { return __d * sizeof(_PTp); }
630
631     public:
632       __atomic_base() noexcept = default;
633       ~__atomic_base() noexcept = default;
634       __atomic_base(const __atomic_base&) = delete;
635       __atomic_base& operator=(const __atomic_base&) = delete;
636       __atomic_base& operator=(const __atomic_base&) volatile = delete;
637
638       // Requires __pointer_type convertible to _M_p.
639       constexpr __atomic_base(__pointer_type __p) noexcept : _M_p (__p) { }
640
641       operator __pointer_type() const noexcept
642       { return load(); }
643
644       operator __pointer_type() const volatile noexcept
645       { return load(); }
646
647       __pointer_type
648       operator=(__pointer_type __p) noexcept
649       {
650         store(__p);
651         return __p;
652       }
653
654       __pointer_type
655       operator=(__pointer_type __p) volatile noexcept
656       {
657         store(__p);
658         return __p;
659       }
660
661       __pointer_type
662       operator++(int) noexcept
663       { return fetch_add(1); }
664
665       __pointer_type
666       operator++(int) volatile noexcept
667       { return fetch_add(1); }
668
669       __pointer_type
670       operator--(int) noexcept
671       { return fetch_sub(1); }
672
673       __pointer_type
674       operator--(int) volatile noexcept
675       { return fetch_sub(1); }
676
677       __pointer_type
678       operator++() noexcept
679       { return __atomic_add_fetch(&_M_p, _M_type_size(1),
680                                   memory_order_seq_cst); }
681
682       __pointer_type
683       operator++() volatile noexcept
684       { return __atomic_add_fetch(&_M_p, _M_type_size(1),
685                                   memory_order_seq_cst); }
686
687       __pointer_type
688       operator--() noexcept
689       { return __atomic_sub_fetch(&_M_p, _M_type_size(1),
690                                   memory_order_seq_cst); }
691
692       __pointer_type
693       operator--() volatile noexcept
694       { return __atomic_sub_fetch(&_M_p, _M_type_size(1),
695                                   memory_order_seq_cst); }
696
697       __pointer_type
698       operator+=(ptrdiff_t __d) noexcept
699       { return __atomic_add_fetch(&_M_p, _M_type_size(__d),
700                                   memory_order_seq_cst); }
701
702       __pointer_type
703       operator+=(ptrdiff_t __d) volatile noexcept
704       { return __atomic_add_fetch(&_M_p, _M_type_size(__d),
705                                   memory_order_seq_cst); }
706
707       __pointer_type
708       operator-=(ptrdiff_t __d) noexcept
709       { return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
710                                   memory_order_seq_cst); }
711
712       __pointer_type
713       operator-=(ptrdiff_t __d) volatile noexcept
714       { return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
715                                   memory_order_seq_cst); }
716
717       bool
718       is_lock_free() const noexcept
719       { return __atomic_is_lock_free(_M_type_size(1), &_M_p); }
720
721       bool
722       is_lock_free() const volatile noexcept
723       { return __atomic_is_lock_free(_M_type_size(1), &_M_p); }
724
725       void
726       store(__pointer_type __p,
727             memory_order __m = memory_order_seq_cst) noexcept
728       {
729         __glibcxx_assert(__m != memory_order_acquire);
730         __glibcxx_assert(__m != memory_order_acq_rel);
731         __glibcxx_assert(__m != memory_order_consume);
732
733         __atomic_store_n(&_M_p, __p, __m);
734       }
735
736       void
737       store(__pointer_type __p,
738             memory_order __m = memory_order_seq_cst) volatile noexcept
739       {
740         __glibcxx_assert(__m != memory_order_acquire);
741         __glibcxx_assert(__m != memory_order_acq_rel);
742         __glibcxx_assert(__m != memory_order_consume);
743
744         __atomic_store_n(&_M_p, __p, __m);
745       }
746
747       __pointer_type
748       load(memory_order __m = memory_order_seq_cst) const noexcept
749       {
750         __glibcxx_assert(__m != memory_order_release);
751         __glibcxx_assert(__m != memory_order_acq_rel);
752
753         return __atomic_load_n(&_M_p, __m);
754       }
755
756       __pointer_type
757       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
758       {
759         __glibcxx_assert(__m != memory_order_release);
760         __glibcxx_assert(__m != memory_order_acq_rel);
761
762         return __atomic_load_n(&_M_p, __m);
763       }
764
765       __pointer_type
766       exchange(__pointer_type __p,
767                memory_order __m = memory_order_seq_cst) noexcept
768       {
769         return __atomic_exchange_n(&_M_p, __p, __m);
770       }
771
772
773       __pointer_type
774       exchange(__pointer_type __p,
775                memory_order __m = memory_order_seq_cst) volatile noexcept
776       {
777         return __atomic_exchange_n(&_M_p, __p, __m);
778       }
779
780       bool
781       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
782                               memory_order __m1,
783                               memory_order __m2) noexcept
784       {
785         __glibcxx_assert(__m2 != memory_order_release);
786         __glibcxx_assert(__m2 != memory_order_acq_rel);
787         __glibcxx_assert(__m2 <= __m1);
788
789         return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
790       }
791
792       bool
793       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
794                               memory_order __m1,
795                               memory_order __m2) volatile noexcept
796       {
797         __glibcxx_assert(__m2 != memory_order_release);
798         __glibcxx_assert(__m2 != memory_order_acq_rel);
799         __glibcxx_assert(__m2 <= __m1);
800
801         return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
802       }
803
804       __pointer_type
805       fetch_add(ptrdiff_t __d,
806                 memory_order __m = memory_order_seq_cst) noexcept
807       { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
808
809       __pointer_type
810       fetch_add(ptrdiff_t __d,
811                 memory_order __m = memory_order_seq_cst) volatile noexcept
812       { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
813
814       __pointer_type
815       fetch_sub(ptrdiff_t __d,
816                 memory_order __m = memory_order_seq_cst) noexcept
817       { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
818
819       __pointer_type
820       fetch_sub(ptrdiff_t __d,
821                 memory_order __m = memory_order_seq_cst) volatile noexcept
822       { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
823     };
824
825   // @} group atomics
826
827 _GLIBCXX_END_NAMESPACE_VERSION
828 } // namespace std
829
830 #endif