// -*- 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___RANGES_COPYABLE_BOX_H
#define _LIBCPP___RANGES_COPYABLE_BOX_H

#include <__config>
#include <__memory/addressof.h>
#include <__memory/construct_at.h>
#include <__utility/move.h>
#include <concepts>
#include <optional>
#include <type_traits>

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

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

#if !defined(_LIBCPP_HAS_NO_RANGES)

// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into
// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state
// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary
// to handle the case where the copy construction fails after destroying the object.
//
// In some cases, we can completely avoid the use of an empty state; we provide a specialization of
// __copyable_box that does this, see below for the details.

template<class _Tp>
concept __copy_constructible_object = copy_constructible<_Tp> && is_object_v<_Tp>;

namespace ranges {
  // Primary template - uses std::optional and introduces an empty state in case assignment fails.
  template<__copy_constructible_object _Tp>
  class __copyable_box {
    [[no_unique_address]] optional<_Tp> __val_;

  public:
    template<class ..._Args>
      requires is_constructible_v<_Tp, _Args...>
    _LIBCPP_HIDE_FROM_ABI
    constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
      noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
      : __val_(in_place, _VSTD::forward<_Args>(__args)...)
    { }

    _LIBCPP_HIDE_FROM_ABI
    constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
      requires default_initializable<_Tp>
      : __val_(in_place)
    { }

    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;

    _LIBCPP_HIDE_FROM_ABI
    constexpr __copyable_box& operator=(__copyable_box const& __other)
      noexcept(is_nothrow_copy_constructible_v<_Tp>)
    {
      if (this != _VSTD::addressof(__other)) {
        if (__other.__has_value()) __val_.emplace(*__other);
        else                       __val_.reset();
      }
      return *this;
    }

    _LIBCPP_HIDE_FROM_ABI
    __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;

    _LIBCPP_HIDE_FROM_ABI
    constexpr __copyable_box& operator=(__copyable_box&& __other)
      noexcept(is_nothrow_move_constructible_v<_Tp>)
    {
      if (this != _VSTD::addressof(__other)) {
        if (__other.__has_value()) __val_.emplace(_VSTD::move(*__other));
        else                       __val_.reset();
      }
      return *this;
    }

    _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; }
    _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; }
    _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); }
  };

  // This partial specialization implements an optimization for when we know we don't need to store
  // an empty state to represent failure to perform an assignment. For copy-assignment, this happens:
  //
  // 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator
  //    directly and avoid using std::optional.
  // 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as
  //    destroy-and-then-construct and we know it will never fail, so we don't need an empty state.
  //
  // The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and
  // nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled
  // whenever we can apply any of these optimizations for both the copy assignment and the move assignment
  // operator.
  template<class _Tp>
  concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>;

  template<class _Tp>
  concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>;

  template<__copy_constructible_object _Tp>
    requires __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>
  class __copyable_box<_Tp> {
    [[no_unique_address]] _Tp __val_;

  public:
    template<class ..._Args>
      requires is_constructible_v<_Tp, _Args...>
    _LIBCPP_HIDE_FROM_ABI
    constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
      noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
      : __val_(_VSTD::forward<_Args>(__args)...)
    { }

    _LIBCPP_HIDE_FROM_ABI
    constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
      requires default_initializable<_Tp>
      : __val_()
    { }

    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;

    // Implementation of assignment operators in case we perform optimization (1)
    _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box const&) requires copyable<_Tp> = default;
    _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;

    // Implementation of assignment operators in case we perform optimization (2)
    _LIBCPP_HIDE_FROM_ABI
    constexpr __copyable_box& operator=(__copyable_box const& __other) noexcept {
      static_assert(is_nothrow_copy_constructible_v<_Tp>);
      if (this != _VSTD::addressof(__other)) {
        _VSTD::destroy_at(_VSTD::addressof(__val_));
        _VSTD::construct_at(_VSTD::addressof(__val_), __other.__val_);
      }
      return *this;
    }

    _LIBCPP_HIDE_FROM_ABI
    constexpr __copyable_box& operator=(__copyable_box&& __other) noexcept {
      static_assert(is_nothrow_move_constructible_v<_Tp>);
      if (this != _VSTD::addressof(__other)) {
        _VSTD::destroy_at(_VSTD::addressof(__val_));
        _VSTD::construct_at(_VSTD::addressof(__val_), _VSTD::move(__other.__val_));
      }
      return *this;
    }

    _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; }
    _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; }
    _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
  };
} // namespace ranges

#endif // !defined(_LIBCPP_HAS_NO_RANGES)

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___RANGES_COPYABLE_BOX_H
