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 include/atomic
26 *  This is a Standard C++ Library header.
27 */
28
29// Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
30// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
31
32#ifndef _GLIBCXX_ATOMIC
33#define _GLIBCXX_ATOMIC 1
34
35#pragma GCC system_header
36
37#ifndef __GXX_EXPERIMENTAL_CXX0X__
38# include <bits/c++0x_warning.h>
39#endif
40
41#include <bits/atomic_base.h>
42
43namespace std _GLIBCXX_VISIBILITY(default)
44{
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
46
47  /**
48   * @addtogroup atomics
49   * @{
50   */
51
52  /// atomic_bool
53  // NB: No operators or fetch-operations for this type.
54  struct atomic_bool
55  {
56  private:
57    __atomic_base<bool>	_M_base;
58
59  public:
60    atomic_bool() noexcept = default;
61    ~atomic_bool() noexcept = default;
62    atomic_bool(const atomic_bool&) = delete;
63    atomic_bool& operator=(const atomic_bool&) = delete;
64    atomic_bool& operator=(const atomic_bool&) volatile = delete;
65
66    constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { }
67
68    bool
69    operator=(bool __i) noexcept
70    { return _M_base.operator=(__i); }
71
72    operator bool() const noexcept
73    { return _M_base.load(); }
74
75    operator bool() const volatile noexcept
76    { return _M_base.load(); }
77
78    bool
79    is_lock_free() const noexcept { return _M_base.is_lock_free(); }
80
81    bool
82    is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
83
84    void
85    store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
86    { _M_base.store(__i, __m); }
87
88    void
89    store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
90    { _M_base.store(__i, __m); }
91
92    bool
93    load(memory_order __m = memory_order_seq_cst) const noexcept
94    { return _M_base.load(__m); }
95
96    bool
97    load(memory_order __m = memory_order_seq_cst) const volatile noexcept
98    { return _M_base.load(__m); }
99
100    bool
101    exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
102    { return _M_base.exchange(__i, __m); }
103
104    bool
105    exchange(bool __i,
106	     memory_order __m = memory_order_seq_cst) volatile noexcept
107    { return _M_base.exchange(__i, __m); }
108
109    bool
110    compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
111			  memory_order __m2) noexcept
112    { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
113
114    bool
115    compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
116			  memory_order __m2) volatile noexcept
117    { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
118
119    bool
120    compare_exchange_weak(bool& __i1, bool __i2,
121			  memory_order __m = memory_order_seq_cst) noexcept
122    { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
123
124    bool
125    compare_exchange_weak(bool& __i1, bool __i2,
126		     memory_order __m = memory_order_seq_cst) volatile noexcept
127    { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
128
129    bool
130    compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
131			    memory_order __m2) noexcept
132    { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
133
134    bool
135    compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
136			    memory_order __m2) volatile noexcept
137    { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
138
139    bool
140    compare_exchange_strong(bool& __i1, bool __i2,
141			    memory_order __m = memory_order_seq_cst) noexcept
142    { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
143
144    bool
145    compare_exchange_strong(bool& __i1, bool __i2,
146		    memory_order __m = memory_order_seq_cst) volatile noexcept
147    { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
148  };
149
150
151  /// atomic
152  /// 29.4.3, Generic atomic type, primary class template.
153  template<typename _Tp>
154    struct atomic
155    {
156    private:
157      _Tp _M_i;
158
159    public:
160      atomic() noexcept = default;
161      ~atomic() noexcept = default;
162      atomic(const atomic&) = delete;
163      atomic& operator=(const atomic&) = delete;
164      atomic& operator=(const atomic&) volatile = delete;
165
166      constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
167
168      operator _Tp() const noexcept
169      { return load(); }
170
171      operator _Tp() const volatile noexcept
172      { return load(); }
173
174      _Tp
175      operator=(_Tp __i) noexcept
176      { store(__i); return __i; }
177
178      _Tp
179      operator=(_Tp __i) volatile noexcept
180      { store(__i); return __i; }
181
182      bool
183      is_lock_free() const noexcept
184      { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); }
185
186      bool
187      is_lock_free() const volatile noexcept
188      { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); }
189
190      void
191      store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
192      { __atomic_store(&_M_i, &__i, _m); }
193
194      void
195      store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept
196      { __atomic_store(&_M_i, &__i, _m); }
197
198      _Tp
199      load(memory_order _m = memory_order_seq_cst) const noexcept
200      {
201        _Tp tmp;
202	__atomic_load(&_M_i, &tmp, _m);
203	return tmp;
204      }
205
206      _Tp
207      load(memory_order _m = memory_order_seq_cst) const volatile noexcept
208      {
209        _Tp tmp;
210	__atomic_load(&_M_i, &tmp, _m);
211	return tmp;
212      }
213
214      _Tp
215      exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
216      {
217        _Tp tmp;
218	__atomic_exchange(&_M_i, &__i, &tmp, _m);
219	return tmp;
220      }
221
222      _Tp
223      exchange(_Tp __i,
224	       memory_order _m = memory_order_seq_cst) volatile noexcept
225      {
226        _Tp tmp;
227	__atomic_exchange(&_M_i, &__i, &tmp, _m);
228	return tmp;
229      }
230
231      bool
232      compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
233			    memory_order __f) noexcept
234      {
235	return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
236      }
237
238      bool
239      compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
240			    memory_order __f) volatile noexcept
241      {
242	return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
243      }
244
245      bool
246      compare_exchange_weak(_Tp& __e, _Tp __i,
247			    memory_order __m = memory_order_seq_cst) noexcept
248      { return compare_exchange_weak(__e, __i, __m, __m); }
249
250      bool
251      compare_exchange_weak(_Tp& __e, _Tp __i,
252		     memory_order __m = memory_order_seq_cst) volatile noexcept
253      { return compare_exchange_weak(__e, __i, __m, __m); }
254
255      bool
256      compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
257			      memory_order __f) noexcept
258      {
259	return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
260      }
261
262      bool
263      compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
264			      memory_order __f) volatile noexcept
265      {
266	return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
267      }
268
269      bool
270      compare_exchange_strong(_Tp& __e, _Tp __i,
271			       memory_order __m = memory_order_seq_cst) noexcept
272      { return compare_exchange_strong(__e, __i, __m, __m); }
273
274      bool
275      compare_exchange_strong(_Tp& __e, _Tp __i,
276		     memory_order __m = memory_order_seq_cst) volatile noexcept
277      { return compare_exchange_strong(__e, __i, __m, __m); }
278    };
279
280
281  /// Partial specialization for pointer types.
282  template<typename _Tp>
283    struct atomic<_Tp*>
284    {
285      typedef _Tp* 			__pointer_type;
286      typedef __atomic_base<_Tp*>	__base_type;
287      __base_type			_M_b;
288
289      atomic() noexcept = default;
290      ~atomic() noexcept = default;
291      atomic(const atomic&) = delete;
292      atomic& operator=(const atomic&) = delete;
293      atomic& operator=(const atomic&) volatile = delete;
294
295      constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
296
297      operator __pointer_type() const noexcept
298      { return __pointer_type(_M_b); }
299
300      operator __pointer_type() const volatile noexcept
301      { return __pointer_type(_M_b); }
302
303      __pointer_type
304      operator=(__pointer_type __p) noexcept
305      { return _M_b.operator=(__p); }
306
307      __pointer_type
308      operator=(__pointer_type __p) volatile noexcept
309      { return _M_b.operator=(__p); }
310
311      __pointer_type
312      operator++(int) noexcept
313      { return _M_b++; }
314
315      __pointer_type
316      operator++(int) volatile noexcept
317      { return _M_b++; }
318
319      __pointer_type
320      operator--(int) noexcept
321      { return _M_b--; }
322
323      __pointer_type
324      operator--(int) volatile noexcept
325      { return _M_b--; }
326
327      __pointer_type
328      operator++() noexcept
329      { return ++_M_b; }
330
331      __pointer_type
332      operator++() volatile noexcept
333      { return ++_M_b; }
334
335      __pointer_type
336      operator--() noexcept
337      { return --_M_b; }
338
339      __pointer_type
340      operator--() volatile noexcept
341      { return --_M_b; }
342
343      __pointer_type
344      operator+=(ptrdiff_t __d) noexcept
345      { return _M_b.operator+=(__d); }
346
347      __pointer_type
348      operator+=(ptrdiff_t __d) volatile noexcept
349      { return _M_b.operator+=(__d); }
350
351      __pointer_type
352      operator-=(ptrdiff_t __d) noexcept
353      { return _M_b.operator-=(__d); }
354
355      __pointer_type
356      operator-=(ptrdiff_t __d) volatile noexcept
357      { return _M_b.operator-=(__d); }
358
359      bool
360      is_lock_free() const noexcept
361      { return _M_b.is_lock_free(); }
362
363      bool
364      is_lock_free() const volatile noexcept
365      { return _M_b.is_lock_free(); }
366
367      void
368      store(__pointer_type __p,
369	    memory_order __m = memory_order_seq_cst) noexcept
370      { return _M_b.store(__p, __m); }
371
372      void
373      store(__pointer_type __p,
374	    memory_order __m = memory_order_seq_cst) volatile noexcept
375      { return _M_b.store(__p, __m); }
376
377      __pointer_type
378      load(memory_order __m = memory_order_seq_cst) const noexcept
379      { return _M_b.load(__m); }
380
381      __pointer_type
382      load(memory_order __m = memory_order_seq_cst) const volatile noexcept
383      { return _M_b.load(__m); }
384
385      __pointer_type
386      exchange(__pointer_type __p,
387	       memory_order __m = memory_order_seq_cst) noexcept
388      { return _M_b.exchange(__p, __m); }
389
390      __pointer_type
391      exchange(__pointer_type __p,
392	       memory_order __m = memory_order_seq_cst) volatile noexcept
393      { return _M_b.exchange(__p, __m); }
394
395      bool
396      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
397			    memory_order __m1, memory_order __m2) noexcept
398      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
399
400      bool
401      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
402			    memory_order __m1,
403			    memory_order __m2) volatile noexcept
404      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
405
406      bool
407      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
408			    memory_order __m = memory_order_seq_cst) noexcept
409      {
410	return compare_exchange_weak(__p1, __p2, __m,
411				     __cmpexch_failure_order(__m));
412      }
413
414      bool
415      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
416		    memory_order __m = memory_order_seq_cst) volatile noexcept
417      {
418	return compare_exchange_weak(__p1, __p2, __m,
419				     __cmpexch_failure_order(__m));
420      }
421
422      bool
423      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
424			      memory_order __m1, memory_order __m2) noexcept
425      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
426
427      bool
428      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
429			      memory_order __m1,
430			      memory_order __m2) volatile noexcept
431      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
432
433      bool
434      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
435			      memory_order __m = memory_order_seq_cst) noexcept
436      {
437	return _M_b.compare_exchange_strong(__p1, __p2, __m,
438					    __cmpexch_failure_order(__m));
439      }
440
441      bool
442      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
443		    memory_order __m = memory_order_seq_cst) volatile noexcept
444      {
445	return _M_b.compare_exchange_strong(__p1, __p2, __m,
446					    __cmpexch_failure_order(__m));
447      }
448
449      __pointer_type
450      fetch_add(ptrdiff_t __d,
451		memory_order __m = memory_order_seq_cst) noexcept
452      { return _M_b.fetch_add(__d, __m); }
453
454      __pointer_type
455      fetch_add(ptrdiff_t __d,
456		memory_order __m = memory_order_seq_cst) volatile noexcept
457      { return _M_b.fetch_add(__d, __m); }
458
459      __pointer_type
460      fetch_sub(ptrdiff_t __d,
461		memory_order __m = memory_order_seq_cst) noexcept
462      { return _M_b.fetch_sub(__d, __m); }
463
464      __pointer_type
465      fetch_sub(ptrdiff_t __d,
466		memory_order __m = memory_order_seq_cst) volatile noexcept
467      { return _M_b.fetch_sub(__d, __m); }
468    };
469
470
471  /// Explicit specialization for bool.
472  template<>
473    struct atomic<bool> : public atomic_bool
474    {
475      typedef bool 			__integral_type;
476      typedef atomic_bool 		__base_type;
477
478      atomic() noexcept = default;
479      ~atomic() noexcept = default;
480      atomic(const atomic&) = delete;
481      atomic& operator=(const atomic&) = delete;
482      atomic& operator=(const atomic&) volatile = delete;
483
484      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
485
486      using __base_type::operator __integral_type;
487      using __base_type::operator=;
488    };
489
490  /// Explicit specialization for char.
491  template<>
492    struct atomic<char> : public atomic_char
493    {
494      typedef char 			__integral_type;
495      typedef atomic_char 		__base_type;
496
497      atomic() noexcept = default;
498      ~atomic() noexcept = default;
499      atomic(const atomic&) = delete;
500      atomic& operator=(const atomic&) = delete;
501      atomic& operator=(const atomic&) volatile = delete;
502
503      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
504
505      using __base_type::operator __integral_type;
506      using __base_type::operator=;
507    };
508
509  /// Explicit specialization for signed char.
510  template<>
511    struct atomic<signed char> : public atomic_schar
512    {
513      typedef signed char 		__integral_type;
514      typedef atomic_schar 		__base_type;
515
516      atomic() noexcept= default;
517      ~atomic() noexcept = default;
518      atomic(const atomic&) = delete;
519      atomic& operator=(const atomic&) = delete;
520      atomic& operator=(const atomic&) volatile = delete;
521
522      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
523
524      using __base_type::operator __integral_type;
525      using __base_type::operator=;
526    };
527
528  /// Explicit specialization for unsigned char.
529  template<>
530    struct atomic<unsigned char> : public atomic_uchar
531    {
532      typedef unsigned char 		__integral_type;
533      typedef atomic_uchar 		__base_type;
534
535      atomic() noexcept= default;
536      ~atomic() noexcept = default;
537      atomic(const atomic&) = delete;
538      atomic& operator=(const atomic&) = delete;
539      atomic& operator=(const atomic&) volatile = delete;
540
541      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
542
543      using __base_type::operator __integral_type;
544      using __base_type::operator=;
545    };
546
547  /// Explicit specialization for short.
548  template<>
549    struct atomic<short> : public atomic_short
550    {
551      typedef short 			__integral_type;
552      typedef atomic_short 		__base_type;
553
554      atomic() noexcept = default;
555      ~atomic() noexcept = default;
556      atomic(const atomic&) = delete;
557      atomic& operator=(const atomic&) = delete;
558      atomic& operator=(const atomic&) volatile = delete;
559
560      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
561
562      using __base_type::operator __integral_type;
563      using __base_type::operator=;
564    };
565
566  /// Explicit specialization for unsigned short.
567  template<>
568    struct atomic<unsigned short> : public atomic_ushort
569    {
570      typedef unsigned short 	      	__integral_type;
571      typedef atomic_ushort 		__base_type;
572
573      atomic() noexcept = default;
574      ~atomic() noexcept = default;
575      atomic(const atomic&) = delete;
576      atomic& operator=(const atomic&) = delete;
577      atomic& operator=(const atomic&) volatile = delete;
578
579      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
580
581      using __base_type::operator __integral_type;
582      using __base_type::operator=;
583    };
584
585  /// Explicit specialization for int.
586  template<>
587    struct atomic<int> : atomic_int
588    {
589      typedef int 			__integral_type;
590      typedef atomic_int 		__base_type;
591
592      atomic() noexcept = default;
593      ~atomic() noexcept = default;
594      atomic(const atomic&) = delete;
595      atomic& operator=(const atomic&) = delete;
596      atomic& operator=(const atomic&) volatile = delete;
597
598      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
599
600      using __base_type::operator __integral_type;
601      using __base_type::operator=;
602    };
603
604  /// Explicit specialization for unsigned int.
605  template<>
606    struct atomic<unsigned int> : public atomic_uint
607    {
608      typedef unsigned int		__integral_type;
609      typedef atomic_uint 		__base_type;
610
611      atomic() noexcept = default;
612      ~atomic() noexcept = default;
613      atomic(const atomic&) = delete;
614      atomic& operator=(const atomic&) = delete;
615      atomic& operator=(const atomic&) volatile = delete;
616
617      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
618
619      using __base_type::operator __integral_type;
620      using __base_type::operator=;
621    };
622
623  /// Explicit specialization for long.
624  template<>
625    struct atomic<long> : public atomic_long
626    {
627      typedef long 			__integral_type;
628      typedef atomic_long 		__base_type;
629
630      atomic() noexcept = default;
631      ~atomic() noexcept = default;
632      atomic(const atomic&) = delete;
633      atomic& operator=(const atomic&) = delete;
634      atomic& operator=(const atomic&) volatile = delete;
635
636      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
637
638      using __base_type::operator __integral_type;
639      using __base_type::operator=;
640    };
641
642  /// Explicit specialization for unsigned long.
643  template<>
644    struct atomic<unsigned long> : public atomic_ulong
645    {
646      typedef unsigned long 		__integral_type;
647      typedef atomic_ulong 		__base_type;
648
649      atomic() noexcept = default;
650      ~atomic() noexcept = default;
651      atomic(const atomic&) = delete;
652      atomic& operator=(const atomic&) = delete;
653      atomic& operator=(const atomic&) volatile = delete;
654
655      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
656
657      using __base_type::operator __integral_type;
658      using __base_type::operator=;
659    };
660
661  /// Explicit specialization for long long.
662  template<>
663    struct atomic<long long> : public atomic_llong
664    {
665      typedef long long 		__integral_type;
666      typedef atomic_llong 		__base_type;
667
668      atomic() noexcept = default;
669      ~atomic() noexcept = default;
670      atomic(const atomic&) = delete;
671      atomic& operator=(const atomic&) = delete;
672      atomic& operator=(const atomic&) volatile = delete;
673
674      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
675
676      using __base_type::operator __integral_type;
677      using __base_type::operator=;
678    };
679
680  /// Explicit specialization for unsigned long long.
681  template<>
682    struct atomic<unsigned long long> : public atomic_ullong
683    {
684      typedef unsigned long long       	__integral_type;
685      typedef atomic_ullong 		__base_type;
686
687      atomic() noexcept = default;
688      ~atomic() noexcept = default;
689      atomic(const atomic&) = delete;
690      atomic& operator=(const atomic&) = delete;
691      atomic& operator=(const atomic&) volatile = delete;
692
693      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
694
695      using __base_type::operator __integral_type;
696      using __base_type::operator=;
697    };
698
699  /// Explicit specialization for wchar_t.
700  template<>
701    struct atomic<wchar_t> : public atomic_wchar_t
702    {
703      typedef wchar_t 			__integral_type;
704      typedef atomic_wchar_t 		__base_type;
705
706      atomic() noexcept = default;
707      ~atomic() noexcept = default;
708      atomic(const atomic&) = delete;
709      atomic& operator=(const atomic&) = delete;
710      atomic& operator=(const atomic&) volatile = delete;
711
712      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
713
714      using __base_type::operator __integral_type;
715      using __base_type::operator=;
716    };
717
718  /// Explicit specialization for char16_t.
719  template<>
720    struct atomic<char16_t> : public atomic_char16_t
721    {
722      typedef char16_t 			__integral_type;
723      typedef atomic_char16_t 		__base_type;
724
725      atomic() noexcept = default;
726      ~atomic() noexcept = default;
727      atomic(const atomic&) = delete;
728      atomic& operator=(const atomic&) = delete;
729      atomic& operator=(const atomic&) volatile = delete;
730
731      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
732
733      using __base_type::operator __integral_type;
734      using __base_type::operator=;
735    };
736
737  /// Explicit specialization for char32_t.
738  template<>
739    struct atomic<char32_t> : public atomic_char32_t
740    {
741      typedef char32_t 			__integral_type;
742      typedef atomic_char32_t 		__base_type;
743
744      atomic() noexcept = default;
745      ~atomic() noexcept = default;
746      atomic(const atomic&) = delete;
747      atomic& operator=(const atomic&) = delete;
748      atomic& operator=(const atomic&) volatile = delete;
749
750      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
751
752      using __base_type::operator __integral_type;
753      using __base_type::operator=;
754    };
755
756
757  // Function definitions, atomic_flag operations.
758  inline bool
759  atomic_flag_test_and_set_explicit(atomic_flag* __a,
760				    memory_order __m) noexcept
761  { return __a->test_and_set(__m); }
762
763  inline bool
764  atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
765				    memory_order __m) noexcept
766  { return __a->test_and_set(__m); }
767
768  inline void
769  atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
770  { __a->clear(__m); }
771
772  inline void
773  atomic_flag_clear_explicit(volatile atomic_flag* __a,
774			     memory_order __m) noexcept
775  { __a->clear(__m); }
776
777  inline bool
778  atomic_flag_test_and_set(atomic_flag* __a) noexcept
779  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
780
781  inline bool
782  atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
783  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
784
785  inline void
786  atomic_flag_clear(atomic_flag* __a) noexcept
787  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
788
789  inline void
790  atomic_flag_clear(volatile atomic_flag* __a) noexcept
791  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
792
793
794  // Function templates generally applicable to atomic types.
795  template<typename _ITp>
796    inline bool
797    atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
798    { return __a->is_lock_free(); }
799
800  template<typename _ITp>
801    inline bool
802    atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
803    { return __a->is_lock_free(); }
804
805  template<typename _ITp>
806    inline void
807    atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
808
809  template<typename _ITp>
810    inline void
811    atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
812
813  template<typename _ITp>
814    inline void
815    atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
816			  memory_order __m) noexcept
817    { __a->store(__i, __m); }
818
819  template<typename _ITp>
820    inline void
821    atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
822			  memory_order __m) noexcept
823    { __a->store(__i, __m); }
824
825  template<typename _ITp>
826    inline _ITp
827    atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
828    { return __a->load(__m); }
829
830  template<typename _ITp>
831    inline _ITp
832    atomic_load_explicit(const volatile atomic<_ITp>* __a,
833			 memory_order __m) noexcept
834    { return __a->load(__m); }
835
836  template<typename _ITp>
837    inline _ITp
838    atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
839			     memory_order __m) noexcept
840    { return __a->exchange(__i, __m); }
841
842  template<typename _ITp>
843    inline _ITp
844    atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
845			     memory_order __m) noexcept
846    { return __a->exchange(__i, __m); }
847
848  template<typename _ITp>
849    inline bool
850    atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
851					  _ITp* __i1, _ITp __i2,
852					  memory_order __m1,
853					  memory_order __m2) noexcept
854    { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
855
856  template<typename _ITp>
857    inline bool
858    atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
859					  _ITp* __i1, _ITp __i2,
860					  memory_order __m1,
861					  memory_order __m2) noexcept
862    { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
863
864  template<typename _ITp>
865    inline bool
866    atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
867					    _ITp* __i1, _ITp __i2,
868					    memory_order __m1,
869					    memory_order __m2) noexcept
870    { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
871
872  template<typename _ITp>
873    inline bool
874    atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
875					    _ITp* __i1, _ITp __i2,
876					    memory_order __m1,
877					    memory_order __m2) noexcept
878    { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
879
880
881  template<typename _ITp>
882    inline void
883    atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
884    { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
885
886  template<typename _ITp>
887    inline void
888    atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
889    { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
890
891  template<typename _ITp>
892    inline _ITp
893    atomic_load(const atomic<_ITp>* __a) noexcept
894    { return atomic_load_explicit(__a, memory_order_seq_cst); }
895
896  template<typename _ITp>
897    inline _ITp
898    atomic_load(const volatile atomic<_ITp>* __a) noexcept
899    { return atomic_load_explicit(__a, memory_order_seq_cst); }
900
901  template<typename _ITp>
902    inline _ITp
903    atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
904    { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
905
906  template<typename _ITp>
907    inline _ITp
908    atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
909    { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
910
911  template<typename _ITp>
912    inline bool
913    atomic_compare_exchange_weak(atomic<_ITp>* __a,
914				 _ITp* __i1, _ITp __i2) noexcept
915    {
916      return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
917						   memory_order_seq_cst,
918						   memory_order_seq_cst);
919    }
920
921  template<typename _ITp>
922    inline bool
923    atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
924				 _ITp* __i1, _ITp __i2) noexcept
925    {
926      return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
927						   memory_order_seq_cst,
928						   memory_order_seq_cst);
929    }
930
931  template<typename _ITp>
932    inline bool
933    atomic_compare_exchange_strong(atomic<_ITp>* __a,
934				   _ITp* __i1, _ITp __i2) noexcept
935    {
936      return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
937						     memory_order_seq_cst,
938						     memory_order_seq_cst);
939    }
940
941  template<typename _ITp>
942    inline bool
943    atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
944				   _ITp* __i1, _ITp __i2) noexcept
945    {
946      return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
947						     memory_order_seq_cst,
948						     memory_order_seq_cst);
949    }
950
951  // Function templates for atomic_integral operations only, using
952  // __atomic_base. Template argument should be constricted to
953  // intergral types as specified in the standard, excluding address
954  // types.
955  template<typename _ITp>
956    inline _ITp
957    atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
958			      memory_order __m) noexcept
959    { return __a->fetch_add(__i, __m); }
960
961  template<typename _ITp>
962    inline _ITp
963    atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
964			      memory_order __m) noexcept
965    { return __a->fetch_add(__i, __m); }
966
967  template<typename _ITp>
968    inline _ITp
969    atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
970			      memory_order __m) noexcept
971    { return __a->fetch_sub(__i, __m); }
972
973  template<typename _ITp>
974    inline _ITp
975    atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
976			      memory_order __m) noexcept
977    { return __a->fetch_sub(__i, __m); }
978
979  template<typename _ITp>
980    inline _ITp
981    atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
982			      memory_order __m) noexcept
983    { return __a->fetch_and(__i, __m); }
984
985  template<typename _ITp>
986    inline _ITp
987    atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
988			      memory_order __m) noexcept
989    { return __a->fetch_and(__i, __m); }
990
991  template<typename _ITp>
992    inline _ITp
993    atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
994			     memory_order __m) noexcept
995    { return __a->fetch_or(__i, __m); }
996
997  template<typename _ITp>
998    inline _ITp
999    atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1000			     memory_order __m) noexcept
1001    { return __a->fetch_or(__i, __m); }
1002
1003  template<typename _ITp>
1004    inline _ITp
1005    atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1006			      memory_order __m) noexcept
1007    { return __a->fetch_xor(__i, __m); }
1008
1009  template<typename _ITp>
1010    inline _ITp
1011    atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1012			      memory_order __m) noexcept
1013    { return __a->fetch_xor(__i, __m); }
1014
1015  template<typename _ITp>
1016    inline _ITp
1017    atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1018    { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1019
1020  template<typename _ITp>
1021    inline _ITp
1022    atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1023    { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1024
1025  template<typename _ITp>
1026    inline _ITp
1027    atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1028    { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1029
1030  template<typename _ITp>
1031    inline _ITp
1032    atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1033    { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1034
1035  template<typename _ITp>
1036    inline _ITp
1037    atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1038    { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1039
1040  template<typename _ITp>
1041    inline _ITp
1042    atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1043    { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1044
1045  template<typename _ITp>
1046    inline _ITp
1047    atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1048    { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1049
1050  template<typename _ITp>
1051    inline _ITp
1052    atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1053    { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1054
1055  template<typename _ITp>
1056    inline _ITp
1057    atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1058    { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1059
1060  template<typename _ITp>
1061    inline _ITp
1062    atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1063    { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1064
1065
1066  // Partial specializations for pointers.
1067  template<typename _ITp>
1068    inline _ITp*
1069    atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1070			      memory_order __m) noexcept
1071    { return __a->fetch_add(__d, __m); }
1072
1073  template<typename _ITp>
1074    inline _ITp*
1075    atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1076			      memory_order __m) noexcept
1077    { return __a->fetch_add(__d, __m); }
1078
1079  template<typename _ITp>
1080    inline _ITp*
1081    atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1082    { return __a->fetch_add(__d); }
1083
1084  template<typename _ITp>
1085    inline _ITp*
1086    atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1087    { return __a->fetch_add(__d); }
1088
1089  template<typename _ITp>
1090    inline _ITp*
1091    atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1092			      ptrdiff_t __d, memory_order __m) noexcept
1093    { return __a->fetch_sub(__d, __m); }
1094
1095  template<typename _ITp>
1096    inline _ITp*
1097    atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1098			      memory_order __m) noexcept
1099    { return __a->fetch_sub(__d, __m); }
1100
1101  template<typename _ITp>
1102    inline _ITp*
1103    atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1104    { return __a->fetch_sub(__d); }
1105
1106  template<typename _ITp>
1107    inline _ITp*
1108    atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1109    { return __a->fetch_sub(__d); }
1110  // @} group atomics
1111
1112_GLIBCXX_END_NAMESPACE_VERSION
1113} // namespace
1114
1115#endif
1116