// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT

#pragma once
#include <concepts>
#include <futex.h>
#include <type_traits>

__clang_ignored_warning_push("-Watomic-alignment") namespace std
{
	enum class memory_order : int
	{
		relaxed = __ATOMIC_RELAXED,
		consume = __ATOMIC_CONSUME,
		acquire = __ATOMIC_ACQUIRE,
		release = __ATOMIC_RELEASE,
		acq_rel = __ATOMIC_ACQ_REL,
		seq_cst = __ATOMIC_SEQ_CST,
	};
	inline constexpr memory_order memory_order_relaxed = memory_order::relaxed;
	inline constexpr memory_order memory_order_consume = memory_order::consume;
	inline constexpr memory_order memory_order_acquire = memory_order::acquire;
	inline constexpr memory_order memory_order_release = memory_order::release;
	inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel;
	inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst;

	namespace detail
	{
		/**
		 * Version of atomic<T> for primitive types.  This calls the atomics
		 * support library for everything on platforms with no A extension and
		 * will use atomic instructions on ones that do.
		 *
		 * This differs from std::atomic in two intentional ways:
		 *
		 *  - The `wait` and `notify_*` methods are defined only on 4-byte
		 *    values.  If there is a requirement for anything else, we should
		 *    extend the futex APIs in the scheduler to deal with other types.
		 *  - The `wait` call has a non-standard extension that handles takes a
		 *    CHERIoT timeout parameter.
		 *
		 *  Any other divergence is a bug.
		 *
		 *  This is a base class that is extended for arithmetic and pointer
		 *  types.
		 */
		template<typename T>
		class primitive_atomic
		{
			/**
			 * SFINAE helper to give us the underlying type of enums and the
			 * raw type of everything else.
			 */
			template<typename U, bool = std::is_enum_v<U>>
			struct underlying_type
			{
				using type = U;
			};

			template<typename U>
			struct underlying_type<U, true> : ::std::underlying_type<U>
			{
			};

			protected:
			typename underlying_type<T>::type value;
			static_assert(std::is_arithmetic_v<T> || std::is_enum_v<T> ||
			                std::is_pointer_v<T> || std::is_null_pointer_v<T>,
			              "Invalid type for primitive atomic");

			__always_inline auto *pointer_for_intrinsics(T *pointer)
			{
				if constexpr (std::is_enum_v<T>)
				{
					return static_cast<std::underlying_type_t<T> *>(pointer);
				}
				else
				{
					return pointer;
				}
			}

			static decltype(value) *as_underlying(T *v)
			{
				return reinterpret_cast<decltype(value) *>(v);
			}
			static decltype(value) as_underlying(T v)
			{
				return static_cast<decltype(value)>(v);
			}

			public:
			using value_type                          = T;
			static constexpr bool is_always_lock_free = true;
			__always_inline bool  is_lock_free() const noexcept
			{
				return true;
			}
			__always_inline bool is_lock_free() const volatile noexcept
			{
				return true;
			}

			constexpr primitive_atomic() noexcept = default;
			__always_inline constexpr primitive_atomic(T desired) noexcept
			{
				value = desired;
			}
			primitive_atomic(const primitive_atomic &) = delete;

			__always_inline T operator=(T desired) noexcept
			{
				store(desired);
				return desired;
			}
			__always_inline T operator=(T desired) volatile noexcept
			{
				return *const_cast<primitive_atomic<T> *>(this) = desired;
			}
			primitive_atomic &operator=(const primitive_atomic &) = delete;
			primitive_atomic &
			operator=(const primitive_atomic &) volatile = delete;

			__always_inline void
			store(T desired, memory_order order = memory_order_seq_cst) noexcept
			{
				__atomic_store_n(&value, as_underlying(desired), int(order));
			}
			__always_inline void
			store(T            desired,
			      memory_order order = memory_order_seq_cst) volatile noexcept
			{
				const_cast<primitive_atomic<T> *>(this)->store(desired, order);
			}

			__always_inline T
			load(memory_order order = memory_order_seq_cst) const noexcept
			{
				return __atomic_load_n(&value, int(order));
			}

			__always_inline T load(
			  memory_order order = memory_order_seq_cst) const volatile noexcept
			{
				return const_cast<primitive_atomic<T> *>(this)->load(order);
			}

			__always_inline operator T() const noexcept
			{
				return load();
			}
			__always_inline operator T() const volatile noexcept
			{
				return load();
			}

			__always_inline T
			exchange(T            desired,
			         memory_order order = memory_order_seq_cst) noexcept
			{
				return T(__atomic_exchange_n(
				  &value, as_underlying(desired), int(order)));
			}
			__always_inline T exchange(
			  T            desired,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				return const_cast<primitive_atomic<T> *>(this)->exchange(
				  desired, order);
			}

			__always_inline bool
			compare_exchange_weak(T           &expected,
			                      T            desired,
			                      memory_order success,
			                      memory_order failure) noexcept
			{
				__atomic_compare_exchange_n(&value,
				                            as_underlying(&expected),
				                            as_underlying(desired),
				                            true,
				                            int(success),
				                            int(failure));
			}
			__always_inline bool
			compare_exchange_weak(T           &expected,
			                      T            desired,
			                      memory_order success,
			                      memory_order failure) volatile noexcept
			{
				return const_cast<primitive_atomic<T> *>(this)
				  ->compare_exchange_weak(expected, desired, success, failure);
			}
			__always_inline bool compare_exchange_weak(
			  T           &expected,
			  T            desired,
			  memory_order order = memory_order_seq_cst) noexcept
			{
				return compare_exchange_weak(expected, desired, order, order);
			}
			__always_inline bool compare_exchange_weak(
			  T           &expected,
			  T            desired,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				return const_cast<primitive_atomic<T> *>(this)
				  ->compare_exchange_weak(expected, desired, order);
			}

			__always_inline bool
			compare_exchange_strong(T           &expected,
			                        T            desired,
			                        memory_order success,
			                        memory_order failure) noexcept
			{
				return __atomic_compare_exchange_n(&value,
				                                   as_underlying(&expected),
				                                   as_underlying(desired),
				                                   false,
				                                   int(success),
				                                   int(failure));
			}
			__always_inline bool
			compare_exchange_strong(T           &expected,
			                        T            desired,
			                        memory_order success,
			                        memory_order failure) volatile noexcept
			{
				return const_cast<primitive_atomic<T> *>(this)
				  ->compare_exchange_strong(
				    expected, desired, success, failure);
			}
			__always_inline bool compare_exchange_strong(
			  T           &expected,
			  T            desired,
			  memory_order order = memory_order_seq_cst) noexcept
			{
				return compare_exchange_strong(expected, desired, order, order);
			}

			__always_inline bool compare_exchange_strong(
			  T           &expected,
			  T            desired,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				return const_cast<primitive_atomic<T> *>(this)
				  ->compare_exchange_strong(expected, desired, order);
			}

			__always_inline void
			wait(T            old,
			     memory_order order = memory_order::seq_cst) const noexcept
			  requires(sizeof(T) == sizeof(uint32_t))
			{
				futex_wait(reinterpret_cast<const uint32_t *>(&value),
				           reinterpret_cast<uint32_t>(as_underlying(old)));
			}

			__always_inline int
			wait(Timeout       *timeout,
			     T              old,
			     memory_order   order = memory_order::seq_cst,
			     FutexWaitFlags flags = FutexNone) const noexcept
			  requires(sizeof(T) == sizeof(uint32_t))
			{
				return futex_timed_wait(
				  timeout,
				  reinterpret_cast<const uint32_t *>(&value),
				  static_cast<uint32_t>(as_underlying(old)),
				  flags);
			}

			__always_inline int
			wait(Timeout *timeout, T old, FutexWaitFlags flags) const noexcept
			  requires(sizeof(T) == sizeof(uint32_t))
			{
				return wait(timeout, old, memory_order::seq_cst, flags);
			}

			__always_inline void
			wait(T old, memory_order order = memory_order::seq_cst) const
			  volatile noexcept requires(sizeof(T) == sizeof(uint32_t))
			{
				const_cast<primitive_atomic<T> *>(this)->wait(old, order);
			}

			__always_inline void notify_one() noexcept
			  requires(sizeof(T) == sizeof(uint32_t))
			{
				(void)futex_wake(reinterpret_cast<uint32_t *>(&value), 1);
			}
			__always_inline void notify_one() volatile noexcept
			  requires(sizeof(T) == sizeof(uint32_t))
			{
				const_cast<primitive_atomic<T> *>(this)->notify_one();
			}

			__always_inline void notify_all() noexcept
			  requires(sizeof(T) == sizeof(uint32_t))
			{
				(void)futex_wake(reinterpret_cast<uint32_t *>(&value),
				                 std::numeric_limits<uint32_t>::max());
			}
			__always_inline void notify_all() volatile noexcept
			  requires(sizeof(T) == sizeof(uint32_t))
			{
				const_cast<primitive_atomic<T> *>(this)->notify_all();
			}
		};

		/**
		 * Version of atomic for arithmetic types.  This adds the arithmetic
		 * methods.
		 */
		template<typename T>
		class arithmetic_atomic : public primitive_atomic<T>
		{
			public:
			using primitive_atomic<T>::primitive_atomic;
			using primitive_atomic<T>::operator=;
			using difference_type = typename primitive_atomic<T>::value_type;

			__always_inline T
			fetch_add(T arg, memory_order order = memory_order_seq_cst) noexcept
			{
				return __atomic_fetch_add(&this->value, arg, int(order));
			}
			__always_inline T fetch_add(
			  T            arg,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				const_cast<arithmetic_atomic<T> *>(this)->fetch_add(arg, order);
			}

			__always_inline T
			fetch_sub(T arg, memory_order order = memory_order_seq_cst) noexcept
			{
				return __atomic_fetch_sub(&this->value, arg, int(order));
			}
			__always_inline T fetch_sub(
			  T            arg,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				const_cast<arithmetic_atomic<T> *>(this)->fetch_sub(arg, order);
			}

			__always_inline T
			fetch_and(T arg, memory_order order = memory_order_seq_cst) noexcept
			{
				return __atomic_fetch_and(&this->value, arg, int(order));
			}
			__always_inline T fetch_and(
			  T            arg,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				const_cast<arithmetic_atomic<T> *>(this)->fetch_and(arg, order);
			}

			__always_inline T
			fetch_or(T arg, memory_order order = memory_order_seq_cst) noexcept
			{
				return __atomic_fetch_or(&this->value, arg, int(order));
			}
			__always_inline T fetch_or(
			  T            arg,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				const_cast<arithmetic_atomic<T> *>(this)->fetch_or(arg, order);
			}

			__always_inline T
			fetch_xor(T arg, memory_order order = memory_order_seq_cst) noexcept
			{
				return __atomic_fetch_xor(&this->value, arg, int(order));
			}
			__always_inline T fetch_xor(
			  T            arg,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				const_cast<arithmetic_atomic<T> *>(this)->fetch_xor(arg, order);
			}

			__always_inline T operator++() noexcept
			{
				return fetch_add(1) + 1;
			}
			__always_inline T operator++() volatile noexcept
			{
				return fetch_add(1) + 1;
			}
			__always_inline T operator++(int) noexcept
			{
				return fetch_add(1);
			}
			__always_inline T operator++(int) volatile noexcept
			{
				return fetch_add(1);
			}
			__always_inline T operator--() noexcept
			{
				return fetch_sub(1) - 1;
			}
			__always_inline T operator--() volatile noexcept
			{
				return fetch_sub(1) - 1;
			}
			__always_inline T operator--(int) noexcept
			{
				return fetch_sub(1);
			}
			__always_inline T operator--(int) volatile noexcept
			{
				return fetch_sub(1);
			}

			__always_inline T operator+=(T arg) noexcept
			{
				return fetch_add(arg) + arg;
			}
			__always_inline T operator+=(T arg) volatile noexcept
			{
				return fetch_add(arg) + arg;
			}
			__always_inline T operator-=(T arg) noexcept
			{
				return fetch_sub(arg) - arg;
			}
			__always_inline T operator-=(T arg) volatile noexcept
			{
				return fetch_sub(arg) - arg;
			}

			__always_inline T operator&=(T arg) noexcept
			{
				return fetch_and(arg) & arg;
			}
			__always_inline T operator&=(T arg) volatile noexcept
			{
				return fetch_and(arg) & arg;
			}
			__always_inline T operator|=(T arg) noexcept
			{
				return fetch_or(arg) | arg;
			}
			__always_inline T operator|=(T arg) volatile noexcept
			{
				return fetch_or(arg) | arg;
			}
			__always_inline T operator^=(T arg) noexcept
			{
				return fetch_xor(arg) ^ arg;
			}
			__always_inline T operator^=(T arg) volatile noexcept
			{
				return fetch_xor(arg) ^ arg;
			}
		};

		/**
		 * Version of atomic for pointer types.  This adds pointer arithmetic
		 * methods.
		 */
		template<typename T>
		class pointer_atomic : public primitive_atomic<T>
		{
			public:
			using primitive_atomic<T>::primitive_atomic;
			using difference_type = std::ptrdiff_t;

			T *fetch_add(std::ptrdiff_t arg,
			             memory_order   order = memory_order_seq_cst) noexcept
			{
				return __atomic_fetch_add(
				  &this->value, arg * sizeof(T), int(order));
			}
			T *fetch_add(
			  std::ptrdiff_t arg,
			  memory_order   order = memory_order_seq_cst) volatile noexcept
			{
				const_cast<pointer_atomic<T> *>(this)->fetch_add(arg,
				                                                 int(order));
			}

			T *fetch_sub(std::ptrdiff_t arg,
			             memory_order   order = memory_order_seq_cst) noexcept
			{
				return __atomic_fetch_sub(
				  &this->value, arg * sizeof(T), int(order));
			}
			T *fetch_sub(
			  std::ptrdiff_t arg,
			  memory_order   order = memory_order_seq_cst) volatile noexcept
			{
				const_cast<pointer_atomic<T> *>(this)->fetch_sub(arg,
				                                                 int(order));
			}

			__always_inline T *operator++() noexcept
			{
				return fetch_add(1) + 1;
			}
			__always_inline T *operator++() volatile noexcept
			{
				return fetch_add(1) + 1;
			}
			__always_inline T *operator++(int) noexcept
			{
				return fetch_add(1);
			}
			__always_inline T *operator++(int) volatile noexcept
			{
				return fetch_add(1);
			}
			__always_inline T *operator--() noexcept
			{
				return fetch_sub(1) - 1;
			}
			__always_inline T *operator--() volatile noexcept
			{
				return fetch_sub(1) - 1;
			}
			__always_inline T *operator--(int) noexcept
			{
				return fetch_sub(1);
			}
			__always_inline T *operator--(int) volatile noexcept
			{
				return fetch_sub(1);
			}

			__always_inline T *operator+=(std::ptrdiff_t arg) noexcept
			{
				return fetch_add(arg) + arg;
			}
			__always_inline T *operator+=(std::ptrdiff_t arg) volatile noexcept
			{
				return fetch_add(arg) + arg;
			}
			__always_inline T *operator-=(std::ptrdiff_t arg) noexcept
			{
				return fetch_sub(arg) - arg;
			}
			__always_inline T *operator-=(std::ptrdiff_t arg) volatile noexcept
			{
				return fetch_sub(arg) - arg;
			}
		};

		/**
		 * Simple flag lock.  This uses `primitive_atomic` to build a trivial
		 * lock.
		 */
		class flag_lock
		{
			/**
			 * Possible states of the flag lock.
			 */
			enum class LockState : uint32_t
			{
				/// Lock is not held.
				Unlocked,
				/// Lock is held, no waiters.
				Locked,
				/// Lock is held and one or more waiters exist.
				LockedWithWaiters
			};
			/// The lock state.
			primitive_atomic<LockState> lockWord;

			public:
			/**
			 * Acquire the lock.  Blocks indefinitely.
			 */
			__noinline void lock()
			{
				LockState old = LockState::Unlocked;
				while (true)
				{
					switch (old)
					{
						// If the lock is not held, try to acquire it and return
						// if we can.
						case LockState::Unlocked:
							if (lockWord.compare_exchange_strong(
							      old, LockState::Locked))
							{
								return;
							}
							break;
							// If the lock is held, mark it as having waiters
							// and then wait.
						case LockState::Locked:
							lockWord.exchange(LockState::LockedWithWaiters);
							[[fallthrough]];
							// If the lock is blocked with waiters, sleep
						case LockState::LockedWithWaiters:
							lockWord.wait(LockState::LockedWithWaiters);
					}
				}
			}

			/**
			 * Release the lock, waking any waiters if there are any.
			 */
			__noinline void unlock()
			{
				auto old = lockWord.exchange(LockState::Unlocked);
				if (old == LockState::LockedWithWaiters)
				{
					lockWord.notify_all();
				}
			}
		};

		/**
		 * Fallback `atomic` implementation that uses a lock to protect the
		 * value.
		 */
		template<typename T>
		class locked_atomic
		{
			private:
			/// The atomic value.
			T value;
			/// Lock protecting this object, at the end so that it can go into
			/// padding.
			mutable flag_lock lock;

			struct guard
			{
				flag_lock &lock;
				__always_inline ~guard()
				{
					lock.unlock();
				}
			};
			__always_inline guard acquire_lock()
			{
				lock.lock();
				return {lock};
			}

			public:
			using value_type                          = T;
			static constexpr bool is_always_lock_free = false;
			__always_inline bool  is_lock_free() const noexcept
			{
				return false;
			}
			__always_inline bool is_lock_free() const volatile noexcept
			{
				return false;
			}

			constexpr locked_atomic() noexcept = default;
			__always_inline constexpr locked_atomic(T desired) noexcept
			{
				value = desired;
			}
			locked_atomic(const locked_atomic &) = delete;

			__always_inline T operator=(T desired) noexcept
			{
				auto g = acquire_lock();
				value  = desired;
				return desired;
			}
			__always_inline T operator=(T desired) volatile noexcept
			{
				return *const_cast<locked_atomic<T> *>(this) = desired;
			}
			locked_atomic &operator=(const locked_atomic &) = delete;
			locked_atomic &operator=(const locked_atomic &) volatile = delete;

			__always_inline void
			store(T desired, memory_order order = memory_order_seq_cst) noexcept
			{
				auto g = acquire_lock();
				value  = desired;
			}
			__always_inline void
			store(T            desired,
			      memory_order order = memory_order_seq_cst) volatile noexcept
			{
				const_cast<locked_atomic<T> *>(this)->store(desired, order);
			}

			__always_inline T
			load(memory_order order = memory_order_seq_cst) const noexcept
			{
				auto g = acquire_lock();
				return value;
			}

			__always_inline T load(
			  memory_order order = memory_order_seq_cst) const volatile noexcept
			{
				return const_cast<locked_atomic<T> *>(this)->load(order);
			}

			__always_inline operator T() const noexcept
			{
				return load();
			}
			__always_inline operator T() const volatile noexcept
			{
				return load();
			}

			__always_inline T
			exchange(T            desired,
			         memory_order order = memory_order_seq_cst) noexcept
			{
				auto g   = acquire_lock();
				T    tmp = value;
				value    = desired;
				return tmp;
			}
			__always_inline T exchange(
			  T            desired,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				return const_cast<locked_atomic<T> *>(this)->exchange(desired,
				                                                      order);
			}

			__always_inline bool
			compare_exchange_weak(T           &expected,
			                      T            desired,
			                      memory_order success,
			                      memory_order failure) noexcept
			{
				auto g = acquire_lock();
				if (value == expected)
				{
					desired = value;
				}
				expected = value;
				return true;
			}
			__always_inline bool
			compare_exchange_weak(T           &expected,
			                      T            desired,
			                      memory_order success,
			                      memory_order failure) volatile noexcept
			{
				return const_cast<locked_atomic<T> *>(this)
				  ->compare_exchange_weak(expected, desired, success, failure);
			}
			__always_inline bool compare_exchange_weak(
			  T           &expected,
			  T            desired,
			  memory_order order = memory_order_seq_cst) noexcept
			{
				return compare_exchange_weak(expected, desired, order, order);
			}
			__always_inline bool compare_exchange_weak(
			  T           &expected,
			  T            desired,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				return const_cast<locked_atomic<T> *>(this)
				  ->compare_exchange_weak(expected, desired, order);
			}

			__always_inline bool
			compare_exchange_strong(T           &expected,
			                        T            desired,
			                        memory_order success,
			                        memory_order failure) noexcept
			{
				return compare_exchange_weak(
				  expected, desired, success, failure);
			}
			__always_inline bool
			compare_exchange_strong(T           &expected,
			                        T            desired,
			                        memory_order success,
			                        memory_order failure) volatile noexcept
			{
				return const_cast<locked_atomic<T> *>(this)
				  ->compare_exchange_strong(
				    expected, desired, success, failure);
			}
			__always_inline bool compare_exchange_strong(
			  T           &expected,
			  T            desired,
			  memory_order order = memory_order_seq_cst) noexcept
			{
				return compare_exchange_strong(expected, desired, order, order);
			}

			__always_inline bool compare_exchange_strong(
			  T           &expected,
			  T            desired,
			  memory_order order = memory_order_seq_cst) volatile noexcept
			{
				return const_cast<locked_atomic<T> *>(this)
				  ->compare_exchange_strong(expected, desired, order);
			}
		};

		template<typename T>
		using atomic = std::conditional_t<
		  std::is_pointer_v<T>,
		  detail::pointer_atomic<T>,
		  std::conditional_t<std::is_arithmetic_v<T>,
		                     detail::arithmetic_atomic<T>,
		                     std::conditional_t<std::is_enum_v<T>,
		                                        detail::primitive_atomic<T>,
		                                        detail::locked_atomic<T>>>>;
	}; // namespace detail

	/**
	 * Select the correct `atomic` implementation based on the type.
	 */
	template<typename T>
	class atomic : public detail::atomic<T>
	{
		public:
		using detail::atomic<T>::atomic;
		using detail::atomic<T>::operator=;
	};

	template<class T>
	void atomic_store(std::atomic<T> * obj,
	                  typename std::atomic<T>::value_type desired) noexcept
	{
		return obj->store(desired);
	}
	template<class T>
	void atomic_store(volatile std::atomic<T> * obj,
	                  typename std::atomic<T>::value_type desired) noexcept
	{
		return obj->store(desired);
	}
	template<class T>
	void atomic_store_explicit(std::atomic<T> * obj,
	                           typename std::atomic<T>::value_type desired,
	                           std::memory_order order) noexcept
	{
		return obj->store(desired, order);
	}
	template<class T>
	void atomic_store_explicit(volatile std::atomic<T> * obj,
	                           typename std::atomic<T>::value_type desired,
	                           std::memory_order order) noexcept
	{
		return obj->store(desired, order);
	}

	template<class T>
	T atomic_load(const std::atomic<T> *obj) noexcept
	{
		return obj->load();
	}
	template<class T>
	T atomic_load(const volatile std::atomic<T> *obj) noexcept
	{
		return obj->load();
	}
	template<class T>
	T atomic_load_explicit(const std::atomic<T> *obj,
	                       std::memory_order     order) noexcept
	{
		return obj->load(order);
	}
	template<class T>
	T atomic_load_explicit(const volatile std::atomic<T> *obj,
	                       std::memory_order              order) noexcept
	{
		return obj->load(order);
	}

	template<class T>
	T atomic_exchange(std::atomic<T> * obj,
	                  typename std::atomic<T>::value_type desired) noexcept
	{
		return obj->exchange(desired);
	}
	template<class T>
	T atomic_exchange(volatile std::atomic<T> * obj,
	                  typename std::atomic<T>::value_type desired) noexcept
	{
		return obj->exchange(desired);
	}
	template<class T>
	T atomic_exchange_explicit(std::atomic<T> * obj,
	                           typename std::atomic<T>::value_type desired,
	                           std::memory_order order) noexcept
	{
		return obj->exchange(desired, order);
	}
	template<class T>
	T atomic_exchange_explicit(volatile std::atomic<T> * obj,
	                           typename std::atomic<T>::value_type desired,
	                           std::memory_order order) noexcept
	{
		return obj->exchange(desired, order);
	}

	template<class T>
	T atomic_fetch_add(std::atomic<T> * obj,
	                   typename std::atomic<T>::difference_type arg) noexcept
	{
		return obj->fetch_add(arg);
	}
	template<class T>
	T atomic_fetch_add(volatile std::atomic<T> * obj,
	                   typename std::atomic<T>::difference_type arg) noexcept
	{
		return obj->fetch_add(arg);
	}
	template<class T>
	T atomic_fetch_add_explicit(std::atomic<T> * obj,
	                            typename std::atomic<T>::difference_type arg,
	                            std::memory_order order) noexcept
	{
		return obj->fetch_add(arg, order);
	}
	template<class T>
	T atomic_fetch_add_explicit(volatile std::atomic<T> * obj,
	                            typename std::atomic<T>::difference_type arg,
	                            std::memory_order order) noexcept
	{
		return obj->fetch_add(arg, order);
	}

	template<class T>
	T atomic_fetch_sub(std::atomic<T> * obj,
	                   typename std::atomic<T>::difference_type arg) noexcept
	{
		return obj->fetch_sub(arg);
	}
	template<class T>
	T atomic_fetch_sub(volatile std::atomic<T> * obj,
	                   typename std::atomic<T>::difference_type arg) noexcept
	{
		return obj->fetch_sub(arg);
	}
	template<class T>
	T atomic_fetch_sub_explicit(std::atomic<T> * obj,
	                            typename std::atomic<T>::difference_type arg,
	                            std::memory_order order) noexcept
	{
		return obj->fetch_sub(arg, order);
	}
	template<class T>
	T atomic_fetch_sub_explicit(volatile std::atomic<T> * obj,
	                            typename std::atomic<T>::difference_type arg,
	                            std::memory_order order) noexcept
	{
		return obj->fetch_sub(arg, order);
	}

	template<class T>
	T atomic_fetch_and(std::atomic<T> * obj,
	                   typename std::atomic<T>::difference_type arg) noexcept
	{
		return obj->fetch_and(arg);
	}
	template<class T>
	T atomic_fetch_and(volatile std::atomic<T> * obj,
	                   typename std::atomic<T>::difference_type arg) noexcept
	{
		return obj->fetch_and(arg);
	}
	template<class T>
	T atomic_fetch_and_explicit(std::atomic<T> * obj,
	                            typename std::atomic<T>::difference_type arg,
	                            std::memory_order order) noexcept
	{
		return obj->fetch_and(arg, order);
	}
	template<class T>
	T atomic_fetch_and_explicit(volatile std::atomic<T> * obj,
	                            typename std::atomic<T>::difference_type arg,
	                            std::memory_order order) noexcept
	{
		return obj->fetch_and(arg, order);
	}

	template<class T>
	T atomic_fetch_or(std::atomic<T> * obj,
	                  typename std::atomic<T>::difference_type arg) noexcept
	{
		return obj->fetch_or(arg);
	}
	template<class T>
	T atomic_fetch_or(volatile std::atomic<T> * obj,
	                  typename std::atomic<T>::difference_type arg) noexcept
	{
		return obj->fetch_or(arg);
	}
	template<class T>
	T atomic_fetch_or_explicit(std::atomic<T> * obj,
	                           typename std::atomic<T>::difference_type arg,
	                           std::memory_order order) noexcept
	{
		return obj->fetch_or(arg, order);
	}
	template<class T>
	T atomic_fetch_or_explicit(volatile std::atomic<T> * obj,
	                           typename std::atomic<T>::difference_type arg,
	                           std::memory_order order) noexcept
	{
		return obj->fetch_or(arg, order);
	}

	template<class T>
	T atomic_fetch_xor(std::atomic<T> * obj,
	                   typename std::atomic<T>::difference_type arg) noexcept
	{
		return obj->fetch_xor(arg);
	}
	template<class T>
	T atomic_fetch_xor(volatile std::atomic<T> * obj,
	                   typename std::atomic<T>::difference_type arg) noexcept
	{
		return obj->fetch_xor(arg);
	}
	template<class T>
	T atomic_fetch_xor_explicit(std::atomic<T> * obj,
	                            typename std::atomic<T>::difference_type arg,
	                            std::memory_order order) noexcept
	{
		return obj->fetch_xor(arg, order);
	}
	template<class T>
	T atomic_fetch_xor_explicit(volatile std::atomic<T> * obj,
	                            typename std::atomic<T>::difference_type arg,
	                            std::memory_order order) noexcept
	{
		return obj->fetch_xor(arg, order);
	}

	template<class T>
	void atomic_wait(const std::atomic<T>               *object,
	                 typename std::atomic<T>::value_type old)
	{
		object->wait(old);
	}
	template<class T>
	void atomic_wait(const volatile std::atomic<T>      *object,
	                 typename std::atomic<T>::value_type old)
	{
		object->wait(old);
	}
	template<class T>
	void atomic_wait_explicit(const std::atomic<T>               *object,
	                          typename std::atomic<T>::value_type old,
	                          std::memory_order                   order)
	{
		object->wait(old, order);
	}
	template<class T>
	void atomic_wait_explicit(const volatile std::atomic<T>      *object,
	                          typename std::atomic<T>::value_type old,
	                          std::memory_order                   order)
	{
		object->wait(old, order);
	}

	template<class T>
	void atomic_notify_one(std::atomic<T> * object)
	{
		object->notify_one();
	}
	template<class T>
	void atomic_notify_one(volatile std::atomic<T> * object)
	{
		object->notify_one();
	}

	template<class T>
	void atomic_notify_all(std::atomic<T> * object)
	{
		object->notify_all();
	}
	template<class T>
	void atomic_notify_all(volatile std::atomic<T> * object)
	{
		object->notify_all();
	}
} // namespace std

__clang_ignored_warning_pop()
