xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/atomic (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1// -*- C++ -*- header.
2
3// Copyright (C) 2008-2022 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#if __cplusplus >= 201703L
53# define __cpp_lib_atomic_is_always_lock_free 201603L
54#endif
55
56  template<typename _Tp>
57    struct atomic;
58
59  /// atomic<bool>
60  // NB: No operators or fetch-operations for this type.
61  template<>
62  struct atomic<bool>
63  {
64    using value_type = bool;
65
66  private:
67    __atomic_base<bool>	_M_base;
68
69  public:
70    atomic() noexcept = default;
71    ~atomic() noexcept = default;
72    atomic(const atomic&) = delete;
73    atomic& operator=(const atomic&) = delete;
74    atomic& operator=(const atomic&) volatile = delete;
75
76    constexpr atomic(bool __i) noexcept : _M_base(__i) { }
77
78    bool
79    operator=(bool __i) noexcept
80    { return _M_base.operator=(__i); }
81
82    bool
83    operator=(bool __i) volatile noexcept
84    { return _M_base.operator=(__i); }
85
86    operator bool() const noexcept
87    { return _M_base.load(); }
88
89    operator bool() const volatile noexcept
90    { return _M_base.load(); }
91
92    bool
93    is_lock_free() const noexcept { return _M_base.is_lock_free(); }
94
95    bool
96    is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
97
98#if __cplusplus >= 201703L
99    static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2;
100#endif
101
102    void
103    store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
104    { _M_base.store(__i, __m); }
105
106    void
107    store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
108    { _M_base.store(__i, __m); }
109
110    bool
111    load(memory_order __m = memory_order_seq_cst) const noexcept
112    { return _M_base.load(__m); }
113
114    bool
115    load(memory_order __m = memory_order_seq_cst) const volatile noexcept
116    { return _M_base.load(__m); }
117
118    bool
119    exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
120    { return _M_base.exchange(__i, __m); }
121
122    bool
123    exchange(bool __i,
124	     memory_order __m = memory_order_seq_cst) volatile noexcept
125    { return _M_base.exchange(__i, __m); }
126
127    bool
128    compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
129			  memory_order __m2) noexcept
130    { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
131
132    bool
133    compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
134			  memory_order __m2) volatile noexcept
135    { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
136
137    bool
138    compare_exchange_weak(bool& __i1, bool __i2,
139			  memory_order __m = memory_order_seq_cst) noexcept
140    { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
141
142    bool
143    compare_exchange_weak(bool& __i1, bool __i2,
144		     memory_order __m = memory_order_seq_cst) volatile noexcept
145    { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
146
147    bool
148    compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
149			    memory_order __m2) noexcept
150    { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
151
152    bool
153    compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
154			    memory_order __m2) volatile noexcept
155    { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
156
157    bool
158    compare_exchange_strong(bool& __i1, bool __i2,
159			    memory_order __m = memory_order_seq_cst) noexcept
160    { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
161
162    bool
163    compare_exchange_strong(bool& __i1, bool __i2,
164		    memory_order __m = memory_order_seq_cst) volatile noexcept
165    { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
166
167#if __cpp_lib_atomic_wait
168    void
169    wait(bool __old, memory_order __m = memory_order_seq_cst) const noexcept
170    { _M_base.wait(__old, __m); }
171
172    // TODO add const volatile overload
173
174    void
175    notify_one() noexcept
176    { _M_base.notify_one(); }
177
178    void
179    notify_all() noexcept
180    { _M_base.notify_all(); }
181#endif // __cpp_lib_atomic_wait
182  };
183
184/// @cond undocumented
185#if __cpp_lib_atomic_value_initialization
186# define _GLIBCXX20_INIT(I) = I
187#else
188# define _GLIBCXX20_INIT(I)
189#endif
190/// @endcond
191
192  /**
193   *  @brief Generic atomic type, primary class template.
194   *
195   *  @tparam _Tp  Type to be made atomic, must be trivially copyable.
196   */
197  template<typename _Tp>
198    struct atomic
199    {
200      using value_type = _Tp;
201
202    private:
203      // Align 1/2/4/8/16-byte types to at least their size.
204      static constexpr int _S_min_alignment
205	= (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
206	? 0 : sizeof(_Tp);
207
208      static constexpr int _S_alignment
209        = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
210
211      alignas(_S_alignment) _Tp _M_i _GLIBCXX20_INIT(_Tp());
212
213      static_assert(__is_trivially_copyable(_Tp),
214		    "std::atomic requires a trivially copyable type");
215
216      static_assert(sizeof(_Tp) > 0,
217		    "Incomplete or zero-sized types are not supported");
218
219#if __cplusplus > 201703L
220      static_assert(is_copy_constructible_v<_Tp>);
221      static_assert(is_move_constructible_v<_Tp>);
222      static_assert(is_copy_assignable_v<_Tp>);
223      static_assert(is_move_assignable_v<_Tp>);
224#endif
225
226    public:
227      atomic() = default;
228      ~atomic() noexcept = default;
229      atomic(const atomic&) = delete;
230      atomic& operator=(const atomic&) = delete;
231      atomic& operator=(const atomic&) volatile = delete;
232
233      constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
234
235      operator _Tp() const noexcept
236      { return load(); }
237
238      operator _Tp() const volatile noexcept
239      { return load(); }
240
241      _Tp
242      operator=(_Tp __i) noexcept
243      { store(__i); return __i; }
244
245      _Tp
246      operator=(_Tp __i) volatile noexcept
247      { store(__i); return __i; }
248
249      bool
250      is_lock_free() const noexcept
251      {
252	// Produce a fake, minimally aligned pointer.
253	return __atomic_is_lock_free(sizeof(_M_i),
254	    reinterpret_cast<void *>(-_S_alignment));
255      }
256
257      bool
258      is_lock_free() const volatile noexcept
259      {
260	// Produce a fake, minimally aligned pointer.
261	return __atomic_is_lock_free(sizeof(_M_i),
262	    reinterpret_cast<void *>(-_S_alignment));
263      }
264
265#if __cplusplus >= 201703L
266      static constexpr bool is_always_lock_free
267	= __atomic_always_lock_free(sizeof(_M_i), 0);
268#endif
269
270      void
271      store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
272      {
273	__atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m));
274      }
275
276      void
277      store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
278      {
279	__atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m));
280      }
281
282      _Tp
283      load(memory_order __m = memory_order_seq_cst) const noexcept
284      {
285	alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
286	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
287	__atomic_load(std::__addressof(_M_i), __ptr, int(__m));
288	return *__ptr;
289      }
290
291      _Tp
292      load(memory_order __m = memory_order_seq_cst) const volatile noexcept
293      {
294        alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
295	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
296	__atomic_load(std::__addressof(_M_i), __ptr, int(__m));
297	return *__ptr;
298      }
299
300      _Tp
301      exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
302      {
303        alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
304	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
305	__atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
306			  __ptr, int(__m));
307	return *__ptr;
308      }
309
310      _Tp
311      exchange(_Tp __i,
312	       memory_order __m = memory_order_seq_cst) volatile noexcept
313      {
314        alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
315	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
316	__atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
317			  __ptr, int(__m));
318	return *__ptr;
319      }
320
321      bool
322      compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
323			    memory_order __f) noexcept
324      {
325	__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
326
327	return __atomic_compare_exchange(std::__addressof(_M_i),
328					 std::__addressof(__e),
329					 std::__addressof(__i),
330					 true, int(__s), int(__f));
331      }
332
333      bool
334      compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
335			    memory_order __f) volatile noexcept
336      {
337	__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
338
339	return __atomic_compare_exchange(std::__addressof(_M_i),
340					 std::__addressof(__e),
341					 std::__addressof(__i),
342					 true, int(__s), int(__f));
343      }
344
345      bool
346      compare_exchange_weak(_Tp& __e, _Tp __i,
347			    memory_order __m = memory_order_seq_cst) noexcept
348      { return compare_exchange_weak(__e, __i, __m,
349                                     __cmpexch_failure_order(__m)); }
350
351      bool
352      compare_exchange_weak(_Tp& __e, _Tp __i,
353		     memory_order __m = memory_order_seq_cst) volatile noexcept
354      { return compare_exchange_weak(__e, __i, __m,
355                                     __cmpexch_failure_order(__m)); }
356
357      bool
358      compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
359			      memory_order __f) noexcept
360      {
361	__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
362
363	return __atomic_compare_exchange(std::__addressof(_M_i),
364					 std::__addressof(__e),
365					 std::__addressof(__i),
366					 false, int(__s), int(__f));
367      }
368
369      bool
370      compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
371			      memory_order __f) volatile noexcept
372      {
373	__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
374
375	return __atomic_compare_exchange(std::__addressof(_M_i),
376					 std::__addressof(__e),
377					 std::__addressof(__i),
378					 false, int(__s), int(__f));
379      }
380
381      bool
382      compare_exchange_strong(_Tp& __e, _Tp __i,
383			       memory_order __m = memory_order_seq_cst) noexcept
384      { return compare_exchange_strong(__e, __i, __m,
385                                       __cmpexch_failure_order(__m)); }
386
387      bool
388      compare_exchange_strong(_Tp& __e, _Tp __i,
389		     memory_order __m = memory_order_seq_cst) volatile noexcept
390      { return compare_exchange_strong(__e, __i, __m,
391                                       __cmpexch_failure_order(__m)); }
392
393#if __cpp_lib_atomic_wait
394    void
395    wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
396    {
397      std::__atomic_wait_address_v(&_M_i, __old,
398			 [__m, this] { return this->load(__m); });
399    }
400
401    // TODO add const volatile overload
402
403    void
404    notify_one() noexcept
405    { std::__atomic_notify_address(&_M_i, false); }
406
407    void
408    notify_all() noexcept
409    { std::__atomic_notify_address(&_M_i, true); }
410#endif // __cpp_lib_atomic_wait
411
412    };
413#undef _GLIBCXX20_INIT
414
415  /// Partial specialization for pointer types.
416  template<typename _Tp>
417    struct atomic<_Tp*>
418    {
419      using value_type = _Tp*;
420      using difference_type = ptrdiff_t;
421
422      typedef _Tp* 			__pointer_type;
423      typedef __atomic_base<_Tp*>	__base_type;
424      __base_type			_M_b;
425
426      atomic() noexcept = default;
427      ~atomic() noexcept = default;
428      atomic(const atomic&) = delete;
429      atomic& operator=(const atomic&) = delete;
430      atomic& operator=(const atomic&) volatile = delete;
431
432      constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
433
434      operator __pointer_type() const noexcept
435      { return __pointer_type(_M_b); }
436
437      operator __pointer_type() const volatile noexcept
438      { return __pointer_type(_M_b); }
439
440      __pointer_type
441      operator=(__pointer_type __p) noexcept
442      { return _M_b.operator=(__p); }
443
444      __pointer_type
445      operator=(__pointer_type __p) volatile noexcept
446      { return _M_b.operator=(__p); }
447
448      __pointer_type
449      operator++(int) noexcept
450      {
451#if __cplusplus >= 201703L
452	static_assert( is_object<_Tp>::value, "pointer to object type" );
453#endif
454	return _M_b++;
455      }
456
457      __pointer_type
458      operator++(int) volatile noexcept
459      {
460#if __cplusplus >= 201703L
461	static_assert( is_object<_Tp>::value, "pointer to object type" );
462#endif
463	return _M_b++;
464      }
465
466      __pointer_type
467      operator--(int) noexcept
468      {
469#if __cplusplus >= 201703L
470	static_assert( is_object<_Tp>::value, "pointer to object type" );
471#endif
472	return _M_b--;
473      }
474
475      __pointer_type
476      operator--(int) volatile noexcept
477      {
478#if __cplusplus >= 201703L
479	static_assert( is_object<_Tp>::value, "pointer to object type" );
480#endif
481	return _M_b--;
482      }
483
484      __pointer_type
485      operator++() noexcept
486      {
487#if __cplusplus >= 201703L
488	static_assert( is_object<_Tp>::value, "pointer to object type" );
489#endif
490	return ++_M_b;
491      }
492
493      __pointer_type
494      operator++() volatile noexcept
495      {
496#if __cplusplus >= 201703L
497	static_assert( is_object<_Tp>::value, "pointer to object type" );
498#endif
499	return ++_M_b;
500      }
501
502      __pointer_type
503      operator--() noexcept
504      {
505#if __cplusplus >= 201703L
506	static_assert( is_object<_Tp>::value, "pointer to object type" );
507#endif
508	return --_M_b;
509      }
510
511      __pointer_type
512      operator--() volatile noexcept
513      {
514#if __cplusplus >= 201703L
515	static_assert( is_object<_Tp>::value, "pointer to object type" );
516#endif
517	return --_M_b;
518      }
519
520      __pointer_type
521      operator+=(ptrdiff_t __d) noexcept
522      {
523#if __cplusplus >= 201703L
524	static_assert( is_object<_Tp>::value, "pointer to object type" );
525#endif
526	return _M_b.operator+=(__d);
527      }
528
529      __pointer_type
530      operator+=(ptrdiff_t __d) volatile noexcept
531      {
532#if __cplusplus >= 201703L
533	static_assert( is_object<_Tp>::value, "pointer to object type" );
534#endif
535	return _M_b.operator+=(__d);
536      }
537
538      __pointer_type
539      operator-=(ptrdiff_t __d) noexcept
540      {
541#if __cplusplus >= 201703L
542	static_assert( is_object<_Tp>::value, "pointer to object type" );
543#endif
544	return _M_b.operator-=(__d);
545      }
546
547      __pointer_type
548      operator-=(ptrdiff_t __d) volatile noexcept
549      {
550#if __cplusplus >= 201703L
551	static_assert( is_object<_Tp>::value, "pointer to object type" );
552#endif
553	return _M_b.operator-=(__d);
554      }
555
556      bool
557      is_lock_free() const noexcept
558      { return _M_b.is_lock_free(); }
559
560      bool
561      is_lock_free() const volatile noexcept
562      { return _M_b.is_lock_free(); }
563
564#if __cplusplus >= 201703L
565      static constexpr bool is_always_lock_free
566	= ATOMIC_POINTER_LOCK_FREE == 2;
567#endif
568
569      void
570      store(__pointer_type __p,
571	    memory_order __m = memory_order_seq_cst) noexcept
572      { return _M_b.store(__p, __m); }
573
574      void
575      store(__pointer_type __p,
576	    memory_order __m = memory_order_seq_cst) volatile noexcept
577      { return _M_b.store(__p, __m); }
578
579      __pointer_type
580      load(memory_order __m = memory_order_seq_cst) const noexcept
581      { return _M_b.load(__m); }
582
583      __pointer_type
584      load(memory_order __m = memory_order_seq_cst) const volatile noexcept
585      { return _M_b.load(__m); }
586
587      __pointer_type
588      exchange(__pointer_type __p,
589	       memory_order __m = memory_order_seq_cst) noexcept
590      { return _M_b.exchange(__p, __m); }
591
592      __pointer_type
593      exchange(__pointer_type __p,
594	       memory_order __m = memory_order_seq_cst) volatile noexcept
595      { return _M_b.exchange(__p, __m); }
596
597      bool
598      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
599			    memory_order __m1, memory_order __m2) noexcept
600      { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); }
601
602      bool
603      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
604			    memory_order __m1,
605			    memory_order __m2) volatile noexcept
606      { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); }
607
608      bool
609      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
610			    memory_order __m = memory_order_seq_cst) noexcept
611      {
612	return compare_exchange_weak(__p1, __p2, __m,
613				     __cmpexch_failure_order(__m));
614      }
615
616      bool
617      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
618		    memory_order __m = memory_order_seq_cst) volatile noexcept
619      {
620	return compare_exchange_weak(__p1, __p2, __m,
621				     __cmpexch_failure_order(__m));
622      }
623
624      bool
625      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
626			      memory_order __m1, memory_order __m2) noexcept
627      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
628
629      bool
630      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
631			      memory_order __m1,
632			      memory_order __m2) volatile noexcept
633      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
634
635      bool
636      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
637			      memory_order __m = memory_order_seq_cst) noexcept
638      {
639	return _M_b.compare_exchange_strong(__p1, __p2, __m,
640					    __cmpexch_failure_order(__m));
641      }
642
643      bool
644      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
645		    memory_order __m = memory_order_seq_cst) volatile noexcept
646      {
647	return _M_b.compare_exchange_strong(__p1, __p2, __m,
648					    __cmpexch_failure_order(__m));
649      }
650
651#if __cpp_lib_atomic_wait
652    void
653    wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) const noexcept
654    { _M_b.wait(__old, __m); }
655
656    // TODO add const volatile overload
657
658    void
659    notify_one() noexcept
660    { _M_b.notify_one(); }
661
662    void
663    notify_all() noexcept
664    { _M_b.notify_all(); }
665#endif // __cpp_lib_atomic_wait
666
667      __pointer_type
668      fetch_add(ptrdiff_t __d,
669		memory_order __m = memory_order_seq_cst) noexcept
670      {
671#if __cplusplus >= 201703L
672	static_assert( is_object<_Tp>::value, "pointer to object type" );
673#endif
674	return _M_b.fetch_add(__d, __m);
675      }
676
677      __pointer_type
678      fetch_add(ptrdiff_t __d,
679		memory_order __m = memory_order_seq_cst) volatile noexcept
680      {
681#if __cplusplus >= 201703L
682	static_assert( is_object<_Tp>::value, "pointer to object type" );
683#endif
684	return _M_b.fetch_add(__d, __m);
685      }
686
687      __pointer_type
688      fetch_sub(ptrdiff_t __d,
689		memory_order __m = memory_order_seq_cst) noexcept
690      {
691#if __cplusplus >= 201703L
692	static_assert( is_object<_Tp>::value, "pointer to object type" );
693#endif
694	return _M_b.fetch_sub(__d, __m);
695      }
696
697      __pointer_type
698      fetch_sub(ptrdiff_t __d,
699		memory_order __m = memory_order_seq_cst) volatile noexcept
700      {
701#if __cplusplus >= 201703L
702	static_assert( is_object<_Tp>::value, "pointer to object type" );
703#endif
704	return _M_b.fetch_sub(__d, __m);
705      }
706    };
707
708
709  /// Explicit specialization for char.
710  template<>
711    struct atomic<char> : __atomic_base<char>
712    {
713      typedef char 			__integral_type;
714      typedef __atomic_base<char> 	__base_type;
715
716      atomic() noexcept = default;
717      ~atomic() noexcept = default;
718      atomic(const atomic&) = delete;
719      atomic& operator=(const atomic&) = delete;
720      atomic& operator=(const atomic&) volatile = delete;
721
722      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
723
724      using __base_type::operator __integral_type;
725      using __base_type::operator=;
726
727#if __cplusplus >= 201703L
728      static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
729#endif
730    };
731
732  /// Explicit specialization for signed char.
733  template<>
734    struct atomic<signed char> : __atomic_base<signed char>
735    {
736      typedef signed char 		__integral_type;
737      typedef __atomic_base<signed char> 	__base_type;
738
739      atomic() noexcept= default;
740      ~atomic() noexcept = default;
741      atomic(const atomic&) = delete;
742      atomic& operator=(const atomic&) = delete;
743      atomic& operator=(const atomic&) volatile = delete;
744
745      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
746
747      using __base_type::operator __integral_type;
748      using __base_type::operator=;
749
750#if __cplusplus >= 201703L
751      static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
752#endif
753    };
754
755  /// Explicit specialization for unsigned char.
756  template<>
757    struct atomic<unsigned char> : __atomic_base<unsigned char>
758    {
759      typedef unsigned char 		__integral_type;
760      typedef __atomic_base<unsigned char> 	__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#if __cplusplus >= 201703L
774      static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
775#endif
776    };
777
778  /// Explicit specialization for short.
779  template<>
780    struct atomic<short> : __atomic_base<short>
781    {
782      typedef short 			__integral_type;
783      typedef __atomic_base<short> 		__base_type;
784
785      atomic() noexcept = default;
786      ~atomic() noexcept = default;
787      atomic(const atomic&) = delete;
788      atomic& operator=(const atomic&) = delete;
789      atomic& operator=(const atomic&) volatile = delete;
790
791      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
792
793      using __base_type::operator __integral_type;
794      using __base_type::operator=;
795
796#if __cplusplus >= 201703L
797      static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
798#endif
799    };
800
801  /// Explicit specialization for unsigned short.
802  template<>
803    struct atomic<unsigned short> : __atomic_base<unsigned short>
804    {
805      typedef unsigned short 	      	__integral_type;
806      typedef __atomic_base<unsigned short> 		__base_type;
807
808      atomic() noexcept = default;
809      ~atomic() noexcept = default;
810      atomic(const atomic&) = delete;
811      atomic& operator=(const atomic&) = delete;
812      atomic& operator=(const atomic&) volatile = delete;
813
814      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
815
816      using __base_type::operator __integral_type;
817      using __base_type::operator=;
818
819#if __cplusplus >= 201703L
820      static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
821#endif
822    };
823
824  /// Explicit specialization for int.
825  template<>
826    struct atomic<int> : __atomic_base<int>
827    {
828      typedef int 			__integral_type;
829      typedef __atomic_base<int> 		__base_type;
830
831      atomic() noexcept = default;
832      ~atomic() noexcept = default;
833      atomic(const atomic&) = delete;
834      atomic& operator=(const atomic&) = delete;
835      atomic& operator=(const atomic&) volatile = delete;
836
837      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
838
839      using __base_type::operator __integral_type;
840      using __base_type::operator=;
841
842#if __cplusplus >= 201703L
843      static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
844#endif
845    };
846
847  /// Explicit specialization for unsigned int.
848  template<>
849    struct atomic<unsigned int> : __atomic_base<unsigned int>
850    {
851      typedef unsigned int		__integral_type;
852      typedef __atomic_base<unsigned int> 	__base_type;
853
854      atomic() noexcept = default;
855      ~atomic() noexcept = default;
856      atomic(const atomic&) = delete;
857      atomic& operator=(const atomic&) = delete;
858      atomic& operator=(const atomic&) volatile = delete;
859
860      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
861
862      using __base_type::operator __integral_type;
863      using __base_type::operator=;
864
865#if __cplusplus >= 201703L
866      static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
867#endif
868    };
869
870  /// Explicit specialization for long.
871  template<>
872    struct atomic<long> : __atomic_base<long>
873    {
874      typedef long 			__integral_type;
875      typedef __atomic_base<long> 	__base_type;
876
877      atomic() noexcept = default;
878      ~atomic() noexcept = default;
879      atomic(const atomic&) = delete;
880      atomic& operator=(const atomic&) = delete;
881      atomic& operator=(const atomic&) volatile = delete;
882
883      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
884
885      using __base_type::operator __integral_type;
886      using __base_type::operator=;
887
888#if __cplusplus >= 201703L
889      static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
890#endif
891    };
892
893  /// Explicit specialization for unsigned long.
894  template<>
895    struct atomic<unsigned long> : __atomic_base<unsigned long>
896    {
897      typedef unsigned long 		__integral_type;
898      typedef __atomic_base<unsigned long> 	__base_type;
899
900      atomic() noexcept = default;
901      ~atomic() noexcept = default;
902      atomic(const atomic&) = delete;
903      atomic& operator=(const atomic&) = delete;
904      atomic& operator=(const atomic&) volatile = delete;
905
906      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
907
908      using __base_type::operator __integral_type;
909      using __base_type::operator=;
910
911#if __cplusplus >= 201703L
912      static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
913#endif
914    };
915
916  /// Explicit specialization for long long.
917  template<>
918    struct atomic<long long> : __atomic_base<long long>
919    {
920      typedef long long 		__integral_type;
921      typedef __atomic_base<long long> 		__base_type;
922
923      atomic() noexcept = default;
924      ~atomic() noexcept = default;
925      atomic(const atomic&) = delete;
926      atomic& operator=(const atomic&) = delete;
927      atomic& operator=(const atomic&) volatile = delete;
928
929      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
930
931      using __base_type::operator __integral_type;
932      using __base_type::operator=;
933
934#if __cplusplus >= 201703L
935      static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
936#endif
937    };
938
939  /// Explicit specialization for unsigned long long.
940  template<>
941    struct atomic<unsigned long long> : __atomic_base<unsigned long long>
942    {
943      typedef unsigned long long       	__integral_type;
944      typedef __atomic_base<unsigned long long> 	__base_type;
945
946      atomic() noexcept = default;
947      ~atomic() noexcept = default;
948      atomic(const atomic&) = delete;
949      atomic& operator=(const atomic&) = delete;
950      atomic& operator=(const atomic&) volatile = delete;
951
952      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
953
954      using __base_type::operator __integral_type;
955      using __base_type::operator=;
956
957#if __cplusplus >= 201703L
958      static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
959#endif
960    };
961
962  /// Explicit specialization for wchar_t.
963  template<>
964    struct atomic<wchar_t> : __atomic_base<wchar_t>
965    {
966      typedef wchar_t 			__integral_type;
967      typedef __atomic_base<wchar_t> 	__base_type;
968
969      atomic() noexcept = default;
970      ~atomic() noexcept = default;
971      atomic(const atomic&) = delete;
972      atomic& operator=(const atomic&) = delete;
973      atomic& operator=(const atomic&) volatile = delete;
974
975      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
976
977      using __base_type::operator __integral_type;
978      using __base_type::operator=;
979
980#if __cplusplus >= 201703L
981      static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2;
982#endif
983    };
984
985#ifdef _GLIBCXX_USE_CHAR8_T
986  /// Explicit specialization for char8_t.
987  template<>
988    struct atomic<char8_t> : __atomic_base<char8_t>
989    {
990      typedef char8_t 			__integral_type;
991      typedef __atomic_base<char8_t> 	__base_type;
992
993      atomic() noexcept = default;
994      ~atomic() noexcept = default;
995      atomic(const atomic&) = delete;
996      atomic& operator=(const atomic&) = delete;
997      atomic& operator=(const atomic&) volatile = delete;
998
999      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1000
1001      using __base_type::operator __integral_type;
1002      using __base_type::operator=;
1003
1004#if __cplusplus > 201402L
1005      static constexpr bool is_always_lock_free
1006	= ATOMIC_CHAR8_T_LOCK_FREE == 2;
1007#endif
1008    };
1009#endif
1010
1011  /// Explicit specialization for char16_t.
1012  template<>
1013    struct atomic<char16_t> : __atomic_base<char16_t>
1014    {
1015      typedef char16_t 			__integral_type;
1016      typedef __atomic_base<char16_t> 	__base_type;
1017
1018      atomic() noexcept = default;
1019      ~atomic() noexcept = default;
1020      atomic(const atomic&) = delete;
1021      atomic& operator=(const atomic&) = delete;
1022      atomic& operator=(const atomic&) volatile = delete;
1023
1024      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1025
1026      using __base_type::operator __integral_type;
1027      using __base_type::operator=;
1028
1029#if __cplusplus >= 201703L
1030      static constexpr bool is_always_lock_free
1031	= ATOMIC_CHAR16_T_LOCK_FREE == 2;
1032#endif
1033    };
1034
1035  /// Explicit specialization for char32_t.
1036  template<>
1037    struct atomic<char32_t> : __atomic_base<char32_t>
1038    {
1039      typedef char32_t 			__integral_type;
1040      typedef __atomic_base<char32_t> 	__base_type;
1041
1042      atomic() noexcept = default;
1043      ~atomic() noexcept = default;
1044      atomic(const atomic&) = delete;
1045      atomic& operator=(const atomic&) = delete;
1046      atomic& operator=(const atomic&) volatile = delete;
1047
1048      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1049
1050      using __base_type::operator __integral_type;
1051      using __base_type::operator=;
1052
1053#if __cplusplus >= 201703L
1054      static constexpr bool is_always_lock_free
1055	= ATOMIC_CHAR32_T_LOCK_FREE == 2;
1056#endif
1057    };
1058
1059
1060  /// atomic_bool
1061  typedef atomic<bool>			atomic_bool;
1062
1063  /// atomic_char
1064  typedef atomic<char>			atomic_char;
1065
1066  /// atomic_schar
1067  typedef atomic<signed char>		atomic_schar;
1068
1069  /// atomic_uchar
1070  typedef atomic<unsigned char>		atomic_uchar;
1071
1072  /// atomic_short
1073  typedef atomic<short>			atomic_short;
1074
1075  /// atomic_ushort
1076  typedef atomic<unsigned short>	atomic_ushort;
1077
1078  /// atomic_int
1079  typedef atomic<int>			atomic_int;
1080
1081  /// atomic_uint
1082  typedef atomic<unsigned int>		atomic_uint;
1083
1084  /// atomic_long
1085  typedef atomic<long>			atomic_long;
1086
1087  /// atomic_ulong
1088  typedef atomic<unsigned long>		atomic_ulong;
1089
1090  /// atomic_llong
1091  typedef atomic<long long>		atomic_llong;
1092
1093  /// atomic_ullong
1094  typedef atomic<unsigned long long>	atomic_ullong;
1095
1096  /// atomic_wchar_t
1097  typedef atomic<wchar_t>		atomic_wchar_t;
1098
1099#ifdef _GLIBCXX_USE_CHAR8_T
1100  /// atomic_char8_t
1101  typedef atomic<char8_t>		atomic_char8_t;
1102#endif
1103
1104  /// atomic_char16_t
1105  typedef atomic<char16_t>		atomic_char16_t;
1106
1107  /// atomic_char32_t
1108  typedef atomic<char32_t>		atomic_char32_t;
1109
1110#ifdef _GLIBCXX_USE_C99_STDINT_TR1
1111  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1112  // 2441. Exact-width atomic typedefs should be provided
1113
1114  /// atomic_int8_t
1115  typedef atomic<int8_t>		atomic_int8_t;
1116
1117  /// atomic_uint8_t
1118  typedef atomic<uint8_t>		atomic_uint8_t;
1119
1120  /// atomic_int16_t
1121  typedef atomic<int16_t>		atomic_int16_t;
1122
1123  /// atomic_uint16_t
1124  typedef atomic<uint16_t>		atomic_uint16_t;
1125
1126  /// atomic_int32_t
1127  typedef atomic<int32_t>		atomic_int32_t;
1128
1129  /// atomic_uint32_t
1130  typedef atomic<uint32_t>		atomic_uint32_t;
1131
1132  /// atomic_int64_t
1133  typedef atomic<int64_t>		atomic_int64_t;
1134
1135  /// atomic_uint64_t
1136  typedef atomic<uint64_t>		atomic_uint64_t;
1137
1138
1139  /// atomic_int_least8_t
1140  typedef atomic<int_least8_t>		atomic_int_least8_t;
1141
1142  /// atomic_uint_least8_t
1143  typedef atomic<uint_least8_t>		atomic_uint_least8_t;
1144
1145  /// atomic_int_least16_t
1146  typedef atomic<int_least16_t>		atomic_int_least16_t;
1147
1148  /// atomic_uint_least16_t
1149  typedef atomic<uint_least16_t>	atomic_uint_least16_t;
1150
1151  /// atomic_int_least32_t
1152  typedef atomic<int_least32_t>		atomic_int_least32_t;
1153
1154  /// atomic_uint_least32_t
1155  typedef atomic<uint_least32_t>	atomic_uint_least32_t;
1156
1157  /// atomic_int_least64_t
1158  typedef atomic<int_least64_t>		atomic_int_least64_t;
1159
1160  /// atomic_uint_least64_t
1161  typedef atomic<uint_least64_t>	atomic_uint_least64_t;
1162
1163
1164  /// atomic_int_fast8_t
1165  typedef atomic<int_fast8_t>		atomic_int_fast8_t;
1166
1167  /// atomic_uint_fast8_t
1168  typedef atomic<uint_fast8_t>		atomic_uint_fast8_t;
1169
1170  /// atomic_int_fast16_t
1171  typedef atomic<int_fast16_t>		atomic_int_fast16_t;
1172
1173  /// atomic_uint_fast16_t
1174  typedef atomic<uint_fast16_t>		atomic_uint_fast16_t;
1175
1176  /// atomic_int_fast32_t
1177  typedef atomic<int_fast32_t>		atomic_int_fast32_t;
1178
1179  /// atomic_uint_fast32_t
1180  typedef atomic<uint_fast32_t>		atomic_uint_fast32_t;
1181
1182  /// atomic_int_fast64_t
1183  typedef atomic<int_fast64_t>		atomic_int_fast64_t;
1184
1185  /// atomic_uint_fast64_t
1186  typedef atomic<uint_fast64_t>		atomic_uint_fast64_t;
1187#endif
1188
1189
1190  /// atomic_intptr_t
1191  typedef atomic<intptr_t>		atomic_intptr_t;
1192
1193  /// atomic_uintptr_t
1194  typedef atomic<uintptr_t>		atomic_uintptr_t;
1195
1196  /// atomic_size_t
1197  typedef atomic<size_t>		atomic_size_t;
1198
1199  /// atomic_ptrdiff_t
1200  typedef atomic<ptrdiff_t>		atomic_ptrdiff_t;
1201
1202#ifdef _GLIBCXX_USE_C99_STDINT_TR1
1203  /// atomic_intmax_t
1204  typedef atomic<intmax_t>		atomic_intmax_t;
1205
1206  /// atomic_uintmax_t
1207  typedef atomic<uintmax_t>		atomic_uintmax_t;
1208#endif
1209
1210  // Function definitions, atomic_flag operations.
1211  inline bool
1212  atomic_flag_test_and_set_explicit(atomic_flag* __a,
1213				    memory_order __m) noexcept
1214  { return __a->test_and_set(__m); }
1215
1216  inline bool
1217  atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
1218				    memory_order __m) noexcept
1219  { return __a->test_and_set(__m); }
1220
1221#if __cpp_lib_atomic_flag_test
1222  inline bool
1223  atomic_flag_test(const atomic_flag* __a) noexcept
1224  { return __a->test(); }
1225
1226  inline bool
1227  atomic_flag_test(const volatile atomic_flag* __a) noexcept
1228  { return __a->test(); }
1229
1230  inline bool
1231  atomic_flag_test_explicit(const atomic_flag* __a,
1232			    memory_order __m) noexcept
1233  { return __a->test(__m); }
1234
1235  inline bool
1236  atomic_flag_test_explicit(const volatile atomic_flag* __a,
1237			    memory_order __m) noexcept
1238  { return __a->test(__m); }
1239#endif
1240
1241  inline void
1242  atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
1243  { __a->clear(__m); }
1244
1245  inline void
1246  atomic_flag_clear_explicit(volatile atomic_flag* __a,
1247			     memory_order __m) noexcept
1248  { __a->clear(__m); }
1249
1250  inline bool
1251  atomic_flag_test_and_set(atomic_flag* __a) noexcept
1252  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1253
1254  inline bool
1255  atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
1256  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1257
1258  inline void
1259  atomic_flag_clear(atomic_flag* __a) noexcept
1260  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1261
1262  inline void
1263  atomic_flag_clear(volatile atomic_flag* __a) noexcept
1264  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1265
1266#if __cpp_lib_atomic_wait
1267  inline void
1268  atomic_flag_wait(atomic_flag* __a, bool __old) noexcept
1269  { __a->wait(__old); }
1270
1271  inline void
1272  atomic_flag_wait_explicit(atomic_flag* __a, bool __old,
1273                                memory_order __m) noexcept
1274  { __a->wait(__old, __m); }
1275
1276  inline void
1277  atomic_flag_notify_one(atomic_flag* __a) noexcept
1278  { __a->notify_one(); }
1279
1280  inline void
1281  atomic_flag_notify_all(atomic_flag* __a) noexcept
1282  { __a->notify_all(); }
1283#endif // __cpp_lib_atomic_wait
1284
1285  /// @cond undocumented
1286  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1287  // 3220. P0558 broke conforming C++14 uses of atomic shared_ptr
1288  template<typename _Tp>
1289    using __atomic_val_t = __type_identity_t<_Tp>;
1290  template<typename _Tp>
1291    using __atomic_diff_t = typename atomic<_Tp>::difference_type;
1292  /// @endcond
1293
1294  // [atomics.nonmembers] Non-member functions.
1295  // Function templates generally applicable to atomic types.
1296  template<typename _ITp>
1297    inline bool
1298    atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
1299    { return __a->is_lock_free(); }
1300
1301  template<typename _ITp>
1302    inline bool
1303    atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
1304    { return __a->is_lock_free(); }
1305
1306  template<typename _ITp>
1307    inline void
1308    atomic_init(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1309    { __a->store(__i, memory_order_relaxed); }
1310
1311  template<typename _ITp>
1312    inline void
1313    atomic_init(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1314    { __a->store(__i, memory_order_relaxed); }
1315
1316  template<typename _ITp>
1317    inline void
1318    atomic_store_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
1319			  memory_order __m) noexcept
1320    { __a->store(__i, __m); }
1321
1322  template<typename _ITp>
1323    inline void
1324    atomic_store_explicit(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
1325			  memory_order __m) noexcept
1326    { __a->store(__i, __m); }
1327
1328  template<typename _ITp>
1329    inline _ITp
1330    atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
1331    { return __a->load(__m); }
1332
1333  template<typename _ITp>
1334    inline _ITp
1335    atomic_load_explicit(const volatile atomic<_ITp>* __a,
1336			 memory_order __m) noexcept
1337    { return __a->load(__m); }
1338
1339  template<typename _ITp>
1340    inline _ITp
1341    atomic_exchange_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
1342			     memory_order __m) noexcept
1343    { return __a->exchange(__i, __m); }
1344
1345  template<typename _ITp>
1346    inline _ITp
1347    atomic_exchange_explicit(volatile atomic<_ITp>* __a,
1348			     __atomic_val_t<_ITp> __i,
1349			     memory_order __m) noexcept
1350    { return __a->exchange(__i, __m); }
1351
1352  template<typename _ITp>
1353    inline bool
1354    atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
1355					  __atomic_val_t<_ITp>* __i1,
1356					  __atomic_val_t<_ITp> __i2,
1357					  memory_order __m1,
1358					  memory_order __m2) noexcept
1359    { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1360
1361  template<typename _ITp>
1362    inline bool
1363    atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
1364					  __atomic_val_t<_ITp>* __i1,
1365					  __atomic_val_t<_ITp> __i2,
1366					  memory_order __m1,
1367					  memory_order __m2) noexcept
1368    { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1369
1370  template<typename _ITp>
1371    inline bool
1372    atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
1373					    __atomic_val_t<_ITp>* __i1,
1374					    __atomic_val_t<_ITp> __i2,
1375					    memory_order __m1,
1376					    memory_order __m2) noexcept
1377    { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1378
1379  template<typename _ITp>
1380    inline bool
1381    atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
1382					    __atomic_val_t<_ITp>* __i1,
1383					    __atomic_val_t<_ITp> __i2,
1384					    memory_order __m1,
1385					    memory_order __m2) noexcept
1386    { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1387
1388
1389  template<typename _ITp>
1390    inline void
1391    atomic_store(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1392    { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1393
1394  template<typename _ITp>
1395    inline void
1396    atomic_store(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1397    { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1398
1399  template<typename _ITp>
1400    inline _ITp
1401    atomic_load(const atomic<_ITp>* __a) noexcept
1402    { return atomic_load_explicit(__a, memory_order_seq_cst); }
1403
1404  template<typename _ITp>
1405    inline _ITp
1406    atomic_load(const volatile atomic<_ITp>* __a) noexcept
1407    { return atomic_load_explicit(__a, memory_order_seq_cst); }
1408
1409  template<typename _ITp>
1410    inline _ITp
1411    atomic_exchange(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1412    { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1413
1414  template<typename _ITp>
1415    inline _ITp
1416    atomic_exchange(volatile atomic<_ITp>* __a,
1417		    __atomic_val_t<_ITp> __i) noexcept
1418    { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1419
1420  template<typename _ITp>
1421    inline bool
1422    atomic_compare_exchange_weak(atomic<_ITp>* __a,
1423				 __atomic_val_t<_ITp>* __i1,
1424				 __atomic_val_t<_ITp> __i2) noexcept
1425    {
1426      return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1427						   memory_order_seq_cst,
1428						   memory_order_seq_cst);
1429    }
1430
1431  template<typename _ITp>
1432    inline bool
1433    atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
1434				 __atomic_val_t<_ITp>* __i1,
1435				 __atomic_val_t<_ITp> __i2) noexcept
1436    {
1437      return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1438						   memory_order_seq_cst,
1439						   memory_order_seq_cst);
1440    }
1441
1442  template<typename _ITp>
1443    inline bool
1444    atomic_compare_exchange_strong(atomic<_ITp>* __a,
1445				   __atomic_val_t<_ITp>* __i1,
1446				   __atomic_val_t<_ITp> __i2) noexcept
1447    {
1448      return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1449						     memory_order_seq_cst,
1450						     memory_order_seq_cst);
1451    }
1452
1453  template<typename _ITp>
1454    inline bool
1455    atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
1456				   __atomic_val_t<_ITp>* __i1,
1457				   __atomic_val_t<_ITp> __i2) noexcept
1458    {
1459      return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1460						     memory_order_seq_cst,
1461						     memory_order_seq_cst);
1462    }
1463
1464
1465#if __cpp_lib_atomic_wait
1466  template<typename _Tp>
1467    inline void
1468    atomic_wait(const atomic<_Tp>* __a,
1469	        typename std::atomic<_Tp>::value_type __old) noexcept
1470    { __a->wait(__old); }
1471
1472  template<typename _Tp>
1473    inline void
1474    atomic_wait_explicit(const atomic<_Tp>* __a,
1475			 typename std::atomic<_Tp>::value_type __old,
1476			 std::memory_order __m) noexcept
1477    { __a->wait(__old, __m); }
1478
1479  template<typename _Tp>
1480    inline void
1481    atomic_notify_one(atomic<_Tp>* __a) noexcept
1482    { __a->notify_one(); }
1483
1484  template<typename _Tp>
1485    inline void
1486    atomic_notify_all(atomic<_Tp>* __a) noexcept
1487    { __a->notify_all(); }
1488#endif // __cpp_lib_atomic_wait
1489
1490  // Function templates for atomic_integral and atomic_pointer operations only.
1491  // Some operations (and, or, xor) are only available for atomic integrals,
1492  // which is implemented by taking a parameter of type __atomic_base<_ITp>*.
1493
1494  template<typename _ITp>
1495    inline _ITp
1496    atomic_fetch_add_explicit(atomic<_ITp>* __a,
1497			      __atomic_diff_t<_ITp> __i,
1498			      memory_order __m) noexcept
1499    { return __a->fetch_add(__i, __m); }
1500
1501  template<typename _ITp>
1502    inline _ITp
1503    atomic_fetch_add_explicit(volatile atomic<_ITp>* __a,
1504			      __atomic_diff_t<_ITp> __i,
1505			      memory_order __m) noexcept
1506    { return __a->fetch_add(__i, __m); }
1507
1508  template<typename _ITp>
1509    inline _ITp
1510    atomic_fetch_sub_explicit(atomic<_ITp>* __a,
1511			      __atomic_diff_t<_ITp> __i,
1512			      memory_order __m) noexcept
1513    { return __a->fetch_sub(__i, __m); }
1514
1515  template<typename _ITp>
1516    inline _ITp
1517    atomic_fetch_sub_explicit(volatile atomic<_ITp>* __a,
1518			      __atomic_diff_t<_ITp> __i,
1519			      memory_order __m) noexcept
1520    { return __a->fetch_sub(__i, __m); }
1521
1522  template<typename _ITp>
1523    inline _ITp
1524    atomic_fetch_and_explicit(__atomic_base<_ITp>* __a,
1525			      __atomic_val_t<_ITp> __i,
1526			      memory_order __m) noexcept
1527    { return __a->fetch_and(__i, __m); }
1528
1529  template<typename _ITp>
1530    inline _ITp
1531    atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a,
1532			      __atomic_val_t<_ITp> __i,
1533			      memory_order __m) noexcept
1534    { return __a->fetch_and(__i, __m); }
1535
1536  template<typename _ITp>
1537    inline _ITp
1538    atomic_fetch_or_explicit(__atomic_base<_ITp>* __a,
1539			     __atomic_val_t<_ITp> __i,
1540			     memory_order __m) noexcept
1541    { return __a->fetch_or(__i, __m); }
1542
1543  template<typename _ITp>
1544    inline _ITp
1545    atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a,
1546			     __atomic_val_t<_ITp> __i,
1547			     memory_order __m) noexcept
1548    { return __a->fetch_or(__i, __m); }
1549
1550  template<typename _ITp>
1551    inline _ITp
1552    atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a,
1553			      __atomic_val_t<_ITp> __i,
1554			      memory_order __m) noexcept
1555    { return __a->fetch_xor(__i, __m); }
1556
1557  template<typename _ITp>
1558    inline _ITp
1559    atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a,
1560			      __atomic_val_t<_ITp> __i,
1561			      memory_order __m) noexcept
1562    { return __a->fetch_xor(__i, __m); }
1563
1564  template<typename _ITp>
1565    inline _ITp
1566    atomic_fetch_add(atomic<_ITp>* __a,
1567		     __atomic_diff_t<_ITp> __i) noexcept
1568    { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1569
1570  template<typename _ITp>
1571    inline _ITp
1572    atomic_fetch_add(volatile atomic<_ITp>* __a,
1573		     __atomic_diff_t<_ITp> __i) noexcept
1574    { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1575
1576  template<typename _ITp>
1577    inline _ITp
1578    atomic_fetch_sub(atomic<_ITp>* __a,
1579		     __atomic_diff_t<_ITp> __i) noexcept
1580    { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1581
1582  template<typename _ITp>
1583    inline _ITp
1584    atomic_fetch_sub(volatile atomic<_ITp>* __a,
1585		     __atomic_diff_t<_ITp> __i) noexcept
1586    { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1587
1588  template<typename _ITp>
1589    inline _ITp
1590    atomic_fetch_and(__atomic_base<_ITp>* __a,
1591		     __atomic_val_t<_ITp> __i) noexcept
1592    { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1593
1594  template<typename _ITp>
1595    inline _ITp
1596    atomic_fetch_and(volatile __atomic_base<_ITp>* __a,
1597		     __atomic_val_t<_ITp> __i) noexcept
1598    { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1599
1600  template<typename _ITp>
1601    inline _ITp
1602    atomic_fetch_or(__atomic_base<_ITp>* __a,
1603		    __atomic_val_t<_ITp> __i) noexcept
1604    { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1605
1606  template<typename _ITp>
1607    inline _ITp
1608    atomic_fetch_or(volatile __atomic_base<_ITp>* __a,
1609		    __atomic_val_t<_ITp> __i) noexcept
1610    { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1611
1612  template<typename _ITp>
1613    inline _ITp
1614    atomic_fetch_xor(__atomic_base<_ITp>* __a,
1615		     __atomic_val_t<_ITp> __i) noexcept
1616    { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1617
1618  template<typename _ITp>
1619    inline _ITp
1620    atomic_fetch_xor(volatile __atomic_base<_ITp>* __a,
1621		     __atomic_val_t<_ITp> __i) noexcept
1622    { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1623
1624#if __cplusplus > 201703L
1625#define __cpp_lib_atomic_float 201711L
1626  template<>
1627    struct atomic<float> : __atomic_float<float>
1628    {
1629      atomic() noexcept = default;
1630
1631      constexpr
1632      atomic(float __fp) noexcept : __atomic_float<float>(__fp)
1633      { }
1634
1635      atomic& operator=(const atomic&) volatile = delete;
1636      atomic& operator=(const atomic&) = delete;
1637
1638      using __atomic_float<float>::operator=;
1639    };
1640
1641  template<>
1642    struct atomic<double> : __atomic_float<double>
1643    {
1644      atomic() noexcept = default;
1645
1646      constexpr
1647      atomic(double __fp) noexcept : __atomic_float<double>(__fp)
1648      { }
1649
1650      atomic& operator=(const atomic&) volatile = delete;
1651      atomic& operator=(const atomic&) = delete;
1652
1653      using __atomic_float<double>::operator=;
1654    };
1655
1656  template<>
1657    struct atomic<long double> : __atomic_float<long double>
1658    {
1659      atomic() noexcept = default;
1660
1661      constexpr
1662      atomic(long double __fp) noexcept : __atomic_float<long double>(__fp)
1663      { }
1664
1665      atomic& operator=(const atomic&) volatile = delete;
1666      atomic& operator=(const atomic&) = delete;
1667
1668      using __atomic_float<long double>::operator=;
1669    };
1670
1671#define __cpp_lib_atomic_ref 201806L
1672
1673  /// Class template to provide atomic operations on a non-atomic variable.
1674  template<typename _Tp>
1675    struct atomic_ref : __atomic_ref<_Tp>
1676    {
1677      explicit
1678      atomic_ref(_Tp& __t) noexcept : __atomic_ref<_Tp>(__t)
1679      { }
1680
1681      atomic_ref& operator=(const atomic_ref&) = delete;
1682
1683      atomic_ref(const atomic_ref&) = default;
1684
1685      using __atomic_ref<_Tp>::operator=;
1686    };
1687
1688#endif // C++2a
1689
1690  /// @} group atomics
1691
1692_GLIBCXX_END_NAMESPACE_VERSION
1693} // namespace
1694
1695#endif // C++11
1696
1697#endif // _GLIBCXX_ATOMIC
1698