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