// shared_ptr atomic access -*- C++ -*-

// Copyright (C) 2014-2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file bits/shared_ptr_atomic.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{memory}
 */

#ifndef _SHARED_PTR_ATOMIC_H
#define _SHARED_PTR_ATOMIC_H 1

#include <bits/atomic_base.h>

// Annotations for the custom locking in atomic<shared_ptr<T>>.
#if defined _GLIBCXX_TSAN && __has_include(<sanitizer/tsan_interface.h>)
#include <sanitizer/tsan_interface.h>
#define _GLIBCXX_TSAN_MUTEX_DESTROY(X) \
  __tsan_mutex_destroy(X, __tsan_mutex_not_static)
#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK(X) \
  __tsan_mutex_pre_lock(X, __tsan_mutex_not_static|__tsan_mutex_try_lock)
#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(X) __tsan_mutex_post_lock(X, \
    __tsan_mutex_not_static|__tsan_mutex_try_lock_failed, 0)
#define _GLIBCXX_TSAN_MUTEX_LOCKED(X) \
  __tsan_mutex_post_lock(X, __tsan_mutex_not_static, 0)
#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) __tsan_mutex_pre_unlock(X, 0)
#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) __tsan_mutex_post_unlock(X, 0)
#define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) __tsan_mutex_pre_signal(X, 0)
#define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X) __tsan_mutex_post_signal(X, 0)
#else
#define _GLIBCXX_TSAN_MUTEX_DESTROY(X)
#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK(X)
#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(X)
#define _GLIBCXX_TSAN_MUTEX_LOCKED(X)
#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X)
#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X)
#define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X)
#define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X)
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * @addtogroup pointer_abstractions
   * @relates shared_ptr
   * @{
   */

  /// @cond undocumented

  struct _Sp_locker
  {
    _Sp_locker(const _Sp_locker&) = delete;
    _Sp_locker& operator=(const _Sp_locker&) = delete;

#ifdef __GTHREADS
    explicit
    _Sp_locker(const void*) noexcept;
    _Sp_locker(const void*, const void*) noexcept;
    ~_Sp_locker();

  private:
    unsigned char _M_key1;
    unsigned char _M_key2;
#else
    explicit _Sp_locker(const void*, const void* = nullptr) { }
#endif
  };

  /// @endcond

  /**
   *  @brief  Report whether shared_ptr atomic operations are lock-free.
   *  @param  __p A non-null pointer to a shared_ptr object.
   *  @return True if atomic access to @c *__p is lock-free, false otherwise.
   *  @{
  */
  template<typename _Tp, _Lock_policy _Lp>
    inline bool
    atomic_is_lock_free(const __shared_ptr<_Tp, _Lp>* __p)
    {
#ifdef __GTHREADS
      return __gthread_active_p() == 0;
#else
      return true;
#endif
    }

  template<typename _Tp>
    inline bool
    atomic_is_lock_free(const shared_ptr<_Tp>* __p)
    { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }

  /// @}

  /**
   *  @brief  Atomic load for shared_ptr objects.
   *  @param  __p A non-null pointer to a shared_ptr object.
   *  @return @c *__p
   *
   *  The memory order shall not be `memory_order_release` or
   *  `memory_order_acq_rel`.
   *  @{
  */
  template<typename _Tp>
    inline shared_ptr<_Tp>
    atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
    {
      _Sp_locker __lock{__p};
      return *__p;
    }

  template<typename _Tp>
    inline shared_ptr<_Tp>
    atomic_load(const shared_ptr<_Tp>* __p)
    { return std::atomic_load_explicit(__p, memory_order_seq_cst); }

  template<typename _Tp, _Lock_policy _Lp>
    inline __shared_ptr<_Tp, _Lp>
    atomic_load_explicit(const __shared_ptr<_Tp, _Lp>* __p, memory_order)
    {
      _Sp_locker __lock{__p};
      return *__p;
    }

  template<typename _Tp, _Lock_policy _Lp>
    inline __shared_ptr<_Tp, _Lp>
    atomic_load(const __shared_ptr<_Tp, _Lp>* __p)
    { return std::atomic_load_explicit(__p, memory_order_seq_cst); }
  /// @}

  /**
   *  @brief  Atomic store for shared_ptr objects.
   *  @param  __p A non-null pointer to a shared_ptr object.
   *  @param  __r The value to store.
   *
   *  The memory order shall not be `memory_order_acquire` or
   *  `memory_order_acq_rel`.
   *  @{
  */
  template<typename _Tp>
    inline void
    atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r,
			  memory_order)
    {
      _Sp_locker __lock{__p};
      __p->swap(__r); // use swap so that **__p not destroyed while lock held
    }

  template<typename _Tp>
    inline void
    atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
    { std::atomic_store_explicit(__p, std::move(__r), memory_order_seq_cst); }

  template<typename _Tp, _Lock_policy _Lp>
    inline void
    atomic_store_explicit(__shared_ptr<_Tp, _Lp>* __p,
			  __shared_ptr<_Tp, _Lp> __r,
			  memory_order)
    {
      _Sp_locker __lock{__p};
      __p->swap(__r); // use swap so that **__p not destroyed while lock held
    }

  template<typename _Tp, _Lock_policy _Lp>
    inline void
    atomic_store(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp> __r)
    { std::atomic_store_explicit(__p, std::move(__r), memory_order_seq_cst); }
  /// @}

  /**
   *  @brief  Atomic exchange for shared_ptr objects.
   *  @param  __p A non-null pointer to a shared_ptr object.
   *  @param  __r New value to store in `*__p`.
   *  @return The original value of `*__p`
   *  @{
  */
  template<typename _Tp>
    inline shared_ptr<_Tp>
    atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r,
			     memory_order)
    {
      _Sp_locker __lock{__p};
      __p->swap(__r);
      return __r;
    }

  template<typename _Tp>
    inline shared_ptr<_Tp>
    atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
    {
      return std::atomic_exchange_explicit(__p, std::move(__r),
					   memory_order_seq_cst);
    }

  template<typename _Tp, _Lock_policy _Lp>
    inline __shared_ptr<_Tp, _Lp>
    atomic_exchange_explicit(__shared_ptr<_Tp, _Lp>* __p,
			     __shared_ptr<_Tp, _Lp> __r,
			     memory_order)
    {
      _Sp_locker __lock{__p};
      __p->swap(__r);
      return __r;
    }

  template<typename _Tp, _Lock_policy _Lp>
    inline __shared_ptr<_Tp, _Lp>
    atomic_exchange(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp> __r)
    {
      return std::atomic_exchange_explicit(__p, std::move(__r),
					   memory_order_seq_cst);
    }
  /// @}

  /**
   *  @brief  Atomic compare-and-swap for shared_ptr objects.
   *  @param  __p A non-null pointer to a shared_ptr object.
   *  @param  __v A non-null pointer to a shared_ptr object.
   *  @param  __w A non-null pointer to a shared_ptr object.
   *  @return True if `*__p` was equivalent to `*__v`, false otherwise.
   *
   *  The memory order for failure shall not be `memory_order_release` or
   *  `memory_order_acq_rel`.
   *  @{
  */
  template<typename _Tp>
    bool
    atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
					    shared_ptr<_Tp>* __v,
					    shared_ptr<_Tp> __w,
					    memory_order,
					    memory_order)
    {
      shared_ptr<_Tp> __x; // goes out of scope after __lock
      _Sp_locker __lock{__p, __v};
      owner_less<shared_ptr<_Tp>> __less;
      if (*__p == *__v && !__less(*__p, *__v) && !__less(*__v, *__p))
	{
	  __x = std::move(*__p);
	  *__p = std::move(__w);
	  return true;
	}
      __x = std::move(*__v);
      *__v = *__p;
      return false;
    }

  template<typename _Tp>
    inline bool
    atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
				 shared_ptr<_Tp> __w)
    {
      return std::atomic_compare_exchange_strong_explicit(__p, __v,
	  std::move(__w), memory_order_seq_cst, memory_order_seq_cst);
    }

  template<typename _Tp>
    inline bool
    atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
					  shared_ptr<_Tp>* __v,
					  shared_ptr<_Tp> __w,
					  memory_order __success,
					  memory_order __failure)
    {
      return std::atomic_compare_exchange_strong_explicit(__p, __v,
	  std::move(__w), __success, __failure);
    }

  template<typename _Tp>
    inline bool
    atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
				 shared_ptr<_Tp> __w)
    {
      return std::atomic_compare_exchange_weak_explicit(__p, __v,
	  std::move(__w), memory_order_seq_cst, memory_order_seq_cst);
    }

  template<typename _Tp, _Lock_policy _Lp>
    bool
    atomic_compare_exchange_strong_explicit(__shared_ptr<_Tp, _Lp>* __p,
					    __shared_ptr<_Tp, _Lp>* __v,
					    __shared_ptr<_Tp, _Lp> __w,
					    memory_order,
					    memory_order)
    {
      __shared_ptr<_Tp, _Lp> __x; // goes out of scope after __lock
      _Sp_locker __lock{__p, __v};
      owner_less<__shared_ptr<_Tp, _Lp>> __less;
      if (*__p == *__v && !__less(*__p, *__v) && !__less(*__v, *__p))
	{
	  __x = std::move(*__p);
	  *__p = std::move(__w);
	  return true;
	}
      __x = std::move(*__v);
      *__v = *__p;
      return false;
    }

  template<typename _Tp, _Lock_policy _Lp>
    inline bool
    atomic_compare_exchange_strong(__shared_ptr<_Tp, _Lp>* __p,
				   __shared_ptr<_Tp, _Lp>* __v,
				   __shared_ptr<_Tp, _Lp> __w)
    {
      return std::atomic_compare_exchange_strong_explicit(__p, __v,
	  std::move(__w), memory_order_seq_cst, memory_order_seq_cst);
    }

  template<typename _Tp, _Lock_policy _Lp>
    inline bool
    atomic_compare_exchange_weak_explicit(__shared_ptr<_Tp, _Lp>* __p,
					  __shared_ptr<_Tp, _Lp>* __v,
					  __shared_ptr<_Tp, _Lp> __w,
					  memory_order __success,
					  memory_order __failure)
    {
      return std::atomic_compare_exchange_strong_explicit(__p, __v,
	  std::move(__w), __success, __failure);
    }

  template<typename _Tp, _Lock_policy _Lp>
    inline bool
    atomic_compare_exchange_weak(__shared_ptr<_Tp, _Lp>* __p,
				 __shared_ptr<_Tp, _Lp>* __v,
				 __shared_ptr<_Tp, _Lp> __w)
    {
      return std::atomic_compare_exchange_weak_explicit(__p, __v,
	  std::move(__w), memory_order_seq_cst, memory_order_seq_cst);
    }
  /// @}

  /// @} group pointer_abstractions

