// 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))
			{
				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))
			{
				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 : 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()
