102 |
102 |
103 template<typename D, typename I> |
103 template<typename D, typename I> |
104 inline static D add(D volatile* dest, I add_value, |
104 inline static D add(D volatile* dest, I add_value, |
105 atomic_memory_order order = memory_order_conservative); |
105 atomic_memory_order order = memory_order_conservative); |
106 |
106 |
107 template<typename I, typename D> |
107 template<typename D, typename I> |
108 inline static D sub(I sub_value, D volatile* dest, |
108 inline static D sub(D volatile* dest, I sub_value, |
109 atomic_memory_order order = memory_order_conservative); |
109 atomic_memory_order order = memory_order_conservative); |
110 |
110 |
111 // Atomically increment location. inc() provide: |
111 // Atomically increment location. inc() provide: |
112 // <fence> increment-dest <membar StoreLoad|StoreStore> |
112 // <fence> increment-dest <membar StoreLoad|StoreStore> |
113 // The type D may be either a pointer type, or an integral |
113 // The type D may be either a pointer type, or an integral |
541 // Assumes two's complement integer representation. |
541 // Assumes two's complement integer representation. |
542 #pragma warning(suppress: 4146) |
542 #pragma warning(suppress: 4146) |
543 Atomic::add(dest, I(-1), order); |
543 Atomic::add(dest, I(-1), order); |
544 } |
544 } |
545 |
545 |
546 template<typename I, typename D> |
546 template<typename D, typename I> |
547 inline D Atomic::sub(I sub_value, D volatile* dest, atomic_memory_order order) { |
547 inline D Atomic::sub(D volatile* dest, I sub_value, atomic_memory_order order) { |
548 STATIC_ASSERT(IsPointer<D>::value || IsIntegral<D>::value); |
548 STATIC_ASSERT(IsPointer<D>::value || IsIntegral<D>::value); |
549 STATIC_ASSERT(IsIntegral<I>::value); |
549 STATIC_ASSERT(IsIntegral<I>::value); |
550 // If D is a pointer type, use [u]intptr_t as the addend type, |
550 // If D is a pointer type, use [u]intptr_t as the addend type, |
551 // matching signedness of I. Otherwise, use D as the addend type. |
551 // matching signedness of I. Otherwise, use D as the addend type. |
552 typedef typename Conditional<IsSigned<I>::value, intptr_t, uintptr_t>::type PI; |
552 typedef typename Conditional<IsSigned<I>::value, intptr_t, uintptr_t>::type PI; |