// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef ABSL_TYPES_INTERNAL_OPTIONAL_H_
#define ABSL_TYPES_INTERNAL_OPTIONAL_H_

#include <functional>
#include <new>
#include <type_traits>
#include <utility>

#include "absl/base/internal/inline_variable.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
#include "absl/utility/utility.h"

// ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
//
// Inheriting constructors is supported in GCC 4.8+, Clang 3.3+ and MSVC 2015.
// __cpp_inheriting_constructors is a predefined macro and a recommended way to
// check for this language feature, but GCC doesn't support it until 5.0 and
// Clang doesn't support it until 3.6.
// Also, MSVC 2015 has a bug: it doesn't inherit the constexpr template
// constructor. For example, the following code won't work on MSVC 2015 Update3:
// struct Base {
//   int t;
//   template <typename T>
//   constexpr Base(T t_) : t(t_) {}
// };
// struct Foo : Base {
//   using Base::Base;
// }
// constexpr Foo foo(0);  // doesn't work on MSVC 2015
#if defined(__clang__)
#if __has_feature(cxx_inheriting_constructors)
#define ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS 1
#endif
#elif (defined(__GNUC__) &&                                       \
       (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 8)) || \
    (__cpp_inheriting_constructors >= 200802) ||                  \
    (defined(_MSC_VER) && _MSC_VER >= 1910)
#define ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS 1
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN

// Forward declaration
template <typename T>
class optional;

namespace optional_internal {

// This tag type is used as a constructor parameter type for `nullopt_t`.
struct init_t {
  explicit init_t() = default;
};

struct empty_struct {};

// This class stores the data in optional<T>.
// It is specialized based on whether T is trivially destructible.
// This is the specialization for non trivially destructible type.
template <typename T, bool unused = std::is_trivially_destructible<T>::value>
class optional_data_dtor_base {
  struct dummy_type {
    static_assert(sizeof(T) % sizeof(empty_struct) == 0, "");
    // Use an array to avoid GCC 6 placement-new warning.
    empty_struct data[sizeof(T) / sizeof(empty_struct)];
  };

 protected:
  // Whether there is data or not.
  bool engaged_;
  // Data storage
  union {
    T data_;
    dummy_type dummy_;
  };

  void destruct() noexcept {
    if (engaged_) {
      // `data_` must be initialized if `engaged_` is true.
#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
      data_.~T();
#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
#pragma GCC diagnostic pop
#endif
      engaged_ = false;
    }
  }

  // dummy_ must be initialized for constexpr constructor.
  constexpr optional_data_dtor_base() noexcept : engaged_(false), dummy_{{}} {}

  template <typename... Args>
  constexpr explicit optional_data_dtor_base(in_place_t, Args&&... args)
      : engaged_(true), data_(absl::forward<Args>(args)...) {}

  ~optional_data_dtor_base() { destruct(); }
};

// Specialization for trivially destructible type.
template <typename T>
class optional_data_dtor_base<T, true> {
  struct dummy_type {
    static_assert(sizeof(T) % sizeof(empty_struct) == 0, "");
    // Use array to avoid GCC 6 placement-new warning.
    empty_struct data[sizeof(T) / sizeof(empty_struct)];
  };

 protected:
  // Whether there is data or not.
  bool engaged_;
  // Data storage
  union {
    T data_;
    dummy_type dummy_;
  };
  void destruct() noexcept { engaged_ = false; }

  // dummy_ must be initialized for constexpr constructor.
  constexpr optional_data_dtor_base() noexcept : engaged_(false), dummy_{{}} {}

  template <typename... Args>
  constexpr explicit optional_data_dtor_base(in_place_t, Args&&... args)
      : engaged_(true), data_(absl::forward<Args>(args)...) {}
};

template <typename T>
class optional_data_base : public optional_data_dtor_base<T> {
 protected:
  using base = optional_data_dtor_base<T>;
#ifdef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
  using base::base;
#else
  optional_data_base() = default;

  template <typename... Args>
  constexpr explicit optional_data_base(in_place_t t, Args&&... args)
      : base(t, absl::forward<Args>(args)...) {}
#endif

  template <typename... Args>
  void construct(Args&&... args) {
    // Use dummy_'s address to work around casting cv-qualified T* to void*.
    ::new (static_cast<void*>(&this->dummy_)) T(std::forward<Args>(args)...);
    this->engaged_ = true;
  }

