// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___NODE_HANDLE
#define _LIBCPP___NODE_HANDLE

/*

template<unspecified>
class node-handle {
public:
  using value_type     = see below;     // not present for map containers
  using key_type       = see below;     // not present for set containers
  using mapped_type    = see below;     // not present for set containers
  using allocator_type = see below;

private:
  using container_node_type = unspecified;                  // exposition only
  using ator_traits = allocator_traits<allocator_type>;     // exposition only

  typename ator_traits::template
    rebind_traits<container_node_type>::pointer ptr_;       // exposition only
  optional<allocator_type> alloc_;                          // exposition only

public:
  // [container.node.cons], constructors, copy, and assignment
  constexpr node-handle() noexcept : ptr_(), alloc_() {}
  node-handle(node-handle&&) noexcept;
  node-handle& operator=(node-handle&&);

  // [container.node.dtor], destructor
  ~node-handle();

  // [container.node.observers], observers
  value_type& value() const;            // not present for map containers
  key_type& key() const;                // not present for set containers
  mapped_type& mapped() const;          // not present for set containers

  allocator_type get_allocator() const;
  explicit operator bool() const noexcept;
  [[nodiscard]] bool empty() const noexcept; // nodiscard since C++20

  // [container.node.modifiers], modifiers
  void swap(node-handle&)
    noexcept(ator_traits::propagate_on_container_swap::value ||
             ator_traits::is_always_equal::value);

  friend void swap(node-handle& x, node-handle& y) noexcept(noexcept(x.swap(y))) {
    x.swap(y);
  }
};

*/

#include <__assert>
#include <__config>
#include <__memory/allocator_traits.h>
#include <__memory/pointer_traits.h>
#include <optional>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

#if _LIBCPP_STD_VER >= 17

// Specialized in __tree & __hash_table for their _NodeType.
template <class _NodeType, class _Alloc>
struct __generic_container_node_destructor;

template <class _NodeType, class _Alloc, template <class, class> class _MapOrSetSpecifics>
class _LIBCPP_TEMPLATE_VIS __basic_node_handle
    : public _MapOrSetSpecifics< _NodeType, __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>> {
  template <class _Tp, class _Compare, class _Allocator>
  friend class __tree;
  template <class _Tp, class _Hash, class _Equal, class _Allocator>
  friend class __hash_table;
  friend struct _MapOrSetSpecifics< _NodeType, __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>;

  typedef allocator_traits<_Alloc> __alloc_traits;
  typedef __rebind_pointer_t<typename __alloc_traits::void_pointer, _NodeType> __node_pointer_type;

public:
  typedef _Alloc allocator_type;

private:
  __node_pointer_type __ptr_ = nullptr;
  optional<allocator_type> __alloc_;

  _LIBCPP_HIDE_FROM_ABI void __release_ptr() {
    __ptr_   = nullptr;
    __alloc_ = std::nullopt;
  }

  _LIBCPP_HIDE_FROM_ABI void __destroy_node_pointer() {
    if (__ptr_ != nullptr) {
      typedef typename __allocator_traits_rebind< allocator_type, _NodeType>::type __node_alloc_type;
      __node_alloc_type __alloc(*__alloc_);
      __generic_container_node_destructor<_NodeType, __node_alloc_type>(__alloc, true)(__ptr_);
      __ptr_ = nullptr;
    }
  }

  _LIBCPP_HIDE_FROM_ABI __basic_node_handle(__node_pointer_type __ptr, allocator_type const& __alloc)
      : __ptr_(__ptr), __alloc_(__alloc) {}

public:
  _LIBCPP_HIDE_FROM_ABI __basic_node_handle() = default;

  _LIBCPP_HIDE_FROM_ABI __basic_node_handle(__basic_node_handle&& __other) noexcept
      : __ptr_(__other.__ptr_), __alloc_(std::move(__other.__alloc_)) {
    __other.__ptr_   = nullptr;
    __other.__alloc_ = std::nullopt;
  }

  _LIBCPP_HIDE_FROM_ABI __basic_node_handle& operator=(__basic_node_handle&& __other) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
        __alloc_ == std::nullopt || __alloc_traits::propagate_on_container_move_assignment::value ||
            __alloc_ == __other.__alloc_,
        "node_type with incompatible allocator passed to "
        "node_type::operator=(node_type&&)");

    __destroy_node_pointer();
    __ptr_ = __other.__ptr_;

    if (__alloc_traits::propagate_on_container_move_assignment::value || __alloc_ == std::nullopt)
      __alloc_ = std::move(__other.__alloc_);

    __other.__ptr_   = nullptr;
    __other.__alloc_ = std::nullopt;

    return *this;
  }

  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return *__alloc_; }

  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const { return __ptr_ != nullptr; }

  _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool empty() const { return __ptr_ == nullptr; }

  _LIBCPP_HIDE_FROM_ABI void swap(__basic_node_handle& __other) noexcept(
      __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value) {
    using std::swap;
    swap(__ptr_, __other.__ptr_);
    if (__alloc_traits::propagate_on_container_swap::value || __alloc_ == std::nullopt ||
        __other.__alloc_ == std::nullopt)
      swap(__alloc_, __other.__alloc_);
  }

  _LIBCPP_HIDE_FROM_ABI friend void
  swap(__basic_node_handle& __a, __basic_node_handle& __b) noexcept(noexcept(__a.swap(__b))) {
    __a.swap(__b);
  }

  _LIBCPP_HIDE_FROM_ABI ~__basic_node_handle() { __destroy_node_pointer(); }
};

template <class _NodeType, class _Derived>
struct __set_node_handle_specifics {
  typedef typename _NodeType::__node_value_type value_type;

  _LIBCPP_HIDE_FROM_ABI value_type& value() const { return static_cast<_Derived const*>(this)->__ptr_->__get_value(); }
};

template <class _NodeType, class _Derived>
struct __map_node_handle_specifics {
  typedef typename _NodeType::__node_value_type::key_type key_type;
  typedef typename _NodeType::__node_value_type::mapped_type mapped_type;

  _LIBCPP_HIDE_FROM_ABI key_type& key() const {
    return static_cast<_Derived const*>(this)->__ptr_->__get_value().__ref().first;
  }

  _LIBCPP_HIDE_FROM_ABI mapped_type& mapped() const {
    return static_cast<_Derived const*>(this)->__ptr_->__get_value().__ref().second;
  }
};

template <class _NodeType, class _Alloc>
using __set_node_handle = __basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>;

template <class _NodeType, class _Alloc>
using __map_node_handle = __basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>;

template <class _Iterator, class _NodeType>
struct _LIBCPP_TEMPLATE_VIS __insert_return_type {
  _Iterator position;
  bool inserted;
  _NodeType node;
};

#endif // _LIBCPP_STD_VER >= 17

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___NODE_HANDLE
