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