#if __cplusplus >= 202002L
# define __cpp_lib_atomic_shared_ptr 201711L
  template<typename _Tp>
    class atomic;

  /**
   * @addtogroup pointer_abstractions
   * @relates shared_ptr
   * @{
   */

  template<typename _Up>
    static constexpr bool __is_shared_ptr = false;
  template<typename _Up>
    static constexpr bool __is_shared_ptr<shared_ptr<_Up>> = true;

  template<typename _Tp>
    class _Sp_atomic
    {
      using value_type = _Tp;

      friend class atomic<_Tp>;

      // An atomic version of __shared_count<> and __weak_count<>.
      // Stores a _Sp_counted_base<>* but uses the LSB as a lock.
      struct _Atomic_count
      {
	// Either __shared_count<> or __weak_count<>
	using __count_type = decltype(_Tp::_M_refcount);

	// _Sp_counted_base<>*
	using pointer = decltype(__count_type::_M_pi);

	// Ensure we can use the LSB as the lock bit.
	static_assert(alignof(remove_pointer_t<pointer>) > 1);

	constexpr _Atomic_count() noexcept = default;

	explicit
	_Atomic_count(__count_type&& __c) noexcept
	: _M_val(reinterpret_cast<uintptr_t>(__c._M_pi))
	{
	  __c._M_pi = nullptr;
	}

	~_Atomic_count()
	{
	  auto __val = _M_val.load(memory_order_relaxed);
	  _GLIBCXX_TSAN_MUTEX_DESTROY(&_M_val);
	  __glibcxx_assert(!(__val & _S_lock_bit));
	  if (auto __pi = reinterpret_cast<pointer>(__val))
	    {
	      if constexpr (__is_shared_ptr<_Tp>)
		__pi->_M_release();
	      else
		__pi->_M_weak_release();
	    }
	}

	_Atomic_count(const _Atomic_count&) = delete;
	_Atomic_count& operator=(const _Atomic_count&) = delete;

	// Precondition: Caller does not hold lock!
	// Returns the raw pointer value without the lock bit set.
	pointer
	lock(memory_order __o) const noexcept
	{
	  // To acquire the lock we flip the LSB from 0 to 1.

	  auto __current = _M_val.load(memory_order_relaxed);
	  while (__current & _S_lock_bit)
	    {
#if __cpp_lib_atomic_wait
	      __detail::__thread_relax();
#endif
	      __current = _M_val.load(memory_order_relaxed);
	    }

	  _GLIBCXX_TSAN_MUTEX_TRY_LOCK(&_M_val);

	  while (!_M_val.compare_exchange_strong(__current,
						 __current | _S_lock_bit,
						 __o,
						 memory_order_relaxed))
	    {
	      _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(&_M_val);
#if __cpp_lib_atomic_wait
	      __detail::__thread_relax();
#endif
	      __current = __current & ~_S_lock_bit;
	      _GLIBCXX_TSAN_MUTEX_TRY_LOCK(&_M_val);
	    }
	  _GLIBCXX_TSAN_MUTEX_LOCKED(&_M_val);
	  return reinterpret_cast<pointer>(__current);
	}

	// Precondition: caller holds lock!
	void
	unlock(memory_order __o) const noexcept
	{
	  _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val);
	  _M_val.fetch_sub(1, __o);
	  _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val);
	}

	// Swaps the values of *this and __c, and unlocks *this.
	// Precondition: caller holds lock!
	void
	_M_swap_unlock(__count_type& __c, memory_order __o) noexcept
	{
	  if (__o != memory_order_seq_cst)
	    __o = memory_order_release;
	  auto __x = reinterpret_cast<uintptr_t>(__c._M_pi);
	  _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val);
	  __x = _M_val.exchange(__x, __o);
	  _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val);
	  __c._M_pi = reinterpret_cast<pointer>(__x & ~_S_lock_bit);
	}

