libstdc++
|
00001 // -*- C++ -*- header. 00002 00003 // Copyright (C) 2008-2013 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, __m); } 00256 00257 bool 00258 compare_exchange_weak(_Tp& __e, _Tp __i, 00259 memory_order __m = memory_order_seq_cst) volatile noexcept 00260 { return compare_exchange_weak(__e, __i, __m, __m); } 00261 00262 bool 00263 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 00264 memory_order __f) 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, memory_order __s, 00271 memory_order __f) volatile noexcept 00272 { 00273 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 00274 } 00275 00276 bool 00277 compare_exchange_strong(_Tp& __e, _Tp __i, 00278 memory_order __m = memory_order_seq_cst) noexcept 00279 { return compare_exchange_strong(__e, __i, __m, __m); } 00280 00281 bool 00282 compare_exchange_strong(_Tp& __e, _Tp __i, 00283 memory_order __m = memory_order_seq_cst) volatile noexcept 00284 { return compare_exchange_strong(__e, __i, __m, __m); } 00285 }; 00286 00287 00288 /// Partial specialization for pointer types. 00289 template<typename _Tp> 00290 struct atomic<_Tp*> 00291 { 00292 typedef _Tp* __pointer_type; 00293 typedef __atomic_base<_Tp*> __base_type; 00294 __base_type _M_b; 00295 00296 atomic() noexcept = default; 00297 ~atomic() noexcept = default; 00298 atomic(const atomic&) = delete; 00299 atomic& operator=(const atomic&) = delete; 00300 atomic& operator=(const atomic&) volatile = delete; 00301 00302 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } 00303 00304 operator __pointer_type() const noexcept 00305 { return __pointer_type(_M_b); } 00306 00307 operator __pointer_type() const volatile noexcept 00308 { return __pointer_type(_M_b); } 00309 00310 __pointer_type 00311 operator=(__pointer_type __p) noexcept 00312 { return _M_b.operator=(__p); } 00313 00314 __pointer_type 00315 operator=(__pointer_type __p) volatile noexcept 00316 { return _M_b.operator=(__p); } 00317 00318 __pointer_type 00319 operator++(int) noexcept 00320 { return _M_b++; } 00321 00322 __pointer_type 00323 operator++(int) volatile noexcept 00324 { return _M_b++; } 00325 00326 __pointer_type 00327 operator--(int) noexcept 00328 { return _M_b--; } 00329 00330 __pointer_type 00331 operator--(int) volatile noexcept 00332 { return _M_b--; } 00333 00334 __pointer_type 00335 operator++() noexcept 00336 { return ++_M_b; } 00337 00338 __pointer_type 00339 operator++() volatile noexcept 00340 { return ++_M_b; } 00341 00342 __pointer_type 00343 operator--() noexcept 00344 { return --_M_b; } 00345 00346 __pointer_type 00347 operator--() volatile noexcept 00348 { return --_M_b; } 00349 00350 __pointer_type 00351 operator+=(ptrdiff_t __d) noexcept 00352 { return _M_b.operator+=(__d); } 00353 00354 __pointer_type 00355 operator+=(ptrdiff_t __d) volatile noexcept 00356 { return _M_b.operator+=(__d); } 00357 00358 __pointer_type 00359 operator-=(ptrdiff_t __d) noexcept 00360 { return _M_b.operator-=(__d); } 00361 00362 __pointer_type 00363 operator-=(ptrdiff_t __d) volatile noexcept 00364 { return _M_b.operator-=(__d); } 00365 00366 bool 00367 is_lock_free() const noexcept 00368 { return _M_b.is_lock_free(); } 00369 00370 bool 00371 is_lock_free() const volatile noexcept 00372 { return _M_b.is_lock_free(); } 00373 00374 void 00375 store(__pointer_type __p, 00376 memory_order __m = memory_order_seq_cst) noexcept 00377 { return _M_b.store(__p, __m); } 00378 00379 void 00380 store(__pointer_type __p, 00381 memory_order __m = memory_order_seq_cst) volatile noexcept 00382 { return _M_b.store(__p, __m); } 00383 00384 __pointer_type 00385 load(memory_order __m = memory_order_seq_cst) const noexcept 00386 { return _M_b.load(__m); } 00387 00388 __pointer_type 00389 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 00390 { return _M_b.load(__m); } 00391 00392 __pointer_type 00393 exchange(__pointer_type __p, 00394 memory_order __m = memory_order_seq_cst) noexcept 00395 { return _M_b.exchange(__p, __m); } 00396 00397 __pointer_type 00398 exchange(__pointer_type __p, 00399 memory_order __m = memory_order_seq_cst) volatile noexcept 00400 { return _M_b.exchange(__p, __m); } 00401 00402 bool 00403 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00404 memory_order __m1, memory_order __m2) noexcept 00405 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00406 00407 bool 00408 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00409 memory_order __m1, 00410 memory_order __m2) volatile noexcept 00411 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00412 00413 bool 00414 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00415 memory_order __m = memory_order_seq_cst) noexcept 00416 { 00417 return compare_exchange_weak(__p1, __p2, __m, 00418 __cmpexch_failure_order(__m)); 00419 } 00420 00421 bool 00422 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00423 memory_order __m = memory_order_seq_cst) volatile noexcept 00424 { 00425 return compare_exchange_weak(__p1, __p2, __m, 00426 __cmpexch_failure_order(__m)); 00427 } 00428 00429 bool 00430 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00431 memory_order __m1, memory_order __m2) noexcept 00432 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00433 00434 bool 00435 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00436 memory_order __m1, 00437 memory_order __m2) volatile noexcept 00438 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00439 00440 bool 00441 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00442 memory_order __m = memory_order_seq_cst) noexcept 00443 { 00444 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00445 __cmpexch_failure_order(__m)); 00446 } 00447 00448 bool 00449 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00450 memory_order __m = memory_order_seq_cst) volatile noexcept 00451 { 00452 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00453 __cmpexch_failure_order(__m)); 00454 } 00455 00456 __pointer_type 00457 fetch_add(ptrdiff_t __d, 00458 memory_order __m = memory_order_seq_cst) noexcept 00459 { return _M_b.fetch_add(__d, __m); } 00460 00461 __pointer_type 00462 fetch_add(ptrdiff_t __d, 00463 memory_order __m = memory_order_seq_cst) volatile noexcept 00464 { return _M_b.fetch_add(__d, __m); } 00465 00466 __pointer_type 00467 fetch_sub(ptrdiff_t __d, 00468 memory_order __m = memory_order_seq_cst) noexcept 00469 { return _M_b.fetch_sub(__d, __m); } 00470 00471 __pointer_type 00472 fetch_sub(ptrdiff_t __d, 00473 memory_order __m = memory_order_seq_cst) volatile noexcept 00474 { return _M_b.fetch_sub(__d, __m); } 00475 }; 00476 00477 00478 /// Explicit specialization for bool. 00479 template<> 00480 struct atomic<bool> : public atomic_bool 00481 { 00482 typedef bool __integral_type; 00483 typedef atomic_bool __base_type; 00484 00485 atomic() noexcept = default; 00486 ~atomic() noexcept = default; 00487 atomic(const atomic&) = delete; 00488 atomic& operator=(const atomic&) = delete; 00489 atomic& operator=(const atomic&) volatile = delete; 00490 00491 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00492 00493 using __base_type::operator __integral_type; 00494 using __base_type::operator=; 00495 }; 00496 00497 /// Explicit specialization for char. 00498 template<> 00499 struct atomic<char> : public atomic_char 00500 { 00501 typedef char __integral_type; 00502 typedef atomic_char __base_type; 00503 00504 atomic() noexcept = default; 00505 ~atomic() noexcept = default; 00506 atomic(const atomic&) = delete; 00507 atomic& operator=(const atomic&) = delete; 00508 atomic& operator=(const atomic&) volatile = delete; 00509 00510 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00511 00512 using __base_type::operator __integral_type; 00513 using __base_type::operator=; 00514 }; 00515 00516 /// Explicit specialization for signed char. 00517 template<> 00518 struct atomic<signed char> : public atomic_schar 00519 { 00520 typedef signed char __integral_type; 00521 typedef atomic_schar __base_type; 00522 00523 atomic() noexcept= default; 00524 ~atomic() noexcept = default; 00525 atomic(const atomic&) = delete; 00526 atomic& operator=(const atomic&) = delete; 00527 atomic& operator=(const atomic&) volatile = delete; 00528 00529 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00530 00531 using __base_type::operator __integral_type; 00532 using __base_type::operator=; 00533 }; 00534 00535 /// Explicit specialization for unsigned char. 00536 template<> 00537 struct atomic<unsigned char> : public atomic_uchar 00538 { 00539 typedef unsigned char __integral_type; 00540 typedef atomic_uchar __base_type; 00541 00542 atomic() noexcept= default; 00543 ~atomic() noexcept = default; 00544 atomic(const atomic&) = delete; 00545 atomic& operator=(const atomic&) = delete; 00546 atomic& operator=(const atomic&) volatile = delete; 00547 00548 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00549 00550 using __base_type::operator __integral_type; 00551 using __base_type::operator=; 00552 }; 00553 00554 /// Explicit specialization for short. 00555 template<> 00556 struct atomic<short> : public atomic_short 00557 { 00558 typedef short __integral_type; 00559 typedef atomic_short __base_type; 00560 00561 atomic() noexcept = default; 00562 ~atomic() noexcept = default; 00563 atomic(const atomic&) = delete; 00564 atomic& operator=(const atomic&) = delete; 00565 atomic& operator=(const atomic&) volatile = delete; 00566 00567 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00568 00569 using __base_type::operator __integral_type; 00570 using __base_type::operator=; 00571 }; 00572 00573 /// Explicit specialization for unsigned short. 00574 template<> 00575 struct atomic<unsigned short> : public atomic_ushort 00576 { 00577 typedef unsigned short __integral_type; 00578 typedef atomic_ushort __base_type; 00579 00580 atomic() noexcept = default; 00581 ~atomic() noexcept = default; 00582 atomic(const atomic&) = delete; 00583 atomic& operator=(const atomic&) = delete; 00584 atomic& operator=(const atomic&) volatile = delete; 00585 00586 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00587 00588 using __base_type::operator __integral_type; 00589 using __base_type::operator=; 00590 }; 00591 00592 /// Explicit specialization for int. 00593 template<> 00594 struct atomic<int> : atomic_int 00595 { 00596 typedef int __integral_type; 00597 typedef atomic_int __base_type; 00598 00599 atomic() noexcept = default; 00600 ~atomic() noexcept = default; 00601 atomic(const atomic&) = delete; 00602 atomic& operator=(const atomic&) = delete; 00603 atomic& operator=(const atomic&) volatile = delete; 00604 00605 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00606 00607 using __base_type::operator __integral_type; 00608 using __base_type::operator=; 00609 }; 00610 00611 /// Explicit specialization for unsigned int. 00612 template<> 00613 struct atomic<unsigned int> : public atomic_uint 00614 { 00615 typedef unsigned int __integral_type; 00616 typedef atomic_uint __base_type; 00617 00618 atomic() noexcept = default; 00619 ~atomic() noexcept = default; 00620 atomic(const atomic&) = delete; 00621 atomic& operator=(const atomic&) = delete; 00622 atomic& operator=(const atomic&) volatile = delete; 00623 00624 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00625 00626 using __base_type::operator __integral_type; 00627 using __base_type::operator=; 00628 }; 00629 00630 /// Explicit specialization for long. 00631 template<> 00632 struct atomic<long> : public atomic_long 00633 { 00634 typedef long __integral_type; 00635 typedef atomic_long __base_type; 00636 00637 atomic() noexcept = default; 00638 ~atomic() noexcept = default; 00639 atomic(const atomic&) = delete; 00640 atomic& operator=(const atomic&) = delete; 00641 atomic& operator=(const atomic&) volatile = delete; 00642 00643 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00644 00645 using __base_type::operator __integral_type; 00646 using __base_type::operator=; 00647 }; 00648 00649 /// Explicit specialization for unsigned long. 00650 template<> 00651 struct atomic<unsigned long> : public atomic_ulong 00652 { 00653 typedef unsigned long __integral_type; 00654 typedef atomic_ulong __base_type; 00655 00656 atomic() noexcept = default; 00657 ~atomic() noexcept = default; 00658 atomic(const atomic&) = delete; 00659 atomic& operator=(const atomic&) = delete; 00660 atomic& operator=(const atomic&) volatile = delete; 00661 00662 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00663 00664 using __base_type::operator __integral_type; 00665 using __base_type::operator=; 00666 }; 00667 00668 /// Explicit specialization for long long. 00669 template<> 00670 struct atomic<long long> : public atomic_llong 00671 { 00672 typedef long long __integral_type; 00673 typedef atomic_llong __base_type; 00674 00675 atomic() noexcept = default; 00676 ~atomic() noexcept = default; 00677 atomic(const atomic&) = delete; 00678 atomic& operator=(const atomic&) = delete; 00679 atomic& operator=(const atomic&) volatile = delete; 00680 00681 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00682 00683 using __base_type::operator __integral_type; 00684 using __base_type::operator=; 00685 }; 00686 00687 /// Explicit specialization for unsigned long long. 00688 template<> 00689 struct atomic<unsigned long long> : public atomic_ullong 00690 { 00691 typedef unsigned long long __integral_type; 00692 typedef atomic_ullong __base_type; 00693 00694 atomic() noexcept = default; 00695 ~atomic() noexcept = default; 00696 atomic(const atomic&) = delete; 00697 atomic& operator=(const atomic&) = delete; 00698 atomic& operator=(const atomic&) volatile = delete; 00699 00700 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00701 00702 using __base_type::operator __integral_type; 00703 using __base_type::operator=; 00704 }; 00705 00706 /// Explicit specialization for wchar_t. 00707 template<> 00708 struct atomic<wchar_t> : public atomic_wchar_t 00709 { 00710 typedef wchar_t __integral_type; 00711 typedef atomic_wchar_t __base_type; 00712 00713 atomic() noexcept = default; 00714 ~atomic() noexcept = default; 00715 atomic(const atomic&) = delete; 00716 atomic& operator=(const atomic&) = delete; 00717 atomic& operator=(const atomic&) volatile = delete; 00718 00719 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00720 00721 using __base_type::operator __integral_type; 00722 using __base_type::operator=; 00723 }; 00724 00725 /// Explicit specialization for char16_t. 00726 template<> 00727 struct atomic<char16_t> : public atomic_char16_t 00728 { 00729 typedef char16_t __integral_type; 00730 typedef atomic_char16_t __base_type; 00731 00732 atomic() noexcept = default; 00733 ~atomic() noexcept = default; 00734 atomic(const atomic&) = delete; 00735 atomic& operator=(const atomic&) = delete; 00736 atomic& operator=(const atomic&) volatile = delete; 00737 00738 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00739 00740 using __base_type::operator __integral_type; 00741 using __base_type::operator=; 00742 }; 00743 00744 /// Explicit specialization for char32_t. 00745 template<> 00746 struct atomic<char32_t> : public atomic_char32_t 00747 { 00748 typedef char32_t __integral_type; 00749 typedef atomic_char32_t __base_type; 00750 00751 atomic() noexcept = default; 00752 ~atomic() noexcept = default; 00753 atomic(const atomic&) = delete; 00754 atomic& operator=(const atomic&) = delete; 00755 atomic& operator=(const atomic&) volatile = delete; 00756 00757 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00758 00759 using __base_type::operator __integral_type; 00760 using __base_type::operator=; 00761 }; 00762 00763 00764 // Function definitions, atomic_flag operations. 00765 inline bool 00766 atomic_flag_test_and_set_explicit(atomic_flag* __a, 00767 memory_order __m) noexcept 00768 { return __a->test_and_set(__m); } 00769 00770 inline bool 00771 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, 00772 memory_order __m) noexcept 00773 { return __a->test_and_set(__m); } 00774 00775 inline void 00776 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept 00777 { __a->clear(__m); } 00778 00779 inline void 00780 atomic_flag_clear_explicit(volatile atomic_flag* __a, 00781 memory_order __m) noexcept 00782 { __a->clear(__m); } 00783 00784 inline bool 00785 atomic_flag_test_and_set(atomic_flag* __a) noexcept 00786 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00787 00788 inline bool 00789 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept 00790 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00791 00792 inline void 00793 atomic_flag_clear(atomic_flag* __a) noexcept 00794 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00795 00796 inline void 00797 atomic_flag_clear(volatile atomic_flag* __a) noexcept 00798 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00799 00800 00801 // Function templates generally applicable to atomic types. 00802 template<typename _ITp> 00803 inline bool 00804 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept 00805 { return __a->is_lock_free(); } 00806 00807 template<typename _ITp> 00808 inline bool 00809 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept 00810 { return __a->is_lock_free(); } 00811 00812 template<typename _ITp> 00813 inline void 00814 atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept; 00815 00816 template<typename _ITp> 00817 inline void 00818 atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept; 00819 00820 template<typename _ITp> 00821 inline void 00822 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, 00823 memory_order __m) noexcept 00824 { __a->store(__i, __m); } 00825 00826 template<typename _ITp> 00827 inline void 00828 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00829 memory_order __m) noexcept 00830 { __a->store(__i, __m); } 00831 00832 template<typename _ITp> 00833 inline _ITp 00834 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept 00835 { return __a->load(__m); } 00836 00837 template<typename _ITp> 00838 inline _ITp 00839 atomic_load_explicit(const volatile atomic<_ITp>* __a, 00840 memory_order __m) noexcept 00841 { return __a->load(__m); } 00842 00843 template<typename _ITp> 00844 inline _ITp 00845 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, 00846 memory_order __m) noexcept 00847 { return __a->exchange(__i, __m); } 00848 00849 template<typename _ITp> 00850 inline _ITp 00851 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00852 memory_order __m) noexcept 00853 { return __a->exchange(__i, __m); } 00854 00855 template<typename _ITp> 00856 inline bool 00857 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, 00858 _ITp* __i1, _ITp __i2, 00859 memory_order __m1, 00860 memory_order __m2) noexcept 00861 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00862 00863 template<typename _ITp> 00864 inline bool 00865 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, 00866 _ITp* __i1, _ITp __i2, 00867 memory_order __m1, 00868 memory_order __m2) noexcept 00869 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00870 00871 template<typename _ITp> 00872 inline bool 00873 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, 00874 _ITp* __i1, _ITp __i2, 00875 memory_order __m1, 00876 memory_order __m2) noexcept 00877 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00878 00879 template<typename _ITp> 00880 inline bool 00881 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, 00882 _ITp* __i1, _ITp __i2, 00883 memory_order __m1, 00884 memory_order __m2) noexcept 00885 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00886 00887 00888 template<typename _ITp> 00889 inline void 00890 atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept 00891 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00892 00893 template<typename _ITp> 00894 inline void 00895 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00896 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00897 00898 template<typename _ITp> 00899 inline _ITp 00900 atomic_load(const atomic<_ITp>* __a) noexcept 00901 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00902 00903 template<typename _ITp> 00904 inline _ITp 00905 atomic_load(const volatile atomic<_ITp>* __a) noexcept 00906 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00907 00908 template<typename _ITp> 00909 inline _ITp 00910 atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept 00911 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00912 00913 template<typename _ITp> 00914 inline _ITp 00915 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00916 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00917 00918 template<typename _ITp> 00919 inline bool 00920 atomic_compare_exchange_weak(atomic<_ITp>* __a, 00921 _ITp* __i1, _ITp __i2) noexcept 00922 { 00923 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00924 memory_order_seq_cst, 00925 memory_order_seq_cst); 00926 } 00927 00928 template<typename _ITp> 00929 inline bool 00930 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, 00931 _ITp* __i1, _ITp __i2) noexcept 00932 { 00933 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00934 memory_order_seq_cst, 00935 memory_order_seq_cst); 00936 } 00937 00938 template<typename _ITp> 00939 inline bool 00940 atomic_compare_exchange_strong(atomic<_ITp>* __a, 00941 _ITp* __i1, _ITp __i2) noexcept 00942 { 00943 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00944 memory_order_seq_cst, 00945 memory_order_seq_cst); 00946 } 00947 00948 template<typename _ITp> 00949 inline bool 00950 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, 00951 _ITp* __i1, _ITp __i2) noexcept 00952 { 00953 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00954 memory_order_seq_cst, 00955 memory_order_seq_cst); 00956 } 00957 00958 // Function templates for atomic_integral operations only, using 00959 // __atomic_base. Template argument should be constricted to 00960 // intergral types as specified in the standard, excluding address 00961 // types. 00962 template<typename _ITp> 00963 inline _ITp 00964 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00965 memory_order __m) noexcept 00966 { return __a->fetch_add(__i, __m); } 00967 00968 template<typename _ITp> 00969 inline _ITp 00970 atomic_fetch_add_explicit(volatile __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_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00977 memory_order __m) noexcept 00978 { return __a->fetch_sub(__i, __m); } 00979 00980 template<typename _ITp> 00981 inline _ITp 00982 atomic_fetch_sub_explicit(volatile __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_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00989 memory_order __m) noexcept 00990 { return __a->fetch_and(__i, __m); } 00991 00992 template<typename _ITp> 00993 inline _ITp 00994 atomic_fetch_and_explicit(volatile __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_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01001 memory_order __m) noexcept 01002 { return __a->fetch_or(__i, __m); } 01003 01004 template<typename _ITp> 01005 inline _ITp 01006 atomic_fetch_or_explicit(volatile __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_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01013 memory_order __m) noexcept 01014 { return __a->fetch_xor(__i, __m); } 01015 01016 template<typename _ITp> 01017 inline _ITp 01018 atomic_fetch_xor_explicit(volatile __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_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01025 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01026 01027 template<typename _ITp> 01028 inline _ITp 01029 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01030 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01031 01032 template<typename _ITp> 01033 inline _ITp 01034 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01035 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01036 01037 template<typename _ITp> 01038 inline _ITp 01039 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01040 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01041 01042 template<typename _ITp> 01043 inline _ITp 01044 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01045 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01046 01047 template<typename _ITp> 01048 inline _ITp 01049 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01050 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01051 01052 template<typename _ITp> 01053 inline _ITp 01054 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01055 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01056 01057 template<typename _ITp> 01058 inline _ITp 01059 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01060 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01061 01062 template<typename _ITp> 01063 inline _ITp 01064 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01065 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01066 01067 template<typename _ITp> 01068 inline _ITp 01069 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01070 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01071 01072 01073 // Partial specializations for pointers. 01074 template<typename _ITp> 01075 inline _ITp* 01076 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01077 memory_order __m) noexcept 01078 { return __a->fetch_add(__d, __m); } 01079 01080 template<typename _ITp> 01081 inline _ITp* 01082 atomic_fetch_add_explicit(volatile 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(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01089 { return __a->fetch_add(__d); } 01090 01091 template<typename _ITp> 01092 inline _ITp* 01093 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01094 { return __a->fetch_add(__d); } 01095 01096 template<typename _ITp> 01097 inline _ITp* 01098 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, 01099 ptrdiff_t __d, memory_order __m) noexcept 01100 { return __a->fetch_sub(__d, __m); } 01101 01102 template<typename _ITp> 01103 inline _ITp* 01104 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01105 memory_order __m) noexcept 01106 { return __a->fetch_sub(__d, __m); } 01107 01108 template<typename _ITp> 01109 inline _ITp* 01110 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01111 { return __a->fetch_sub(__d); } 01112 01113 template<typename _ITp> 01114 inline _ITp* 01115 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01116 { return __a->fetch_sub(__d); } 01117 // @} group atomics 01118 01119 _GLIBCXX_END_NAMESPACE_VERSION 01120 } // namespace 01121 01122 #endif