root/core/atomic_counter_impl.hpp

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. locker
  2. locker
  3. locker
  4. locker
  5. locker
  6. swap
  7. swap
  8. get
  9. apply
  10. apply
  11. apply
  12. compare_exchange_strong
  13. compare_exchange_strong
  14. assign
  15. swap
  16. swap
  17. get
  18. compare_exchange_strong
  19. compare_exchange_strong
  20. apply
  21. apply
  22. apply
  23. assign

   1 /******************************************************************************
   2 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/core/atomic_counter_impl.hpp 2055 2017-05-13 19:35:47Z jmmcg $
   3 **
   4 ** Copyright © 2007 by J.M.McGuiness, coder@hussar.me.uk
   5 **
   6 ** This library is free software; you can redistribute it and/or
   7 ** modify it under the terms of the GNU Lesser General Public
   8 ** License as published by the Free Software Foundation; either
   9 ** version 2.1 of the License, or (at your option) any later version.
  10 **
  11 ** This library is distributed in the hope that it will be useful,
  12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 ** Lesser General Public License for more details.
  15 **
  16 ** You should have received a copy of the GNU Lesser General Public
  17 ** License along with this library; if not, write to the Free Software
  18 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 */
  20 
  21 namespace jmmcg { namespace ppd {
  22 
  23 template<class V, class LkT> inline constexpr
  24 atomic_ctr_gen<V, LkT>::atomic_ctr_gen() noexcept(noexcept(value_type()) && noexcept(atomic_t()))
  25 : count(), locker() {
  26 }
  27 
  28 template<class V, class LkT> inline constexpr
  29 atomic_ctr_gen<V, LkT>::atomic_ctr_gen(const value_type v) noexcept(noexcept(value_type(std::declval<value_type>())) && noexcept(atomic_t()))
  30 : count(v), locker() {
  31 }
  32 
  33 template<class V, class LkT> inline constexpr
  34 atomic_ctr_gen<V, LkT>::atomic_ctr_gen(const atomic_ctr_gen &a) noexcept(false)
  35 : count(a.count), locker() {
  36 }
  37 
  38 template<class V, class LkT>
  39 template<class V1>
  40 inline constexpr
  41 atomic_ctr_gen<V, LkT>::atomic_ctr_gen(const atomic_ctr_gen<V1, LkT> &a) noexcept(false)
  42 : count(dynamic_cast<value_type>(a.count)), locker() {
  43         static_assert(std::is_base_of<typename std::remove_pointer<value_type>::type, typename std::remove_pointer<V1>::type>::value, "The two types must have the same base.");
  44 }
  45 
  46 template<class V, class LkT>
  47 template<class V1>
  48 inline
  49 atomic_ctr_gen<V, LkT>::atomic_ctr_gen(atomic_ctr_gen<V1, LkT> &&a) noexcept(true)
  50 : count(), locker() {
  51         static_assert(std::is_base_of<typename std::remove_pointer<value_type>::type, typename std::remove_pointer<V1>::type>::value, "The two types must have the same base.");
  52         swap(a);
  53 }
  54 
  55 template<class V, class LkT> inline
  56 atomic_ctr_gen<V, LkT>::~atomic_ctr_gen() noexcept(true) {
  57 }
  58 
  59 template<class V, class LkT> inline void
  60 atomic_ctr_gen<V, LkT>::swap(atomic_ctr_gen &a) noexcept(true) {
  61         const typename atomic_t::write_lock_type lock_this(locker, atomic_t::infinite_timeout());
  62         const typename atomic_t::write_lock_type lock_that(a.locker, atomic_t::infinite_timeout());
  63         std::swap(count, a.count);
  64 }
  65 
  66 template<class V, class LkT>
  67 template<class V1, class V2>
  68 inline typename std::enable_if<std::is_pointer<V2>::value, void>::type
  69 atomic_ctr_gen<V, LkT>::swap(atomic_ctr_gen<V1, LkT> &a) noexcept(true) {
  70 // This is too brutal: it doesn't detect common bases....                       static_assert(std::is_base_of<typename std::remove_pointer<value_type>::type, typename std::remove_pointer<V1>::type>::value, "The two types must have the same base.");
  71         const typename atomic_t::write_lock_type lock_this(locker, atomic_t::infinite_timeout());
  72         const typename atomic_t::write_lock_type lock_that(a.locker, atomic_t::infinite_timeout());
  73         std::swap(count, a.count);
  74 }
  75 
  76 template<class V, class LkT> inline void
  77 atomic_ctr_gen<V, LkT>::operator=(const atomic_ctr_gen &a) noexcept(true) {
  78         const typename atomic_t::write_lock_type lock_this(locker, atomic_t::infinite_timeout());
  79         const typename atomic_t::read_lock_type lock_that(a.locker, atomic_t::infinite_timeout());
  80         count=a.count;
  81 }
  82 
  83 template<class V, class LkT>
  84 template<class V1, class V2>
  85 inline typename std::enable_if<std::is_pointer<V2>::value, void>::type
  86 atomic_ctr_gen<V, LkT>::operator=(const atomic_ctr_gen<V1, LkT> &a) noexcept(true) {
  87         static_assert(std::is_base_of<typename std::remove_pointer<value_type>::type, typename std::remove_pointer<V1>::type>::value, "The two types must have the same base.");
  88         const typename atomic_t::write_lock_type lock_this(locker, atomic_t::infinite_timeout());
  89         const typename atomic_t::read_lock_type lock_that(a.locker, atomic_t::infinite_timeout());
  90         count=dynamic_cast<value_type>(a.get());
  91 }
  92 
  93 template<class V, class LkT> inline void
  94 atomic_ctr_gen<V, LkT>::operator=(const value_type &v) noexcept(true) {
  95         const typename atomic_t::write_lock_type lock_this(locker, atomic_t::infinite_timeout());
  96         count=v;
  97 }
  98 
  99 template<class V, class LkT> inline constexpr typename atomic_ctr_gen<V, LkT>::value_type const &
 100 atomic_ctr_gen<V, LkT>::get() const noexcept(true) {
 101         return count;
 102 }
 103 
 104 template<class V, class LkT> inline constexpr bool
 105 atomic_ctr_gen<V, LkT>::operator==(const value_type v) const noexcept(true) {
 106         return count==v;
 107 }
 108 
 109 template<class V, class LkT> inline constexpr bool
 110 atomic_ctr_gen<V, LkT>::operator==(const atomic_ctr_gen &a) const noexcept(true) {
 111         return count==a.count;
 112 }
 113 
 114 template<class V, class LkT> inline constexpr bool
 115 atomic_ctr_gen<V, LkT>::operator!=(const value_type v) const noexcept(true) {
 116         return !operator==(v);
 117 }
 118 
 119 template<class V, class LkT> inline constexpr bool
 120 atomic_ctr_gen<V, LkT>::operator!=(const atomic_ctr_gen &a) const noexcept(true) {
 121         return !operator==(a);
 122 }
 123 
 124 template<class V, class LkT> inline constexpr bool
 125 atomic_ctr_gen<V, LkT>::operator!() const noexcept(true) {
 126         return operator==(0);
 127 }
 128 
 129 template<class V, class LkT> inline constexpr bool
 130 atomic_ctr_gen<V, LkT>::operator<(const value_type v) const noexcept(true) {
 131         return count<v;
 132 }
 133 
 134 template<class V, class LkT> inline constexpr bool
 135 atomic_ctr_gen<V, LkT>::operator<(const atomic_ctr_gen &a) const noexcept(true) {
 136         return count<a.count;
 137 }
 138 
 139 template<class V, class LkT> inline constexpr bool
 140 atomic_ctr_gen<V, LkT>::operator<(const base_t &a) const noexcept(true) {
 141         return *this<dynamic_cast<atomic_ctr_gen const &>(a);
 142 }
 143 
 144 template<class V, class LkT> inline constexpr bool
 145 atomic_ctr_gen<V, LkT>::operator>(const value_type v) const noexcept(true) {
 146         return count>v;
 147 }
 148 
 149 template<class V, class LkT> inline constexpr bool
 150 atomic_ctr_gen<V, LkT>::operator>(const atomic_ctr_gen &a) const noexcept(true) {
 151         return count>a.count;
 152 }
 153 
 154 template<class V, class LkT> inline constexpr bool
 155 atomic_ctr_gen<V, LkT>::operator>(const base_t &a) const noexcept(true) {
 156         return *this>dynamic_cast<atomic_ctr_gen const &>(a);
 157 }
 158 
 159 template<class V, class LkT> inline constexpr bool
 160 atomic_ctr_gen<V, LkT>::operator<=(const value_type v) const noexcept(true) {
 161         return count<=v;
 162 }
 163 
 164 template<class V, class LkT> inline constexpr bool
 165 atomic_ctr_gen<V, LkT>::operator<=(const atomic_ctr_gen &a) const noexcept(true) {
 166         return count<=a.count;
 167 }
 168 
 169 template<class V, class LkT> inline constexpr bool
 170 atomic_ctr_gen<V, LkT>::operator>=(const atomic_ctr_gen &a) const noexcept(true) {
 171         return count>=a.count;
 172 }
 173 
 174 template<class V, class LkT> inline constexpr bool
 175 atomic_ctr_gen<V, LkT>::operator>=(const value_type v) const noexcept(true) {
 176         return count>=v;
 177 }
 178 
 179 template<class V, class LkT> inline typename atomic_ctr_gen<V, LkT>::value_type
 180 atomic_ctr_gen<V, LkT>::operator++() noexcept(true) {
 181         const typename atomic_t::write_lock_type lock(locker, atomic_t::infinite_timeout());
 182         const value_type ret=++count;
 183         return ret;
 184 }
 185 
 186 template<class V, class LkT> inline typename atomic_ctr_gen<V, LkT>::value_type
 187 atomic_ctr_gen<V, LkT>::operator++(int) noexcept(true) {
 188         const value_type orig(count);
 189         ++*this;
 190         return orig;
 191 }
 192 
 193 template<class V, class LkT> inline typename atomic_ctr_gen<V, LkT>::value_type
 194 atomic_ctr_gen<V, LkT>::operator--() noexcept(true) {
 195         const typename atomic_t::write_lock_type lock(locker, atomic_t::infinite_timeout());
 196         const value_type ret=--count;
 197         return ret;
 198 }
 199 
 200 template<class V, class LkT> inline typename atomic_ctr_gen<V, LkT>::value_type
 201 atomic_ctr_gen<V, LkT>::operator--(int) noexcept(true) {
 202         const value_type orig(count);
 203         --*this;
 204         return orig;
 205 }
 206 
 207 template<class V, class LkT> inline typename atomic_ctr_gen<V, LkT>::value_type
 208 atomic_ctr_gen<V, LkT>::operator+=(const value_type v) noexcept(true) {
 209         const typename atomic_t::write_lock_type lock(locker, atomic_t::infinite_timeout());
 210         count+=v;
 211         return count;
 212 }
 213 
 214 template<class V, class LkT> inline typename atomic_ctr_gen<V, LkT>::value_type
 215 atomic_ctr_gen<V, LkT>::operator+=(const atomic_ctr_gen &a) noexcept(true) {
 216         const typename atomic_t::write_lock_type lock_this(locker, atomic_t::infinite_timeout());
 217         const typename atomic_t::read_lock_type lock_that(a.locker, atomic_t::infinite_timeout());
 218         count+=a.count;
 219         return count;
 220 }
 221 
 222 template<class V, class LkT> inline typename atomic_ctr_gen<V, LkT>::value_type
 223 atomic_ctr_gen<V, LkT>::operator-=(const value_type v) noexcept(true) {
 224         const typename atomic_t::write_lock_type lock(locker,atomic_t::infinite_timeout());
 225         count-=v;
 226         return count;
 227 }
 228 
 229 template<class V, class LkT> inline typename atomic_ctr_gen<V, LkT>::value_type
 230 atomic_ctr_gen<V, LkT>::operator-=(const atomic_ctr_gen &a) noexcept(true) {
 231         const typename atomic_t::write_lock_type lock_this(locker, atomic_t::infinite_timeout());
 232         const typename atomic_t::read_lock_type lock_that(a.locker, atomic_t::infinite_timeout());
 233         count-=a.count;
 234         return count;
 235 }
 236 
 237 template<class V, class LkT>
 238 template<class BinOp>
 239 inline
 240 typename atomic_ctr_gen<V, LkT>::value_type
 241 atomic_ctr_gen<V, LkT>::apply(typename BinOp::second_argument_type const &a, BinOp const &op) noexcept(noexcept(op.operator()(std::declval<value_type>(), std::declval<typename BinOp::second_argument_type>()))) {
 242         const typename atomic_t::write_lock_type lock(locker, atomic_t::infinite_timeout());
 243         count=op.operator()(count,a);
 244         return count;
 245 }
 246 
 247 template<class V, class LkT>
 248 template<class V1>
 249 inline
 250 typename atomic_ctr_gen<V, LkT>::value_type
 251 atomic_ctr_gen<V, LkT>::apply(V1 const &a, std::plus<V1> const &) noexcept(true) {
 252         return *this+=a;
 253 }
 254 
 255 template<class V, class LkT>
 256 template<class V1>
 257 inline
 258 typename atomic_ctr_gen<V, LkT>::value_type
 259 atomic_ctr_gen<V, LkT>::apply(V1 const &a, std::minus<V1> const &) noexcept(true) {
 260         return *this-=a;
 261 }
 262 
 263 template<class V, class LkT>
 264 inline bool
 265 atomic_ctr_gen<V, LkT>::compare_exchange_strong(value_type expected, value_type desired) noexcept(true) {
 266         const typename atomic_t::write_lock_type lock(locker, atomic_t::infinite_timeout());
 267         if (count==expected) {
 268                 count=desired;
 269                 return true;
 270         } else {
 271                 return false;
 272         }
 273 }
 274 
 275 template<class V, class LkT>
 276 template<class V1, class V2>
 277 inline typename std::enable_if<std::is_pointer<V2>::value, bool>::type
 278 atomic_ctr_gen<V, LkT>::compare_exchange_strong(value_type expected, V1 desired) noexcept(true) {
 279         static_assert(std::is_base_of<typename std::remove_pointer<value_type>::type, typename std::remove_pointer<V1>::type>::value, "The two types must have the same base.");
 280         const typename atomic_t::write_lock_type lock(locker, atomic_t::infinite_timeout());
 281         if (count==expected) {
 282                 count=desired;
 283                 return true;
 284         } else {
 285                 return false;
 286         }
 287 }
 288 
 289 template<class V, class LkT>
 290 template<class Op>
 291 inline atomic_ctr_gen<V, LkT>
 292 atomic_ctr_gen<V, LkT>::assign(Op &&op) noexcept(true) {
 293         atomic_ctr_gen expected;
 294         do {
 295                 expected=*this;
 296         } while (!compare_exchange_strong(expected, op(expected)));
 297         return expected;
 298 }
 299 
 300 template<class V, class LkT> inline constexpr
 301 atomic_ctr_opt<V, LkT>::atomic_ctr_opt() noexcept(true)
 302 : count() {
 303 }
 304 
 305 template<class V, class LkT> inline constexpr
 306 atomic_ctr_opt<V, LkT>::atomic_ctr_opt(const value_type v) noexcept(true)
 307 : count(v) {
 308 }
 309 
 310 template<class V, class LkT> constexpr inline
 311 atomic_ctr_opt<V, LkT>::atomic_ctr_opt(const atomic_ctr_opt &a) noexcept(true)
 312 : count(a.get()) {
 313 }
 314 
 315 template<class V, class LkT>
 316 template<class V1>
 317 constexpr inline
 318 atomic_ctr_opt<V, LkT>::atomic_ctr_opt(const atomic_ctr_opt<V1, LkT> &a) noexcept(true)
 319 : count(dynamic_cast<value_type>(a.get())) {
 320 // This is too brutal: it doesn't detect common bases....       static_assert(std::is_base_of<typename std::remove_pointer<value_type>::type, typename std::remove_pointer<V1>::type>::value, "The two types must have the same base.");
 321 }
 322 
 323 template<class V, class LkT>
 324 template<class V1>
 325 inline
 326 atomic_ctr_opt<V, LkT>::atomic_ctr_opt(atomic_ctr_opt<V1, LkT> &&a) noexcept(true)
 327 : count() {
 328 // This is too brutal: it doesn't detect common bases....               static_assert(std::is_base_of<typename std::remove_pointer<value_type>::type, typename std::remove_pointer<V1>::type>::value, "The two types must have the same base.");
 329         swap(a);
 330 }
 331 
 332 template<class V, class LkT> inline
 333 atomic_ctr_opt<V, LkT>::~atomic_ctr_opt() noexcept(true) {
 334         assert(count.is_lock_free());
 335 }
 336 
 337 template<class V, class LkT> inline void
 338 atomic_ctr_opt<V, LkT>::swap(atomic_ctr_opt &a) noexcept(true) {
 339         const value_type lhs_orig=count.exchange(a.get());
 340         a.count.store(lhs_orig);
 341 }
 342 
 343 template<class V, class LkT>
 344 template<class V1, class V2>
 345 inline typename std::enable_if<std::is_pointer<V2>::value, void>::type
 346 atomic_ctr_opt<V, LkT>::swap(atomic_ctr_opt<V1, LkT> &a) noexcept(true) {
 347 // This is too brutal: it doesn't detect common bases....                       static_assert(std::is_base_of<typename std::remove_pointer<value_type>::type, typename std::remove_pointer<V1>::type>::value, "The two types must have the same base.");
 348         value_type const tmp=dynamic_cast<value_type>(a.get());
 349         a.count.exchange(dynamic_cast<typename atomic_ctr_opt<V1, LkT>::value_type>(count.load()));
 350         count.exchange(tmp);
 351 }
 352 
 353 template<class V, class LkT>
 354 template<class V1, class V2>
 355 inline typename std::enable_if<std::is_pointer<V2>::value, void>::type
 356 atomic_ctr_opt<V, LkT>::operator=(const atomic_ctr_opt<V1, LkT> &a) noexcept(true) {
 357 // This is too brutal: it doesn't detect common bases....               static_assert(std::is_base_of<typename std::remove_pointer<value_type>::type, typename std::remove_pointer<V1>::type>::value, "The two types must have the same base.");
 358         assert(count.is_lock_free() && a.count.is_lock_free());
 359         count=dynamic_cast<value_type>(a.get());
 360 }
 361 
 362 template<class V, class LkT> inline void
 363 atomic_ctr_opt<V, LkT>::operator=(const atomic_ctr_opt &a) noexcept(true) {
 364         assert(count.is_lock_free() && a.count.is_lock_free());
 365         count=a.get();
 366 }
 367 
 368 template<class V, class LkT> inline void
 369 atomic_ctr_opt<V, LkT>::operator=(const value_type &v) noexcept(true) {
 370         assert(count.is_lock_free());
 371         count=v;
 372 }
 373 
 374 template<class V, class LkT> constexpr inline typename atomic_ctr_opt<V, LkT>::value_type
 375 atomic_ctr_opt<V, LkT>::get() const noexcept(true) {
 376         assert(count.is_lock_free());
 377         return count.load();
 378 }
 379 
 380 template<class V, class LkT> constexpr inline bool
 381 atomic_ctr_opt<V, LkT>::operator==(const value_type v) const noexcept(true) {
 382         assert(count.is_lock_free());
 383         return count==v;
 384 }
 385 
 386 template<class V, class LkT> constexpr inline bool
 387 atomic_ctr_opt<V, LkT>::operator==(const atomic_ctr_opt &a) const noexcept(true) {
 388         assert(count.is_lock_free() && a.count.is_lock_free());
 389         return count==a.count;
 390 }
 391 
 392 template<class V, class LkT> constexpr inline bool
 393 atomic_ctr_opt<V, LkT>::operator!=(const value_type v) const noexcept(true) {
 394         assert(count.is_lock_free());
 395         return !operator==(v);
 396 }
 397 
 398 template<class V, class LkT> constexpr inline bool
 399 atomic_ctr_opt<V, LkT>::operator!=(const atomic_ctr_opt &a) const noexcept(true) {
 400         assert(count.is_lock_free() && a.count.is_lock_free());
 401         return !operator==(a);
 402 }
 403 
 404 template<class V, class LkT> constexpr inline
 405 atomic_ctr_opt<V, LkT>::operator bool() const noexcept(true) {
 406         assert(count.is_lock_free());
 407         return count!=value_type();
 408 }
 409 
 410 template<class V, class LkT> constexpr inline bool
 411 atomic_ctr_opt<V, LkT>::operator<(const value_type v) const noexcept(true) {
 412         assert(count.is_lock_free());
 413         return count<v;
 414 }
 415 
 416 template<class V, class LkT> constexpr inline bool
 417 atomic_ctr_opt<V, LkT>::operator<(const atomic_ctr_opt &a) const noexcept(true) {
 418         assert(count.is_lock_free() && a.count.is_lock_free());
 419         return count<a.count;
 420 }
 421 
 422 template<class V, class LkT> constexpr inline bool
 423 atomic_ctr_opt<V, LkT>::operator<(const base_t &a) const noexcept(true) {
 424         assert(count.is_lock_free());
 425         return *this<dynamic_cast<atomic_ctr_opt const &>(a);
 426 }
 427 
 428 template<class V, class LkT> constexpr inline bool
 429 atomic_ctr_opt<V, LkT>::operator>(const value_type v) const noexcept(true) {
 430         assert(count.is_lock_free());
 431         return count>v;
 432 }
 433 
 434 template<class V, class LkT> constexpr inline bool
 435 atomic_ctr_opt<V, LkT>::operator>(const atomic_ctr_opt &a) const noexcept(true) {
 436         assert(count.is_lock_free() && a.count.is_lock_free());
 437         return count>a.count;
 438 }
 439 
 440 template<class V, class LkT> constexpr inline bool
 441 atomic_ctr_opt<V, LkT>::operator>(const base_t &a) const noexcept(true) {
 442         assert(count.is_lock_free());
 443         return *this>dynamic_cast<atomic_ctr_opt const &>(a);
 444 }
 445 
 446 template<class V, class LkT> constexpr inline bool
 447 atomic_ctr_opt<V, LkT>::operator<=(const value_type v) const noexcept(true) {
 448         assert(count.is_lock_free());
 449         return count<=v;
 450 }
 451 
 452 template<class V, class LkT> constexpr inline bool
 453 atomic_ctr_opt<V, LkT>::operator<=(const atomic_ctr_opt &a) const noexcept(true) {
 454         assert(count.is_lock_free() && a.count.is_lock_free());
 455         return count<=a.count;
 456 }
 457 
 458 template<class V, class LkT> constexpr inline bool
 459 atomic_ctr_opt<V, LkT>::operator>=(const atomic_ctr_opt &a) const noexcept(true) {
 460         assert(count.is_lock_free() && a.count.is_lock_free());
 461         return count>=a.count;
 462 }
 463 
 464 template<class V, class LkT> constexpr inline bool
 465 atomic_ctr_opt<V, LkT>::operator>=(const value_type v) const noexcept(true) {
 466         assert(count.is_lock_free());
 467         return count>=v;
 468 }
 469 
 470 template<class V, class LkT> inline typename atomic_ctr_opt<V, LkT>::value_type
 471 atomic_ctr_opt<V, LkT>::operator++() noexcept(true) {
 472         assert(count.is_lock_free());
 473         return ++count;
 474 }
 475 
 476 template<class V, class LkT> inline typename atomic_ctr_opt<V, LkT>::value_type
 477 atomic_ctr_opt<V, LkT>::operator++(int) noexcept(true) {
 478         assert(count.is_lock_free());
 479         return count++;
 480 }
 481 
 482 template<class V, class LkT> inline typename atomic_ctr_opt<V, LkT>::value_type
 483 atomic_ctr_opt<V, LkT>::operator--() noexcept(true) {
 484         assert(count.is_lock_free());
 485         return --count;
 486 }
 487 
 488 template<class V, class LkT> inline typename atomic_ctr_opt<V, LkT>::value_type
 489 atomic_ctr_opt<V, LkT>::operator--(int) noexcept(true) {
 490         assert(count.is_lock_free());
 491         return count--;
 492 }
 493 
 494 template<class V, class LkT> inline typename atomic_ctr_opt<V, LkT>::value_type
 495 atomic_ctr_opt<V, LkT>::operator+=(const value_type v) noexcept(true) {
 496         assert(count.is_lock_free());
 497         return count+=v;
 498 }
 499 
 500 template<class V, class LkT> inline typename atomic_ctr_opt<V, LkT>::value_type
 501 atomic_ctr_opt<V, LkT>::operator+=(const atomic_ctr_opt &a) noexcept(true) {
 502         assert(count.is_lock_free() && a.count.is_lock_free());
 503         return *this+=a.count;
 504 }
 505 
 506 template<class V, class LkT> inline typename atomic_ctr_opt<V, LkT>::value_type
 507 atomic_ctr_opt<V, LkT>::operator-=(const value_type v) noexcept(true) {
 508         assert(count.is_lock_free());
 509         return count-=v;
 510 }
 511 
 512 template<class V, class LkT> inline typename atomic_ctr_opt<V, LkT>::value_type
 513 atomic_ctr_opt<V, LkT>::operator-=(const atomic_ctr_opt &a) noexcept(true) {
 514         assert(count.is_lock_free() && a.count.is_lock_free());
 515         return *this-=a.count;
 516 }
 517 
 518 template<class V, class LkT>
 519 inline bool
 520 atomic_ctr_opt<V, LkT>::compare_exchange_strong(value_type expected, value_type desired) noexcept(true) {
 521         assert(count.is_lock_free());
 522         return count.compare_exchange_strong(expected, desired);
 523 }
 524 
 525 template<class V, class LkT>
 526 template<class V1, class V2>
 527 inline typename std::enable_if<std::is_pointer<V2>::value, bool>::type
 528 atomic_ctr_opt<V, LkT>::compare_exchange_strong(value_type expected, V1 desired) noexcept(true) {
 529         static_assert(std::is_base_of<typename std::remove_pointer<value_type>::type, typename std::remove_pointer<V1>::type>::value, "The two types must have the same base.");
 530         return count.compare_exchange_strong(expected, desired);
 531 }
 532 
 533 template<class V, class LkT>
 534 template<class BinOp>
 535 inline
 536 typename atomic_ctr_opt<V, LkT>::value_type
 537 atomic_ctr_opt<V, LkT>::apply(typename BinOp::second_argument_type const &a, BinOp const &op) noexcept(noexcept(op.operator()(std::declval<value_type>(), std::declval<typename BinOp::second_argument_type>()))) {
 538         assert(count.is_lock_free());
 539         value_type expected=count.load();
 540         value_type desired;
 541         do {
 542                 desired=op.operator()(expected, a);
 543         } while (!compare_exchange_strong(expected, desired));
 544         return expected;
 545 }
 546 
 547 template<class V, class LkT>
 548 template<class V1>
 549 inline
 550 typename atomic_ctr_opt<V, LkT>::value_type
 551 atomic_ctr_opt<V, LkT>::apply(V1 const &a, std::plus<V1> const &) noexcept(true) {
 552         assert(count.is_lock_free());
 553         return *this+=a;
 554 }
 555 
 556 template<class V, class LkT>
 557 template<class V1>
 558 inline
 559 typename atomic_ctr_opt<V, LkT>::value_type
 560 atomic_ctr_opt<V, LkT>::apply(V1 const &a, std::minus<V1> const &) noexcept(true) {
 561         assert(count.is_lock_free());
 562         return *this-=a;
 563 }
 564 
 565 template<class V, class LkT>
 566 template<class Op>
 567 inline atomic_ctr_opt<V, LkT>
 568 atomic_ctr_opt<V, LkT>::assign(Op &&op) noexcept(true) {
 569         atomic_ctr_opt expected;
 570         do {
 571                 expected=*this;
 572         } while (!compare_exchange_strong(expected.get(), op(expected).get()));
 573         return expected;
 574 }
 575 
 576 } }

/* [<][>][^][v][top][bottom][index][help] */