diff --git a/Include/auROXTL/auAtomic.hpp b/Include/auROXTL/auAtomic.hpp index d85b5d1..e061e47 100644 --- a/Include/auROXTL/auAtomic.hpp +++ b/Include/auROXTL/auAtomic.hpp @@ -18,13 +18,21 @@ struct AuAtomicUtils static T Set(T *in, AuUInt8 offset); /** - * @brief - * @param in - * @param orValue - * @return original value + * @brief + * @param in + * @param orValue + * @return original value */ static T Or(T *in, T orValue); + /** + * @brief + * @param in + * @param andValue + * @return original value + */ + static T And(T *in, T andValue); + /** * @brief Adds addend to in * @return updated value @@ -226,6 +234,59 @@ inline auline T AuAtomicUtils::Set(T *in, AuUInt8 offset) return AuAtomicUtils::Or(in, T(1) << offset); } +#if !defined(AURORA_IS_32BIT) +template <> +inline auline AuUInt64 AuAtomicUtils::And(AuUInt64 *in, AuUInt64 AndValue) +{ + return _InterlockedAnd64(reinterpret_cast(in), AndValue); +} +#endif + +template <> +inline auline AuUInt32 AuAtomicUtils::And(AuUInt32 *in, AuUInt32 AndValue) +{ + return _InterlockedAnd(reinterpret_cast(in), AndValue); +} + +template <> +inline auline AuUInt16 AuAtomicUtils::And(AuUInt16 *in, AuUInt16 AndValue) +{ + return _InterlockedAnd16(reinterpret_cast(in), AndValue); +} + +#if !defined(AURORA_IS_32BIT) +template <> +inline auline AuInt64 AuAtomicUtils::And(AuInt64 *in, AuInt64 AndValue) +{ + return _InterlockedAnd64(reinterpret_cast(in), AndValue); +} +#endif + +template <> +inline auline AuInt32 AuAtomicUtils::And(AuInt32 *in, AuInt32 AndValue) +{ + return _InterlockedAnd(reinterpret_cast(in), AndValue); +} + +template <> +inline auline long AuAtomicUtils::And(long *in, long AndValue) +{ + return _InterlockedAnd(reinterpret_cast(in), AndValue); +} + +template <> +inline auline unsigned long AuAtomicUtils::And(unsigned long *in, unsigned long AndValue) +{ + return _InterlockedAnd(reinterpret_cast(in), AndValue); +} + +template <> +inline auline AuInt16 AuAtomicUtils::And(AuInt16 *in, AuInt16 AndValue) +{ + return _InterlockedAnd16(reinterpret_cast(in), AndValue); +} + + #elif defined(AURORA_COMPILER_CLANG) || defined(AURORA_COMPILER_GCC) template @@ -258,6 +319,12 @@ inline auline T AuAtomicUtils::Or(T *in, T value) return __sync_fetch_and_or(in, value); } +template +inline auline T AuAtomicUtils::And(T *in, T value) +{ + return __sync_fetch_and_and(in, value); +} + #endif template @@ -315,6 +382,13 @@ T AuAtomicSet(T *in, AuUInt8 offset) return AuAtomicUtils::Set(in, offset); } +template +auline +bool AuAtomicUnset(T *in, AuUInt8 offset) +{ + return AuAtomicUtils::And(in, ~(1u << AuUInt32(offset))) != 0; +} + template auline T AuAtomicOr(T *in, T value) @@ -322,6 +396,13 @@ T AuAtomicOr(T *in, T value) return AuAtomicUtils::Or(in, value); } +template +auline +T AuAtomicAnd(T *in, T value) +{ + return AuAtomicUtils::And(in, value); +} + template auline T AuAtomicAdd(T *in, T addend)