#if __cpp_lib_atomic_wait
	// Precondition: caller holds lock!
	void
	_M_wait_unlock(memory_order __o) const noexcept
	{
	  _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val);
	  auto __v = _M_val.fetch_sub(1, memory_order_relaxed);
	  _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val);
	  _M_val.wait(__v & ~_S_lock_bit, __o);
	}

	void
	notify_one() noexcept
	{
	  _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(&_M_val);
	  _M_val.notify_one();
	  _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(&_M_val);
	}

	void
	notify_all() noexcept
	{
	  _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(&_M_val);
	  _M_val.notify_all();
	  _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(&_M_val);
	}
#endif

      private:
	mutable __atomic_base<uintptr_t> _M_val{0};
	static constexpr uintptr_t _S_lock_bit{1};
      };

      typename _Tp::element_type* _M_ptr = nullptr;
      _Atomic_count _M_refcount;

      static typename _Atomic_count::pointer
      _S_add_ref(typename _Atomic_count::pointer __p)
      {
	if (__p)
	  {
	    if constexpr (__is_shared_ptr<_Tp>)
	      __p->_M_add_ref_copy();
	    else
	      __p->_M_weak_add_ref();
	  }
	return __p;
      }

      constexpr _Sp_atomic() noexcept = default;

      explicit
      _Sp_atomic(value_type __r) noexcept
      : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
      { }

      ~_Sp_atomic() = default;

      _Sp_atomic(const _Sp_atomic&) = delete;
      void operator=(const _Sp_atomic&) = delete;

      value_type
      load(memory_order __o) const noexcept
      {
	__glibcxx_assert(__o != memory_order_release
			   && __o != memory_order_acq_rel);
	// Ensure that the correct value of _M_ptr is visible after locking.,
	// by upgrading relaxed or consume to acquire.
	if (__o != memory_order_seq_cst)
	  __o = memory_order_acquire;

	value_type __ret;
	auto __pi = _M_refcount.lock(__o);
	__ret._M_ptr = _M_ptr;
	__ret._M_refcount._M_pi = _S_add_ref(__pi);
	_M_refcount.unlock(memory_order_relaxed);
	return __ret;
      }

      void
      swap(value_type& __r, memory_order __o) noexcept
      {
	_M_refcount.lock(memory_order_acquire);
	std::swap(_M_ptr, __r._M_ptr);
	_M_refcount._M_swap_unlock(__r._M_refcount, __o);
      }

      bool
      compare_exchange_strong(value_type& __expected, value_type __desired,
			      memory_order __o, memory_order __o2) noexcept
      {
	bool __result = true;
	auto __pi = _M_refcount.lock(memory_order_acquire);
	if (_M_ptr == __expected._M_ptr
	      && __pi == __expected._M_refcount._M_pi)
	  {
	    _M_ptr = __desired._M_ptr;
	    _M_refcount._M_swap_unlock(__desired._M_refcount, __o);
	  }
	else
	  {
	    _Tp __sink = std::move(__expected);
	    __expected._M_ptr = _M_ptr;
	    __expected._M_refcount._M_pi = _S_add_ref(__pi);
	    _M_refcount.unlock(__o2);
	    __result = false;
	  }
	return __result;
      }

