503
504 template<typename D>
505 inline void Atomic::inc(D volatile* dest) {
506 STATIC_ASSERT(IsPointer<D>::value || IsIntegral<D>::value);
507 typedef typename Conditional<IsPointer<D>::value, ptrdiff_t, D>::type I;
508 Atomic::add(I(1), dest);
509 }
510
511 template<typename D>
512 inline void Atomic::dec(D volatile* dest) {
513 STATIC_ASSERT(IsPointer<D>::value || IsIntegral<D>::value);
514 typedef typename Conditional<IsPointer<D>::value, ptrdiff_t, D>::type I;
515 // Assumes two's complement integer representation.
516 #pragma warning(suppress: 4146)
517 Atomic::add(I(-1), dest);
518 }
519
520 template<typename I, typename D>
521 inline D Atomic::sub(I sub_value, D volatile* dest) {
522 STATIC_ASSERT(IsPointer<D>::value || IsIntegral<D>::value);
523 // Assumes two's complement integer representation.
524 #pragma warning(suppress: 4146)
525 return Atomic::add(-sub_value, dest);
526 }
527
528 // Define the class before including platform file, which may specialize
529 // the operator definition. No generic definition of specializations
530 // of the operator template are provided, nor are there any generic
531 // specializations of the class. The platform file is responsible for
532 // providing those.
533 template<size_t byte_size>
534 struct Atomic::PlatformCmpxchg VALUE_OBJ_CLASS_SPEC {
535 template<typename T>
536 T operator()(T exchange_value,
537 T volatile* dest,
538 T compare_value,
539 cmpxchg_memory_order order) const;
540 };
541
542 // Define the class before including platform file, which may use this
543 // as a base class, requiring it be complete. The definition is later
544 // in this file, near the other definitions related to cmpxchg.
545 struct Atomic::CmpxchgByteUsingInt VALUE_OBJ_CLASS_SPEC {
|
503
504 template<typename D>
505 inline void Atomic::inc(D volatile* dest) {
506 STATIC_ASSERT(IsPointer<D>::value || IsIntegral<D>::value);
507 typedef typename Conditional<IsPointer<D>::value, ptrdiff_t, D>::type I;
508 Atomic::add(I(1), dest);
509 }
510
511 template<typename D>
512 inline void Atomic::dec(D volatile* dest) {
513 STATIC_ASSERT(IsPointer<D>::value || IsIntegral<D>::value);
514 typedef typename Conditional<IsPointer<D>::value, ptrdiff_t, D>::type I;
515 // Assumes two's complement integer representation.
516 #pragma warning(suppress: 4146)
517 Atomic::add(I(-1), dest);
518 }
519
520 template<typename I, typename D>
521 inline D Atomic::sub(I sub_value, D volatile* dest) {
522 STATIC_ASSERT(IsPointer<D>::value || IsIntegral<D>::value);
523 STATIC_ASSERT(IsIntegral<I>::value);
524 typedef typename Conditional<IsPointer<D>::value, ptrdiff_t, D>::type AddendType;
525 AddendType addend = sub_value;
526 STATIC_ASSERT((IsIntegral<D>::value && IsSigned<I>::value == IsSigned<AddendType>::value) ||
527 IsPointer<D>::value);
528 // Assumes two's complement integer representation.
529 #pragma warning(suppress: 4146)
530 return Atomic::add(-addend, dest);
531 }
532
533 // Define the class before including platform file, which may specialize
534 // the operator definition. No generic definition of specializations
535 // of the operator template are provided, nor are there any generic
536 // specializations of the class. The platform file is responsible for
537 // providing those.
538 template<size_t byte_size>
539 struct Atomic::PlatformCmpxchg VALUE_OBJ_CLASS_SPEC {
540 template<typename T>
541 T operator()(T exchange_value,
542 T volatile* dest,
543 T compare_value,
544 cmpxchg_memory_order order) const;
545 };
546
547 // Define the class before including platform file, which may use this
548 // as a base class, requiring it be complete. The definition is later
549 // in this file, near the other definitions related to cmpxchg.
550 struct Atomic::CmpxchgByteUsingInt VALUE_OBJ_CLASS_SPEC {
|