libstdc++
|
00001 // -*- C++ -*- header. 00002 00003 // Copyright (C) 2008-2014 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file include/atomic 00026 * This is a Standard C++ Library header. 00027 */ 00028 00029 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl. 00030 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html 00031 00032 #ifndef _GLIBCXX_ATOMIC 00033 #define _GLIBCXX_ATOMIC 1 00034 00035 #pragma GCC system_header 00036 00037 #if __cplusplus < 201103L 00038 # include <bits/c++0x_warning.h> 00039 #endif 00040 00041 #include <bits/atomic_base.h> 00042 00043 namespace std _GLIBCXX_VISIBILITY(default) 00044 { 00045 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00046 00047 /** 00048 * @addtogroup atomics 00049 * @{ 00050 */ 00051 00052 /// atomic_bool 00053 // NB: No operators or fetch-operations for this type. 00054 struct atomic_bool 00055 { 00056 private: 00057 __atomic_base<bool> _M_base; 00058 00059 public: 00060 atomic_bool() noexcept = default; 00061 ~atomic_bool() noexcept = default; 00062 atomic_bool(const atomic_bool&) = delete; 00063 atomic_bool& operator=(const atomic_bool&) = delete; 00064 atomic_bool& operator=(const atomic_bool&) volatile = delete; 00065 00066 constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { } 00067 00068 bool 00069 operator=(bool __i) noexcept 00070 { return _M_base.operator=(__i); } 00071 00072 bool 00073 operator=(bool __i) volatile noexcept 00074 { return _M_base.operator=(__i); } 00075 00076 operator bool() const noexcept 00077 { return _M_base.load(); } 00078 00079 operator bool() const volatile noexcept 00080 { return _M_base.load(); } 00081 00082 bool 00083 is_lock_free() const noexcept { return _M_base.is_lock_free(); } 00084 00085 bool 00086 is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); } 00087 00088 void 00089 store(bool __i, memory_order __m = memory_order_seq_cst) noexcept 00090 { _M_base.store(__i, __m); } 00091 00092 void 00093 store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept 00094 { _M_base.store(__i, __m); } 00095 00096 bool 00097 load(memory_order __m = memory_order_seq_cst) const noexcept 00098 { return _M_base.load(__m); } 00099 00100 bool 00101 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 00102 { return _M_base.load(__m); } 00103 00104 bool 00105 exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept 00106 { return _M_base.exchange(__i, __m); } 00107 00108 bool 00109 exchange(bool __i, 00110 memory_order __m = memory_order_seq_cst) volatile noexcept 00111 { return _M_base.exchange(__i, __m); } 00112 00113 bool 00114 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, 00115 memory_order __m2) noexcept 00116 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } 00117 00118 bool 00119 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, 00120 memory_order __m2) volatile noexcept 00121 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } 00122 00123 bool 00124 compare_exchange_weak(bool& __i1, bool __i2, 00125 memory_order __m = memory_order_seq_cst) noexcept 00126 { return _M_base.compare_exchange_weak(__i1, __i2, __m); } 00127 00128 bool 00129 compare_exchange_weak(bool& __i1, bool __i2, 00130 memory_order __m = memory_order_seq_cst) volatile noexcept 00131 { return _M_base.compare_exchange_weak(__i1, __i2, __m); } 00132 00133 bool 00134 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, 00135 memory_order __m2) noexcept 00136 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } 00137 00138 bool 00139 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, 00140 memory_order __m2) volatile noexcept 00141 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } 00142 00143 bool 00144 compare_exchange_strong(bool& __i1, bool __i2, 00145 memory_order __m = memory_order_seq_cst) noexcept 00146 { return _M_base.compare_exchange_strong(__i1, __i2, __m); } 00147 00148 bool 00149 compare_exchange_strong(bool& __i1, bool __i2, 00150 memory_order __m = memory_order_seq_cst) volatile noexcept 00151 { return _M_base.compare_exchange_strong(__i1, __i2, __m); } 00152 }; 00153 00154 00155 /** 00156 * @brief Generic atomic type, primary class template. 00157 * 00158 * @tparam _Tp Type to be made atomic, must be trivally copyable. 00159 */ 00160 template<typename _Tp> 00161 struct atomic 00162 { 00163 private: 00164 _Tp _M_i; 00165 00166 public: 00167 atomic() noexcept = default; 00168 ~atomic() noexcept = default; 00169 atomic(const atomic&) = delete; 00170 atomic& operator=(const atomic&) = delete; 00171 atomic& operator=(const atomic&) volatile = delete; 00172 00173 constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } 00174 00175 operator _Tp() const noexcept 00176 { return load(); } 00177 00178 operator _Tp() const volatile noexcept 00179 { return load(); } 00180 00181 _Tp 00182 operator=(_Tp __i) noexcept 00183 { store(__i); return __i; } 00184 00185 _Tp 00186 operator=(_Tp __i) volatile noexcept 00187 { store(__i); return __i; } 00188 00189 bool 00190 is_lock_free() const noexcept 00191 { return __atomic_is_lock_free(sizeof(_M_i), nullptr); } 00192 00193 bool 00194 is_lock_free() const volatile noexcept 00195 { return __atomic_is_lock_free(sizeof(_M_i), nullptr); } 00196 00197 void 00198 store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept 00199 { __atomic_store(&_M_i, &__i, _m); } 00200 00201 void 00202 store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept 00203 { __atomic_store(&_M_i, &__i, _m); } 00204 00205 _Tp 00206 load(memory_order _m = memory_order_seq_cst) const noexcept 00207 { 00208 _Tp tmp; 00209 __atomic_load(&_M_i, &tmp, _m); 00210 return tmp; 00211 } 00212 00213 _Tp 00214 load(memory_order _m = memory_order_seq_cst) const volatile noexcept 00215 { 00216 _Tp tmp; 00217 __atomic_load(&_M_i, &tmp, _m); 00218 return tmp; 00219 } 00220 00221 _Tp 00222 exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept 00223 { 00224 _Tp tmp; 00225 __atomic_exchange(&_M_i, &__i, &tmp, _m); 00226 return tmp; 00227 } 00228 00229 _Tp 00230 exchange(_Tp __i, 00231 memory_order _m = memory_order_seq_cst) volatile noexcept 00232 { 00233 _Tp tmp; 00234 __atomic_exchange(&_M_i, &__i, &tmp, _m); 00235 return tmp; 00236 } 00237 00238 bool 00239 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 00240 memory_order __f) noexcept 00241 { 00242 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 00243 } 00244 00245 bool 00246 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 00247 memory_order __f) volatile noexcept 00248 { 00249 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 00250 } 00251 00252 bool 00253 compare_exchange_weak(_Tp& __e, _Tp __i, 00254 memory_order __m = memory_order_seq_cst) noexcept 00255 { return compare_exchange_weak(__e, __i, __m, 00256 __cmpexch_failure_order(__m)); } 00257 00258 bool 00259 compare_exchange_weak(_Tp& __e, _Tp __i, 00260 memory_order __m = memory_order_seq_cst) volatile noexcept 00261 { return compare_exchange_weak(__e, __i, __m, 00262 __cmpexch_failure_order(__m)); } 00263 00264 bool 00265 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 00266 memory_order __f) noexcept 00267 { 00268 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 00269 } 00270 00271 bool 00272 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 00273 memory_order __f) volatile noexcept 00274 { 00275 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 00276 } 00277 00278 bool 00279 compare_exchange_strong(_Tp& __e, _Tp __i, 00280 memory_order __m = memory_order_seq_cst) noexcept 00281 { return compare_exchange_strong(__e, __i, __m, 00282 __cmpexch_failure_order(__m)); } 00283 00284 bool 00285 compare_exchange_strong(_Tp& __e, _Tp __i, 00286 memory_order __m = memory_order_seq_cst) volatile noexcept 00287 { return compare_exchange_strong(__e, __i, __m, 00288 __cmpexch_failure_order(__m)); } 00289 }; 00290 00291 00292 /// Partial specialization for pointer types. 00293 template<typename _Tp> 00294 struct atomic<_Tp*> 00295 { 00296 typedef _Tp* __pointer_type; 00297 typedef __atomic_base<_Tp*> __base_type; 00298 __base_type _M_b; 00299 00300 atomic() noexcept = default; 00301 ~atomic() noexcept = default; 00302 atomic(const atomic&) = delete; 00303 atomic& operator=(const atomic&) = delete; 00304 atomic& operator=(const atomic&) volatile = delete; 00305 00306 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } 00307 00308 operator __pointer_type() const noexcept 00309 { return __pointer_type(_M_b); } 00310 00311 operator __pointer_type() const volatile noexcept 00312 { return __pointer_type(_M_b); } 00313 00314 __pointer_type 00315 operator=(__pointer_type __p) noexcept 00316 { return _M_b.operator=(__p); } 00317 00318 __pointer_type 00319 operator=(__pointer_type __p) volatile noexcept 00320 { return _M_b.operator=(__p); } 00321 00322 __pointer_type 00323 operator++(int) noexcept 00324 { return _M_b++; } 00325 00326 __pointer_type 00327 operator++(int) volatile noexcept 00328 { return _M_b++; } 00329 00330 __pointer_type 00331 operator--(int) noexcept 00332 { return _M_b--; } 00333 00334 __pointer_type 00335 operator--(int) volatile noexcept 00336 { return _M_b--; } 00337 00338 __pointer_type 00339 operator++() noexcept 00340 { return ++_M_b; } 00341 00342 __pointer_type 00343 operator++() volatile noexcept 00344 { return ++_M_b; } 00345 00346 __pointer_type 00347 operator--() noexcept 00348 { return --_M_b; } 00349 00350 __pointer_type 00351 operator--() volatile noexcept 00352 { return --_M_b; } 00353 00354 __pointer_type 00355 operator+=(ptrdiff_t __d) noexcept 00356 { return _M_b.operator+=(__d); } 00357 00358 __pointer_type 00359 operator+=(ptrdiff_t __d) volatile noexcept 00360 { return _M_b.operator+=(__d); } 00361 00362 __pointer_type 00363 operator-=(ptrdiff_t __d) noexcept 00364 { return _M_b.operator-=(__d); } 00365 00366 __pointer_type 00367 operator-=(ptrdiff_t __d) volatile noexcept 00368 { return _M_b.operator-=(__d); } 00369 00370 bool 00371 is_lock_free() const noexcept 00372 { return _M_b.is_lock_free(); } 00373 00374 bool 00375 is_lock_free() const volatile noexcept 00376 { return _M_b.is_lock_free(); } 00377 00378 void 00379 store(__pointer_type __p, 00380 memory_order __m = memory_order_seq_cst) noexcept 00381 { return _M_b.store(__p, __m); } 00382 00383 void 00384 store(__pointer_type __p, 00385 memory_order __m = memory_order_seq_cst) volatile noexcept 00386 { return _M_b.store(__p, __m); } 00387 00388 __pointer_type 00389 load(memory_order __m = memory_order_seq_cst) const noexcept 00390 { return _M_b.load(__m); } 00391 00392 __pointer_type 00393 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 00394 { return _M_b.load(__m); } 00395 00396 __pointer_type 00397 exchange(__pointer_type __p, 00398 memory_order __m = memory_order_seq_cst) noexcept 00399 { return _M_b.exchange(__p, __m); } 00400 00401 __pointer_type 00402 exchange(__pointer_type __p, 00403 memory_order __m = memory_order_seq_cst) volatile noexcept 00404 { return _M_b.exchange(__p, __m); } 00405 00406 bool 00407 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00408 memory_order __m1, memory_order __m2) noexcept 00409 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00410 00411 bool 00412 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00413 memory_order __m1, 00414 memory_order __m2) volatile noexcept 00415 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00416 00417 bool 00418 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00419 memory_order __m = memory_order_seq_cst) noexcept 00420 { 00421 return compare_exchange_weak(__p1, __p2, __m, 00422 __cmpexch_failure_order(__m)); 00423 } 00424 00425 bool 00426 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00427 memory_order __m = memory_order_seq_cst) volatile noexcept 00428 { 00429 return compare_exchange_weak(__p1, __p2, __m, 00430 __cmpexch_failure_order(__m)); 00431 } 00432 00433 bool 00434 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00435 memory_order __m1, memory_order __m2) noexcept 00436 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00437 00438 bool 00439 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00440 memory_order __m1, 00441 memory_order __m2) volatile noexcept 00442 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00443 00444 bool 00445 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00446 memory_order __m = memory_order_seq_cst) noexcept 00447 { 00448 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00449 __cmpexch_failure_order(__m)); 00450 } 00451 00452 bool 00453 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00454 memory_order __m = memory_order_seq_cst) volatile noexcept 00455 { 00456 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00457 __cmpexch_failure_order(__m)); 00458 } 00459 00460 __pointer_type 00461 fetch_add(ptrdiff_t __d, 00462 memory_order __m = memory_order_seq_cst) noexcept 00463 { return _M_b.fetch_add(__d, __m); } 00464 00465 __pointer_type 00466 fetch_add(ptrdiff_t __d, 00467 memory_order __m = memory_order_seq_cst) volatile noexcept 00468 { return _M_b.fetch_add(__d, __m); } 00469 00470 __pointer_type 00471 fetch_sub(ptrdiff_t __d, 00472 memory_order __m = memory_order_seq_cst) noexcept 00473 { return _M_b.fetch_sub(__d, __m); } 00474 00475 __pointer_type 00476 fetch_sub(ptrdiff_t __d, 00477 memory_order __m = memory_order_seq_cst) volatile noexcept 00478 { return _M_b.fetch_sub(__d, __m); } 00479 }; 00480 00481 00482 /// Explicit specialization for bool. 00483 template<> 00484 struct atomic<bool> : public atomic_bool 00485 { 00486 typedef bool __integral_type; 00487 typedef atomic_bool __base_type; 00488 00489 atomic() noexcept = default; 00490 ~atomic() noexcept = default; 00491 atomic(const atomic&) = delete; 00492 atomic& operator=(const atomic&) = delete; 00493 atomic& operator=(const atomic&) volatile = delete; 00494 00495 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00496 00497 using __base_type::operator __integral_type; 00498 using __base_type::operator=; 00499 }; 00500 00501 /// Explicit specialization for char. 00502 template<> 00503 struct atomic<char> : public atomic_char 00504 { 00505 typedef char __integral_type; 00506 typedef atomic_char __base_type; 00507 00508 atomic() noexcept = default; 00509 ~atomic() noexcept = default; 00510 atomic(const atomic&) = delete; 00511 atomic& operator=(const atomic&) = delete; 00512 atomic& operator=(const atomic&) volatile = delete; 00513 00514 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00515 00516 using __base_type::operator __integral_type; 00517 using __base_type::operator=; 00518 }; 00519 00520 /// Explicit specialization for signed char. 00521 template<> 00522 struct atomic<signed char> : public atomic_schar 00523 { 00524 typedef signed char __integral_type; 00525 typedef atomic_schar __base_type; 00526 00527 atomic() noexcept= default; 00528 ~atomic() noexcept = default; 00529 atomic(const atomic&) = delete; 00530 atomic& operator=(const atomic&) = delete; 00531 atomic& operator=(const atomic&) volatile = delete; 00532 00533 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00534 00535 using __base_type::operator __integral_type; 00536 using __base_type::operator=; 00537 }; 00538 00539 /// Explicit specialization for unsigned char. 00540 template<> 00541 struct atomic<unsigned char> : public atomic_uchar 00542 { 00543 typedef unsigned char __integral_type; 00544 typedef atomic_uchar __base_type; 00545 00546 atomic() noexcept= default; 00547 ~atomic() noexcept = default; 00548 atomic(const atomic&) = delete; 00549 atomic& operator=(const atomic&) = delete; 00550 atomic& operator=(const atomic&) volatile = delete; 00551 00552 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00553 00554 using __base_type::operator __integral_type; 00555 using __base_type::operator=; 00556 }; 00557 00558 /// Explicit specialization for short. 00559 template<> 00560 struct atomic<short> : public atomic_short 00561 { 00562 typedef short __integral_type; 00563 typedef atomic_short __base_type; 00564 00565 atomic() noexcept = default; 00566 ~atomic() noexcept = default; 00567 atomic(const atomic&) = delete; 00568 atomic& operator=(const atomic&) = delete; 00569 atomic& operator=(const atomic&) volatile = delete; 00570 00571 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00572 00573 using __base_type::operator __integral_type; 00574 using __base_type::operator=; 00575 }; 00576 00577 /// Explicit specialization for unsigned short. 00578 template<> 00579 struct atomic<unsigned short> : public atomic_ushort 00580 { 00581 typedef unsigned short __integral_type; 00582 typedef atomic_ushort __base_type; 00583 00584 atomic() noexcept = default; 00585 ~atomic() noexcept = default; 00586 atomic(const atomic&) = delete; 00587 atomic& operator=(const atomic&) = delete; 00588 atomic& operator=(const atomic&) volatile = delete; 00589 00590 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00591 00592 using __base_type::operator __integral_type; 00593 using __base_type::operator=; 00594 }; 00595 00596 /// Explicit specialization for int. 00597 template<> 00598 struct atomic<int> : atomic_int 00599 { 00600 typedef int __integral_type; 00601 typedef atomic_int __base_type; 00602 00603 atomic() noexcept = default; 00604 ~atomic() noexcept = default; 00605 atomic(const atomic&) = delete; 00606 atomic& operator=(const atomic&) = delete; 00607 atomic& operator=(const atomic&) volatile = delete; 00608 00609 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00610 00611 using __base_type::operator __integral_type; 00612 using __base_type::operator=; 00613 }; 00614 00615 /// Explicit specialization for unsigned int. 00616 template<> 00617 struct atomic<unsigned int> : public atomic_uint 00618 { 00619 typedef unsigned int __integral_type; 00620 typedef atomic_uint __base_type; 00621 00622 atomic() noexcept = default; 00623 ~atomic() noexcept = default; 00624 atomic(const atomic&) = delete; 00625 atomic& operator=(const atomic&) = delete; 00626 atomic& operator=(const atomic&) volatile = delete; 00627 00628 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00629 00630 using __base_type::operator __integral_type; 00631 using __base_type::operator=; 00632 }; 00633 00634 /// Explicit specialization for long. 00635 template<> 00636 struct atomic<long> : public atomic_long 00637 { 00638 typedef long __integral_type; 00639 typedef atomic_long __base_type; 00640 00641 atomic() noexcept = default; 00642 ~atomic() noexcept = default; 00643 atomic(const atomic&) = delete; 00644 atomic& operator=(const atomic&) = delete; 00645 atomic& operator=(const atomic&) volatile = delete; 00646 00647 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00648 00649 using __base_type::operator __integral_type; 00650 using __base_type::operator=; 00651 }; 00652 00653 /// Explicit specialization for unsigned long. 00654 template<> 00655 struct atomic<unsigned long> : public atomic_ulong 00656 { 00657 typedef unsigned long __integral_type; 00658 typedef atomic_ulong __base_type; 00659 00660 atomic() noexcept = default; 00661 ~atomic() noexcept = default; 00662 atomic(const atomic&) = delete; 00663 atomic& operator=(const atomic&) = delete; 00664 atomic& operator=(const atomic&) volatile = delete; 00665 00666 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00667 00668 using __base_type::operator __integral_type; 00669 using __base_type::operator=; 00670 }; 00671 00672 /// Explicit specialization for long long. 00673 template<> 00674 struct atomic<long long> : public atomic_llong 00675 { 00676 typedef long long __integral_type; 00677 typedef atomic_llong __base_type; 00678 00679 atomic() noexcept = default; 00680 ~atomic() noexcept = default; 00681 atomic(const atomic&) = delete; 00682 atomic& operator=(const atomic&) = delete; 00683 atomic& operator=(const atomic&) volatile = delete; 00684 00685 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00686 00687 using __base_type::operator __integral_type; 00688 using __base_type::operator=; 00689 }; 00690 00691 /// Explicit specialization for unsigned long long. 00692 template<> 00693 struct atomic<unsigned long long> : public atomic_ullong 00694 { 00695 typedef unsigned long long __integral_type; 00696 typedef atomic_ullong __base_type; 00697 00698 atomic() noexcept = default; 00699 ~atomic() noexcept = default; 00700 atomic(const atomic&) = delete; 00701 atomic& operator=(const atomic&) = delete; 00702 atomic& operator=(const atomic&) volatile = delete; 00703 00704 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00705 00706 using __base_type::operator __integral_type; 00707 using __base_type::operator=; 00708 }; 00709 00710 /// Explicit specialization for wchar_t. 00711 template<> 00712 struct atomic<wchar_t> : public atomic_wchar_t 00713 { 00714 typedef wchar_t __integral_type; 00715 typedef atomic_wchar_t __base_type; 00716 00717 atomic() noexcept = default; 00718 ~atomic() noexcept = default; 00719 atomic(const atomic&) = delete; 00720 atomic& operator=(const atomic&) = delete; 00721 atomic& operator=(const atomic&) volatile = delete; 00722 00723 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00724 00725 using __base_type::operator __integral_type; 00726 using __base_type::operator=; 00727 }; 00728 00729 /// Explicit specialization for char16_t. 00730 template<> 00731 struct atomic<char16_t> : public atomic_char16_t 00732 { 00733 typedef char16_t __integral_type; 00734 typedef atomic_char16_t __base_type; 00735 00736 atomic() noexcept = default; 00737 ~atomic() noexcept = default; 00738 atomic(const atomic&) = delete; 00739 atomic& operator=(const atomic&) = delete; 00740 atomic& operator=(const atomic&) volatile = delete; 00741 00742 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00743 00744 using __base_type::operator __integral_type; 00745 using __base_type::operator=; 00746 }; 00747 00748 /// Explicit specialization for char32_t. 00749 template<> 00750 struct atomic<char32_t> : public atomic_char32_t 00751 { 00752 typedef char32_t __integral_type; 00753 typedef atomic_char32_t __base_type; 00754 00755 atomic() noexcept = default; 00756 ~atomic() noexcept = default; 00757 atomic(const atomic&) = delete; 00758 atomic& operator=(const atomic&) = delete; 00759 atomic& operator=(const atomic&) volatile = delete; 00760 00761 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00762 00763 using __base_type::operator __integral_type; 00764 using __base_type::operator=; 00765 }; 00766 00767 00768 // Function definitions, atomic_flag operations. 00769 inline bool 00770 atomic_flag_test_and_set_explicit(atomic_flag* __a, 00771 memory_order __m) noexcept 00772 { return __a->test_and_set(__m); } 00773 00774 inline bool 00775 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, 00776 memory_order __m) noexcept 00777 { return __a->test_and_set(__m); } 00778 00779 inline void 00780 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept 00781 { __a->clear(__m); } 00782 00783 inline void 00784 atomic_flag_clear_explicit(volatile atomic_flag* __a, 00785 memory_order __m) noexcept 00786 { __a->clear(__m); } 00787 00788 inline bool 00789 atomic_flag_test_and_set(atomic_flag* __a) noexcept 00790 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00791 00792 inline bool 00793 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept 00794 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00795 00796 inline void 00797 atomic_flag_clear(atomic_flag* __a) noexcept 00798 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00799 00800 inline void 00801 atomic_flag_clear(volatile atomic_flag* __a) noexcept 00802 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00803 00804 00805 // Function templates generally applicable to atomic types. 00806 template<typename _ITp> 00807 inline bool 00808 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept 00809 { return __a->is_lock_free(); } 00810 00811 template<typename _ITp> 00812 inline bool 00813 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept 00814 { return __a->is_lock_free(); } 00815 00816 template<typename _ITp> 00817 inline void 00818 atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept; 00819 00820 template<typename _ITp> 00821 inline void 00822 atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept; 00823 00824 template<typename _ITp> 00825 inline void 00826 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, 00827 memory_order __m) noexcept 00828 { __a->store(__i, __m); } 00829 00830 template<typename _ITp> 00831 inline void 00832 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00833 memory_order __m) noexcept 00834 { __a->store(__i, __m); } 00835 00836 template<typename _ITp> 00837 inline _ITp 00838 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept 00839 { return __a->load(__m); } 00840 00841 template<typename _ITp> 00842 inline _ITp 00843 atomic_load_explicit(const volatile atomic<_ITp>* __a, 00844 memory_order __m) noexcept 00845 { return __a->load(__m); } 00846 00847 template<typename _ITp> 00848 inline _ITp 00849 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, 00850 memory_order __m) noexcept 00851 { return __a->exchange(__i, __m); } 00852 00853 template<typename _ITp> 00854 inline _ITp 00855 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00856 memory_order __m) noexcept 00857 { return __a->exchange(__i, __m); } 00858 00859 template<typename _ITp> 00860 inline bool 00861 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, 00862 _ITp* __i1, _ITp __i2, 00863 memory_order __m1, 00864 memory_order __m2) noexcept 00865 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00866 00867 template<typename _ITp> 00868 inline bool 00869 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, 00870 _ITp* __i1, _ITp __i2, 00871 memory_order __m1, 00872 memory_order __m2) noexcept 00873 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00874 00875 template<typename _ITp> 00876 inline bool 00877 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, 00878 _ITp* __i1, _ITp __i2, 00879 memory_order __m1, 00880 memory_order __m2) noexcept 00881 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00882 00883 template<typename _ITp> 00884 inline bool 00885 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, 00886 _ITp* __i1, _ITp __i2, 00887 memory_order __m1, 00888 memory_order __m2) noexcept 00889 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00890 00891 00892 template<typename _ITp> 00893 inline void 00894 atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept 00895 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00896 00897 template<typename _ITp> 00898 inline void 00899 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00900 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00901 00902 template<typename _ITp> 00903 inline _ITp 00904 atomic_load(const atomic<_ITp>* __a) noexcept 00905 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00906 00907 template<typename _ITp> 00908 inline _ITp 00909 atomic_load(const volatile atomic<_ITp>* __a) noexcept 00910 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00911 00912 template<typename _ITp> 00913 inline _ITp 00914 atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept 00915 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00916 00917 template<typename _ITp> 00918 inline _ITp 00919 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00920 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00921 00922 template<typename _ITp> 00923 inline bool 00924 atomic_compare_exchange_weak(atomic<_ITp>* __a, 00925 _ITp* __i1, _ITp __i2) noexcept 00926 { 00927 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00928 memory_order_seq_cst, 00929 memory_order_seq_cst); 00930 } 00931 00932 template<typename _ITp> 00933 inline bool 00934 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, 00935 _ITp* __i1, _ITp __i2) noexcept 00936 { 00937 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00938 memory_order_seq_cst, 00939 memory_order_seq_cst); 00940 } 00941 00942 template<typename _ITp> 00943 inline bool 00944 atomic_compare_exchange_strong(atomic<_ITp>* __a, 00945 _ITp* __i1, _ITp __i2) noexcept 00946 { 00947 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00948 memory_order_seq_cst, 00949 memory_order_seq_cst); 00950 } 00951 00952 template<typename _ITp> 00953 inline bool 00954 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, 00955 _ITp* __i1, _ITp __i2) noexcept 00956 { 00957 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00958 memory_order_seq_cst, 00959 memory_order_seq_cst); 00960 } 00961 00962 // Function templates for atomic_integral operations only, using 00963 // __atomic_base. Template argument should be constricted to 00964 // intergral types as specified in the standard, excluding address 00965 // types. 00966 template<typename _ITp> 00967 inline _ITp 00968 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00969 memory_order __m) noexcept 00970 { return __a->fetch_add(__i, __m); } 00971 00972 template<typename _ITp> 00973 inline _ITp 00974 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00975 memory_order __m) noexcept 00976 { return __a->fetch_add(__i, __m); } 00977 00978 template<typename _ITp> 00979 inline _ITp 00980 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00981 memory_order __m) noexcept 00982 { return __a->fetch_sub(__i, __m); } 00983 00984 template<typename _ITp> 00985 inline _ITp 00986 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00987 memory_order __m) noexcept 00988 { return __a->fetch_sub(__i, __m); } 00989 00990 template<typename _ITp> 00991 inline _ITp 00992 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00993 memory_order __m) noexcept 00994 { return __a->fetch_and(__i, __m); } 00995 00996 template<typename _ITp> 00997 inline _ITp 00998 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00999 memory_order __m) noexcept 01000 { return __a->fetch_and(__i, __m); } 01001 01002 template<typename _ITp> 01003 inline _ITp 01004 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01005 memory_order __m) noexcept 01006 { return __a->fetch_or(__i, __m); } 01007 01008 template<typename _ITp> 01009 inline _ITp 01010 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01011 memory_order __m) noexcept 01012 { return __a->fetch_or(__i, __m); } 01013 01014 template<typename _ITp> 01015 inline _ITp 01016 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01017 memory_order __m) noexcept 01018 { return __a->fetch_xor(__i, __m); } 01019 01020 template<typename _ITp> 01021 inline _ITp 01022 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01023 memory_order __m) noexcept 01024 { return __a->fetch_xor(__i, __m); } 01025 01026 template<typename _ITp> 01027 inline _ITp 01028 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01029 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01030 01031 template<typename _ITp> 01032 inline _ITp 01033 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01034 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01035 01036 template<typename _ITp> 01037 inline _ITp 01038 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01039 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01040 01041 template<typename _ITp> 01042 inline _ITp 01043 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01044 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01045 01046 template<typename _ITp> 01047 inline _ITp 01048 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01049 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01050 01051 template<typename _ITp> 01052 inline _ITp 01053 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01054 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01055 01056 template<typename _ITp> 01057 inline _ITp 01058 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01059 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01060 01061 template<typename _ITp> 01062 inline _ITp 01063 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01064 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01065 01066 template<typename _ITp> 01067 inline _ITp 01068 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01069 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01070 01071 template<typename _ITp> 01072 inline _ITp 01073 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01074 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01075 01076 01077 // Partial specializations for pointers. 01078 template<typename _ITp> 01079 inline _ITp* 01080 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01081 memory_order __m) noexcept 01082 { return __a->fetch_add(__d, __m); } 01083 01084 template<typename _ITp> 01085 inline _ITp* 01086 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, 01087 memory_order __m) noexcept 01088 { return __a->fetch_add(__d, __m); } 01089 01090 template<typename _ITp> 01091 inline _ITp* 01092 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01093 { return __a->fetch_add(__d); } 01094 01095 template<typename _ITp> 01096 inline _ITp* 01097 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01098 { return __a->fetch_add(__d); } 01099 01100 template<typename _ITp> 01101 inline _ITp* 01102 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, 01103 ptrdiff_t __d, memory_order __m) noexcept 01104 { return __a->fetch_sub(__d, __m); } 01105 01106 template<typename _ITp> 01107 inline _ITp* 01108 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01109 memory_order __m) noexcept 01110 { return __a->fetch_sub(__d, __m); } 01111 01112 template<typename _ITp> 01113 inline _ITp* 01114 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01115 { return __a->fetch_sub(__d); } 01116 01117 template<typename _ITp> 01118 inline _ITp* 01119 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01120 { return __a->fetch_sub(__d); } 01121 // @} group atomics 01122 01123 _GLIBCXX_END_NAMESPACE_VERSION 01124 } // namespace 01125 01126 #endif