  template <typename U>
  void assign(U&& u) {
    if (this->engaged_) {
      this->data_ = std::forward<U>(u);
    } else {
      construct(std::forward<U>(u));
    }
  }
};

// TODO(absl-team): Add another class using
// std::is_trivially_move_constructible trait when available to match
// http://cplusplus.github.io/LWG/lwg-defects.html#2900, for types that
// have trivial move but nontrivial copy.
// Also, we should be checking is_trivially_copyable here, which is not
// supported now, so we use is_trivially_* traits instead.
template <typename T,
          bool unused = absl::is_trivially_copy_constructible<T>::value&&
              absl::is_trivially_copy_assignable<typename std::remove_cv<
                  T>::type>::value&& std::is_trivially_destructible<T>::value>
class optional_data;

// Trivially copyable types
template <typename T>
class optional_data<T, true> : public optional_data_base<T> {
 protected:
#ifdef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
  using optional_data_base<T>::optional_data_base;
#else
  optional_data() = default;

  template <typename... Args>
  constexpr explicit optional_data(in_place_t t, Args&&... args)
      : optional_data_base<T>(t, absl::forward<Args>(args)...) {}
#endif
};

template <typename T>
class optional_data<T, false> : public optional_data_base<T> {
 protected:
#ifdef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS
  using optional_data_base<T>::optional_data_base;
#else
  template <typename... Args>
  constexpr explicit optional_data(in_place_t t, Args&&... args)
      : optional_data_base<T>(t, absl::forward<Args>(args)...) {}
#endif

  optional_data() = default;

  optional_data(const optional_data& rhs) : optional_data_base<T>() {
    if (rhs.engaged_) {
      this->construct(rhs.data_);
    }
  }

  optional_data(optional_data&& rhs) noexcept(
      absl::default_allocator_is_nothrow::value ||
      std::is_nothrow_move_constructible<T>::value)
      : optional_data_base<T>() {
    if (rhs.engaged_) {
      this->construct(std::move(rhs.data_));
    }
  }

  optional_data& operator=(const optional_data& rhs) {
    if (rhs.engaged_) {
      this->assign(rhs.data_);
    } else {
      this->destruct();
    }
    return *this;
  }

