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