#ifndef __has_builtin
# define __has_builtin(x) 0
#endif
#ifndef __has_feature
# define __has_feature(x) 0
#endif
#ifndef __has_extension
# define __has_extension(x) 0
#endif
#if !__has_extension(c_atomic)
# define _Atomic(T) T
#endif
#if __has_builtin(__c11_atomic_exchange)
# define ATOMIC_BUILTIN(name) __c11_atomic_##name
#else
# define ATOMIC_BUILTIN(name) __atomic_##name##_n
#endif
namespace
{
enum memory_order
{
acquire = __ATOMIC_ACQUIRE,
release = __ATOMIC_RELEASE,
seqcst = __ATOMIC_SEQ_CST
};
template<typename T>
class atomic
{
_Atomic(T) val;
public:
constexpr atomic(T init) : val(init) {}
T load(memory_order order = memory_order::seqcst)
{
return ATOMIC_BUILTIN(load)(&val, order);
}
void store(T v, memory_order order = memory_order::seqcst)
{
return ATOMIC_BUILTIN(store)(&val, v, order);
}
T exchange(T v, memory_order order = memory_order::seqcst)
{
return ATOMIC_BUILTIN(exchange)(&val, v, order);
}
bool compare_exchange(T & expected,
T desired,
memory_order order = memory_order::seqcst)
{
#if __has_builtin(__c11_atomic_compare_exchange_strong)
return __c11_atomic_compare_exchange_strong(
&val, &expected, desired, order, order);
#else
return __atomic_compare_exchange_n(
&val, &expected, desired, true, order, order);
#endif
}
};
}
#undef ATOMIC_BUILTIN