libstdc++

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