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
889