#if __cpp_lib_atomic_wait
      void
      wait(value_type __old, memory_order __o) const noexcept
      {
	auto __pi = _M_refcount.lock(memory_order_acquire);
	if (_M_ptr == __old._M_ptr && __pi == __old._M_refcount._M_pi)
	  _M_refcount._M_wait_unlock(__o);
	else
	  _M_refcount.unlock(memory_order_relaxed);
      }

      void
      notify_one() noexcept
      {
	_M_refcount.notify_one();
      }

      void
      notify_all() noexcept
      {
	_M_refcount.notify_all();
      }
#endif
    };

  template<typename _Tp>
    class atomic<shared_ptr<_Tp>>
    {
    public:
      using value_type = shared_ptr<_Tp>;

      static constexpr bool is_always_lock_free = false;

      bool
      is_lock_free() const noexcept
      { return false; }

      constexpr atomic() noexcept = default;

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3661. constinit atomic<shared_ptr<T>> a(nullptr); should work
      constexpr atomic(nullptr_t) noexcept : atomic() { }

      atomic(shared_ptr<_Tp> __r) noexcept
      : _M_impl(std::move(__r))
      { }

      atomic(const atomic&) = delete;
      void operator=(const atomic&) = delete;

      shared_ptr<_Tp>
      load(memory_order __o = memory_order_seq_cst) const noexcept
      { return _M_impl.load(__o); }

      operator shared_ptr<_Tp>() const noexcept
      { return _M_impl.load(memory_order_seq_cst); }

      void
      store(shared_ptr<_Tp> __desired,
	    memory_order __o = memory_order_seq_cst) noexcept
      { _M_impl.swap(__desired, __o); }

      void
      operator=(shared_ptr<_Tp> __desired) noexcept
      { _M_impl.swap(__desired, memory_order_seq_cst); }

      shared_ptr<_Tp>
      exchange(shared_ptr<_Tp> __desired,
	       memory_order __o = memory_order_seq_cst) noexcept
      {
	_M_impl.swap(__desired, __o);
	return __desired;
      }

      bool
      compare_exchange_strong(shared_ptr<_Tp>& __expected,
			      shared_ptr<_Tp> __desired,
			      memory_order __o, memory_order __o2) noexcept
      {
	return _M_impl.compare_exchange_strong(__expected, __desired, __o, __o2);
      }

      bool
      compare_exchange_strong(value_type& __expected, value_type __desired,
			      memory_order __o = memory_order_seq_cst) noexcept
      {
	memory_order __o2;
	switch (__o)
	{
	case memory_order_acq_rel:
	  __o2 = memory_order_acquire;
	  break;
	case memory_order_release:
	  __o2 = memory_order_relaxed;
	  break;
	default:
	  __o2 = __o;
	}
	return compare_exchange_strong(__expected, std::move(__desired),
				       __o, __o2);
      }

      bool
      compare_exchange_weak(value_type& __expected, value_type __desired,
			    memory_order __o, memory_order __o2) noexcept
      {
	return compare_exchange_strong(__expected, std::move(__desired),
				       __o, __o2);
      }

      bool
      compare_exchange_weak(value_type& __expected, value_type __desired,
			    memory_order __o = memory_order_seq_cst) noexcept
      {
	return compare_exchange_strong(__expected, std::move(__desired), __o);
      }

#if __cpp_lib_atomic_wait
      void
      wait(value_type __old,
	   memory_order __o = memory_order_seq_cst) const noexcept
      {
	_M_impl.wait(std::move(__old), __o);
      }

      void
      notify_one() noexcept
      {
	_M_impl.notify_one();
      }

      void
      notify_all() noexcept
      {
	_M_impl.notify_all();
      }
#endif

    private:
      _Sp_atomic<shared_ptr<_Tp>> _M_impl;
    };

  template<typename _Tp>
    class atomic<weak_ptr<_Tp>>
    {
    public:
      using value_type = weak_ptr<_Tp>;

      static constexpr bool is_always_lock_free = false;

      bool
      is_lock_free() const noexcept
      { return false; }

      constexpr atomic() noexcept = default;

      atomic(weak_ptr<_Tp> __r) noexcept
     : _M_impl(move(__r))
      { }

      atomic(const atomic&) = delete;
      void operator=(const atomic&) = delete;

      weak_ptr<_Tp>
      load(memory_order __o = memory_order_seq_cst) const noexcept
      { return _M_impl.load(__o); }

      operator weak_ptr<_Tp>() const noexcept
      { return _M_impl.load(memory_order_seq_cst); }

      void
      store(weak_ptr<_Tp> __desired,
	    memory_order __o = memory_order_seq_cst) noexcept
      { _M_impl.swap(__desired, __o); }

      void
      operator=(weak_ptr<_Tp> __desired) noexcept
      { _M_impl.swap(__desired, memory_order_seq_cst); }

      weak_ptr<_Tp>
      exchange(weak_ptr<_Tp> __desired,
	       memory_order __o = memory_order_seq_cst) noexcept
      {
	_M_impl.swap(__desired, __o);
	return __desired;
      }

      bool
      compare_exchange_strong(weak_ptr<_Tp>& __expected,
			      weak_ptr<_Tp> __desired,
			      memory_order __o, memory_order __o2) noexcept
      {
	return _M_impl.compare_exchange_strong(__expected, __desired, __o, __o2);
      }

      bool
      compare_exchange_strong(value_type& __expected, value_type __desired,
			      memory_order __o = memory_order_seq_cst) noexcept
      {
	memory_order __o2;
	switch (__o)
	{
	case memory_order_acq_rel:
	  __o2 = memory_order_acquire;
	  break;
	case memory_order_release:
	  __o2 = memory_order_relaxed;
	  break;
	default:
	  __o2 = __o;
	}
	return compare_exchange_strong(__expected, std::move(__desired),
				       __o, __o2);
      }

      bool
      compare_exchange_weak(value_type& __expected, value_type __desired,
			    memory_order __o, memory_order __o2) noexcept
      {
	return compare_exchange_strong(__expected, std::move(__desired),
				       __o, __o2);
      }

      bool
      compare_exchange_weak(value_type& __expected, value_type __desired,
			    memory_order __o = memory_order_seq_cst) noexcept
      {
	return compare_exchange_strong(__expected, std::move(__desired), __o);
      }

#if __cpp_lib_atomic_wait
      void
      wait(value_type __old,
	   memory_order __o = memory_order_seq_cst) const noexcept
      {
	_M_impl.wait(std::move(__old), __o);
      }

      void
      notify_one() noexcept
      {
	_M_impl.notify_one();
      }

      void
      notify_all() noexcept
      {
	_M_impl.notify_all();
      }
#endif

    private:
      _Sp_atomic<weak_ptr<_Tp>> _M_impl;
    };
  /// @} group pointer_abstractions
#endif // C++20

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif // _SHARED_PTR_ATOMIC_H
