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