123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- #pragma once
- #include "atomic.h"
- #include <util/generic/typetraits.h>
- template <typename T>
- inline TAtomic* AsAtomicPtr(T volatile* target) {
- return reinterpret_cast<TAtomic*>(target);
- }
- template <typename T>
- inline const TAtomic* AsAtomicPtr(T const volatile* target) {
- return reinterpret_cast<const TAtomic*>(target);
- }
- // integral types
- template <typename T>
- struct TAtomicTraits {
- enum {
- Castable = std::is_integral<T>::value && sizeof(T) == sizeof(TAtomicBase) && !std::is_const<T>::value,
- };
- };
- template <typename T, typename TT>
- using TEnableIfCastable = std::enable_if_t<TAtomicTraits<T>::Castable, TT>;
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicGet(T const volatile& target) {
- return static_cast<T>(AtomicGet(*AsAtomicPtr(&target)));
- }
- template <typename T>
- inline TEnableIfCastable<T, void> AtomicSet(T volatile& target, TAtomicBase value) {
- AtomicSet(*AsAtomicPtr(&target), value);
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicIncrement(T volatile& target) {
- return static_cast<T>(AtomicIncrement(*AsAtomicPtr(&target)));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicGetAndIncrement(T volatile& target) {
- return static_cast<T>(AtomicGetAndIncrement(*AsAtomicPtr(&target)));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicDecrement(T volatile& target) {
- return static_cast<T>(AtomicDecrement(*AsAtomicPtr(&target)));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicGetAndDecrement(T volatile& target) {
- return static_cast<T>(AtomicGetAndDecrement(*AsAtomicPtr(&target)));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicAdd(T volatile& target, TAtomicBase value) {
- return static_cast<T>(AtomicAdd(*AsAtomicPtr(&target), value));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicGetAndAdd(T volatile& target, TAtomicBase value) {
- return static_cast<T>(AtomicGetAndAdd(*AsAtomicPtr(&target), value));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicSub(T volatile& target, TAtomicBase value) {
- return static_cast<T>(AtomicSub(*AsAtomicPtr(&target), value));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicGetAndSub(T volatile& target, TAtomicBase value) {
- return static_cast<T>(AtomicGetAndSub(*AsAtomicPtr(&target), value));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicSwap(T volatile* target, TAtomicBase exchange) {
- return static_cast<T>(AtomicSwap(AsAtomicPtr(target), exchange));
- }
- template <typename T>
- inline TEnableIfCastable<T, bool> AtomicCas(T volatile* target, TAtomicBase exchange, TAtomicBase compare) {
- return AtomicCas(AsAtomicPtr(target), exchange, compare);
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicGetAndCas(T volatile* target, TAtomicBase exchange, TAtomicBase compare) {
- return static_cast<T>(AtomicGetAndCas(AsAtomicPtr(target), exchange, compare));
- }
- template <typename T>
- inline TEnableIfCastable<T, bool> AtomicTryLock(T volatile* target) {
- return AtomicTryLock(AsAtomicPtr(target));
- }
- template <typename T>
- inline TEnableIfCastable<T, bool> AtomicTryAndTryLock(T volatile* target) {
- return AtomicTryAndTryLock(AsAtomicPtr(target));
- }
- template <typename T>
- inline TEnableIfCastable<T, void> AtomicUnlock(T volatile* target) {
- AtomicUnlock(AsAtomicPtr(target));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicOr(T volatile& target, TAtomicBase value) {
- return static_cast<T>(AtomicOr(*AsAtomicPtr(&target), value));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicAnd(T volatile& target, TAtomicBase value) {
- return static_cast<T>(AtomicAnd(*AsAtomicPtr(&target), value));
- }
- template <typename T>
- inline TEnableIfCastable<T, T> AtomicXor(T volatile& target, TAtomicBase value) {
- return static_cast<T>(AtomicXor(*AsAtomicPtr(&target), value));
- }
- // pointer types
- template <typename T>
- inline T* AtomicGet(T* const volatile& target) {
- return reinterpret_cast<T*>(AtomicGet(*AsAtomicPtr(&target)));
- }
- template <typename T>
- inline void AtomicSet(T* volatile& target, T* value) {
- AtomicSet(*AsAtomicPtr(&target), reinterpret_cast<TAtomicBase>(value));
- }
- using TNullPtr = decltype(nullptr);
- template <typename T>
- inline void AtomicSet(T* volatile& target, TNullPtr) {
- AtomicSet(*AsAtomicPtr(&target), 0);
- }
- template <typename T>
- inline T* AtomicSwap(T* volatile* target, T* exchange) {
- return reinterpret_cast<T*>(AtomicSwap(AsAtomicPtr(target), reinterpret_cast<TAtomicBase>(exchange)));
- }
- template <typename T>
- inline T* AtomicSwap(T* volatile* target, TNullPtr) {
- return reinterpret_cast<T*>(AtomicSwap(AsAtomicPtr(target), 0));
- }
- template <typename T>
- inline bool AtomicCas(T* volatile* target, T* exchange, T* compare) {
- return AtomicCas(AsAtomicPtr(target), reinterpret_cast<TAtomicBase>(exchange), reinterpret_cast<TAtomicBase>(compare));
- }
- template <typename T>
- inline T* AtomicGetAndCas(T* volatile* target, T* exchange, T* compare) {
- return reinterpret_cast<T*>(AtomicGetAndCas(AsAtomicPtr(target), reinterpret_cast<TAtomicBase>(exchange), reinterpret_cast<TAtomicBase>(compare)));
- }
- template <typename T>
- inline bool AtomicCas(T* volatile* target, T* exchange, TNullPtr) {
- return AtomicCas(AsAtomicPtr(target), reinterpret_cast<TAtomicBase>(exchange), 0);
- }
- template <typename T>
- inline T* AtomicGetAndCas(T* volatile* target, T* exchange, TNullPtr) {
- return reinterpret_cast<T*>(AtomicGetAndCas(AsAtomicPtr(target), reinterpret_cast<TAtomicBase>(exchange), 0));
- }
- template <typename T>
- inline bool AtomicCas(T* volatile* target, TNullPtr, T* compare) {
- return AtomicCas(AsAtomicPtr(target), 0, reinterpret_cast<TAtomicBase>(compare));
- }
- template <typename T>
- inline T* AtomicGetAndCas(T* volatile* target, TNullPtr, T* compare) {
- return reinterpret_cast<T*>(AtomicGetAndCas(AsAtomicPtr(target), 0, reinterpret_cast<TAtomicBase>(compare)));
- }
- template <typename T>
- inline bool AtomicCas(T* volatile* target, TNullPtr, TNullPtr) {
- return AtomicCas(AsAtomicPtr(target), 0, 0);
- }
- template <typename T>
- inline T* AtomicGetAndCas(T* volatile* target, TNullPtr, TNullPtr) {
- return reinterpret_cast<T*>(AtomicGetAndCas(AsAtomicPtr(target), 0, 0));
- }
|