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