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 { __a->store(__i, memory_order_relaxed); } 00820 00821 template<typename _ITp> 00822 inline void 00823 atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00824 { __a->store(__i, memory_order_relaxed); } 00825 00826 template<typename _ITp> 00827 inline void 00828 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, 00829 memory_order __m) noexcept 00830 { __a->store(__i, __m); } 00831 00832 template<typename _ITp> 00833 inline void 00834 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00835 memory_order __m) noexcept 00836 { __a->store(__i, __m); } 00837 00838 template<typename _ITp> 00839 inline _ITp 00840 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept 00841 { return __a->load(__m); } 00842 00843 template<typename _ITp> 00844 inline _ITp 00845 atomic_load_explicit(const volatile atomic<_ITp>* __a, 00846 memory_order __m) noexcept 00847 { return __a->load(__m); } 00848 00849 template<typename _ITp> 00850 inline _ITp 00851 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, 00852 memory_order __m) noexcept 00853 { return __a->exchange(__i, __m); } 00854 00855 template<typename _ITp> 00856 inline _ITp 00857 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00858 memory_order __m) noexcept 00859 { return __a->exchange(__i, __m); } 00860 00861 template<typename _ITp> 00862 inline bool 00863 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, 00864 _ITp* __i1, _ITp __i2, 00865 memory_order __m1, 00866 memory_order __m2) noexcept 00867 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00868 00869 template<typename _ITp> 00870 inline bool 00871 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, 00872 _ITp* __i1, _ITp __i2, 00873 memory_order __m1, 00874 memory_order __m2) noexcept 00875 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00876 00877 template<typename _ITp> 00878 inline bool 00879 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, 00880 _ITp* __i1, _ITp __i2, 00881 memory_order __m1, 00882 memory_order __m2) noexcept 00883 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00884 00885 template<typename _ITp> 00886 inline bool 00887 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, 00888 _ITp* __i1, _ITp __i2, 00889 memory_order __m1, 00890 memory_order __m2) noexcept 00891 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00892 00893 00894 template<typename _ITp> 00895 inline void 00896 atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept 00897 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00898 00899 template<typename _ITp> 00900 inline void 00901 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00902 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00903 00904 template<typename _ITp> 00905 inline _ITp 00906 atomic_load(const atomic<_ITp>* __a) noexcept 00907 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00908 00909 template<typename _ITp> 00910 inline _ITp 00911 atomic_load(const volatile atomic<_ITp>* __a) noexcept 00912 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00913 00914 template<typename _ITp> 00915 inline _ITp 00916 atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept 00917 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00918 00919 template<typename _ITp> 00920 inline _ITp 00921 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00922 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00923 00924 template<typename _ITp> 00925 inline bool 00926 atomic_compare_exchange_weak(atomic<_ITp>* __a, 00927 _ITp* __i1, _ITp __i2) noexcept 00928 { 00929 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00930 memory_order_seq_cst, 00931 memory_order_seq_cst); 00932 } 00933 00934 template<typename _ITp> 00935 inline bool 00936 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, 00937 _ITp* __i1, _ITp __i2) noexcept 00938 { 00939 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00940 memory_order_seq_cst, 00941 memory_order_seq_cst); 00942 } 00943 00944 template<typename _ITp> 00945 inline bool 00946 atomic_compare_exchange_strong(atomic<_ITp>* __a, 00947 _ITp* __i1, _ITp __i2) noexcept 00948 { 00949 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00950 memory_order_seq_cst, 00951 memory_order_seq_cst); 00952 } 00953 00954 template<typename _ITp> 00955 inline bool 00956 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, 00957 _ITp* __i1, _ITp __i2) noexcept 00958 { 00959 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00960 memory_order_seq_cst, 00961 memory_order_seq_cst); 00962 } 00963 00964 // Function templates for atomic_integral operations only, using 00965 // __atomic_base. Template argument should be constricted to 00966 // intergral types as specified in the standard, excluding address 00967 // types. 00968 template<typename _ITp> 00969 inline _ITp 00970 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00971 memory_order __m) noexcept 00972 { return __a->fetch_add(__i, __m); } 00973 00974 template<typename _ITp> 00975 inline _ITp 00976 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00977 memory_order __m) noexcept 00978 { return __a->fetch_add(__i, __m); } 00979 00980 template<typename _ITp> 00981 inline _ITp 00982 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00983 memory_order __m) noexcept 00984 { return __a->fetch_sub(__i, __m); } 00985 00986 template<typename _ITp> 00987 inline _ITp 00988 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00989 memory_order __m) noexcept 00990 { return __a->fetch_sub(__i, __m); } 00991 00992 template<typename _ITp> 00993 inline _ITp 00994 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00995 memory_order __m) noexcept 00996 { return __a->fetch_and(__i, __m); } 00997 00998 template<typename _ITp> 00999 inline _ITp 01000 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01001 memory_order __m) noexcept 01002 { return __a->fetch_and(__i, __m); } 01003 01004 template<typename _ITp> 01005 inline _ITp 01006 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01007 memory_order __m) noexcept 01008 { return __a->fetch_or(__i, __m); } 01009 01010 template<typename _ITp> 01011 inline _ITp 01012 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01013 memory_order __m) noexcept 01014 { return __a->fetch_or(__i, __m); } 01015 01016 template<typename _ITp> 01017 inline _ITp 01018 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01019 memory_order __m) noexcept 01020 { return __a->fetch_xor(__i, __m); } 01021 01022 template<typename _ITp> 01023 inline _ITp 01024 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01025 memory_order __m) noexcept 01026 { return __a->fetch_xor(__i, __m); } 01027 01028 template<typename _ITp> 01029 inline _ITp 01030 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01031 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01032 01033 template<typename _ITp> 01034 inline _ITp 01035 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01036 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01037 01038 template<typename _ITp> 01039 inline _ITp 01040 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01041 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01042 01043 template<typename _ITp> 01044 inline _ITp 01045 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01046 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01047 01048 template<typename _ITp> 01049 inline _ITp 01050 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01051 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01052 01053 template<typename _ITp> 01054 inline _ITp 01055 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01056 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01057 01058 template<typename _ITp> 01059 inline _ITp 01060 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01061 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01062 01063 template<typename _ITp> 01064 inline _ITp 01065 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01066 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01067 01068 template<typename _ITp> 01069 inline _ITp 01070 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01071 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01072 01073 template<typename _ITp> 01074 inline _ITp 01075 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01076 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01077 01078 01079 // Partial specializations for pointers. 01080 template<typename _ITp> 01081 inline _ITp* 01082 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01083 memory_order __m) noexcept 01084 { return __a->fetch_add(__d, __m); } 01085 01086 template<typename _ITp> 01087 inline _ITp* 01088 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, 01089 memory_order __m) noexcept 01090 { return __a->fetch_add(__d, __m); } 01091 01092 template<typename _ITp> 01093 inline _ITp* 01094 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01095 { return __a->fetch_add(__d); } 01096 01097 template<typename _ITp> 01098 inline _ITp* 01099 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01100 { return __a->fetch_add(__d); } 01101 01102 template<typename _ITp> 01103 inline _ITp* 01104 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, 01105 ptrdiff_t __d, memory_order __m) noexcept 01106 { return __a->fetch_sub(__d, __m); } 01107 01108 template<typename _ITp> 01109 inline _ITp* 01110 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01111 memory_order __m) noexcept 01112 { return __a->fetch_sub(__d, __m); } 01113 01114 template<typename _ITp> 01115 inline _ITp* 01116 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01117 { return __a->fetch_sub(__d); } 01118 01119 template<typename _ITp> 01120 inline _ITp* 01121 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01122 { return __a->fetch_sub(__d); } 01123 // @} group atomics 01124 01125 _GLIBCXX_END_NAMESPACE_VERSION 01126 } // namespace 01127 01128 #endif