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