  optional_data& operator=(optional_data&& rhs) noexcept(
      std::is_nothrow_move_assignable<T>::value&&
          std::is_nothrow_move_constructible<T>::value) {
    if (rhs.engaged_) {
      this->assign(std::move(rhs.data_));
    } else {
      this->destruct();
    }
    return *this;
  }
};

// Ordered by level of restriction, from low to high.
// Copyable implies movable.
enum class copy_traits { copyable = 0, movable = 1, non_movable = 2 };

// Base class for enabling/disabling copy/move constructor.
template <copy_traits>
class optional_ctor_base;

template <>
class optional_ctor_base<copy_traits::copyable> {
 public:
  constexpr optional_ctor_base() = default;
  optional_ctor_base(const optional_ctor_base&) = default;
  optional_ctor_base(optional_ctor_base&&) = default;
  optional_ctor_base& operator=(const optional_ctor_base&) = default;
  optional_ctor_base& operator=(optional_ctor_base&&) = default;
};

template <>
class optional_ctor_base<copy_traits::movable> {
 public:
  constexpr optional_ctor_base() = default;
  optional_ctor_base(const optional_ctor_base&) = delete;
  optional_ctor_base(optional_ctor_base&&) = default;
  optional_ctor_base& operator=(const optional_ctor_base&) = default;
  optional_ctor_base& operator=(optional_ctor_base&&) = default;
};

template <>
class optional_ctor_base<copy_traits::non_movable> {
 public:
  constexpr optional_ctor_base() = default;
  optional_ctor_base(const optional_ctor_base&) = delete;
  optional_ctor_base(optional_ctor_base&&) = delete;
  optional_ctor_base& operator=(const optional_ctor_base&) = default;
  optional_ctor_base& operator=(optional_ctor_base&&) = default;
};

// Base class for enabling/disabling copy/move assignment.
template <copy_traits>
class optional_assign_base;

template <>
class optional_assign_base<copy_traits::copyable> {
 public:
  constexpr optional_assign_base() = default;
  optional_assign_base(const optional_assign_base&) = default;
  optional_assign_base(optional_assign_base&&) = default;
  optional_assign_base& operator=(const optional_assign_base&) = default;
  optional_assign_base& operator=(optional_assign_base&&) = default;
};

template <>
class optional_assign_base<copy_traits::movable> {
 public:
  constexpr optional_assign_base() = default;
  optional_assign_base(const optional_assign_base&) = default;
  optional_assign_base(optional_assign_base&&) = default;
  optional_assign_base& operator=(const optional_assign_base&) = delete;
  optional_assign_base& operator=(optional_assign_base&&) = default;
};

template <>
class optional_assign_base<copy_traits::non_movable> {
 public:
  constexpr optional_assign_base() = default;
  optional_assign_base(const optional_assign_base&) = default;
  optional_assign_base(optional_assign_base&&) = default;
  optional_assign_base& operator=(const optional_assign_base&) = delete;
  optional_assign_base& operator=(optional_assign_base&&) = delete;
};

template <typename T>
struct ctor_copy_traits {
  static constexpr copy_traits traits =
      std::is_copy_constructible<T>::value
          ? copy_traits::copyable
          : std::is_move_constructible<T>::value ? copy_traits::movable
                                                 : copy_traits::non_movable;
};

template <typename T>
struct assign_copy_traits {
  static constexpr copy_traits traits =
      absl::is_copy_assignable<T>::value && std::is_copy_constructible<T>::value
          ? copy_traits::copyable
          : absl::is_move_assignable<T>::value &&
                    std::is_move_constructible<T>::value
                ? copy_traits::movable
                : copy_traits::non_movable;
};

// Whether T is constructible or convertible from optional<U>.
template <typename T, typename U>
struct is_constructible_convertible_from_optional
    : std::integral_constant<
          bool, std::is_constructible<T, optional<U>&>::value ||
                    std::is_constructible<T, optional<U>&&>::value ||
                    std::is_constructible<T, const optional<U>&>::value ||
                    std::is_constructible<T, const optional<U>&&>::value ||
                    std::is_convertible<optional<U>&, T>::value ||
                    std::is_convertible<optional<U>&&, T>::value ||
                    std::is_convertible<const optional<U>&, T>::value ||
                    std::is_convertible<const optional<U>&&, T>::value> {};

// Whether T is constructible or convertible or assignable from optional<U>.
template <typename T, typename U>
struct is_constructible_convertible_assignable_from_optional
    : std::integral_constant<
          bool, is_constructible_convertible_from_optional<T, U>::value ||
                    std::is_assignable<T&, optional<U>&>::value ||
                    std::is_assignable<T&, optional<U>&&>::value ||
                    std::is_assignable<T&, const optional<U>&>::value ||
                    std::is_assignable<T&, const optional<U>&&>::value> {};

// Helper function used by [optional.relops], [optional.comp_with_t],
// for checking whether an expression is convertible to bool.
bool convertible_to_bool(bool);

// Base class for std::hash<absl::optional<T>>:
// If std::hash<std::remove_const_t<T>> is enabled, it provides operator() to
// compute the hash; Otherwise, it is disabled.
// Reference N4659 23.14.15 [unord.hash].
template <typename T, typename = size_t>
struct optional_hash_base {
  optional_hash_base() = delete;
  optional_hash_base(const optional_hash_base&) = delete;
  optional_hash_base(optional_hash_base&&) = delete;
  optional_hash_base& operator=(const optional_hash_base&) = delete;
  optional_hash_base& operator=(optional_hash_base&&) = delete;
};

template <typename T>
struct optional_hash_base<T, decltype(std::hash<absl::remove_const_t<T> >()(
                                 std::declval<absl::remove_const_t<T> >()))> {
  using argument_type = absl::optional<T>;
  using result_type = size_t;
  size_t operator()(const absl::optional<T>& opt) const {
    absl::type_traits_internal::AssertHashEnabled<absl::remove_const_t<T>>();
    if (opt) {
      return std::hash<absl::remove_const_t<T> >()(*opt);
    } else {
      return static_cast<size_t>(0x297814aaad196e6dULL);
    }
  }
};

}  // namespace optional_internal
ABSL_NAMESPACE_END
}  // namespace absl

#undef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS

#endif  // ABSL_TYPES_INTERNAL_OPTIONAL_H_
