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