//
// 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.
//
// -----------------------------------------------------------------------------
// any.h
// -----------------------------------------------------------------------------
//
// This header file define the `absl::any` type for holding a type-safe value
// of any type. The 'absl::any` type is useful for providing a way to hold
// something that is, as yet, unspecified. Such unspecified types
// traditionally are passed between API boundaries until they are later cast to
// their "destination" types. To cast to such a destination type, use
// `absl::any_cast()`. Note that when casting an `absl::any`, you must cast it
// to an explicit type; implicit conversions will throw.
//
// Example:
//
//   auto a = absl::any(65);
//   absl::any_cast<int>(a);         // 65
//   absl::any_cast<char>(a);        // throws absl::bad_any_cast
//   absl::any_cast<std::string>(a); // throws absl::bad_any_cast
//
// `absl::any` is a C++11 compatible version of the C++17 `std::any` abstraction
// and is designed to be a drop-in replacement for code compliant with C++17.
//
// Traditionally, the behavior of casting to a temporary unspecified type has
// been accomplished with the `void *` paradigm, where the pointer was to some
// other unspecified type. `absl::any` provides an "owning" version of `void *`
// that avoids issues of pointer management.
//
// Note: just as in the case of `void *`, use of `absl::any` (and its C++17
// version `std::any`) is a code smell indicating that your API might not be
// constructed correctly. We have seen that most uses of `any` are unwarranted,
// and `absl::any`, like `std::any`, is difficult to use properly. Before using
// this abstraction, make sure that you should not instead be rewriting your
// code to be more specific.
//
// Abseil expects to release an `absl::variant` type shortly (a C++11 compatible
// version of the C++17 `std::variant), which is generally preferred for use
// over `absl::any`.
#ifndef ABSL_TYPES_ANY_H_
#define ABSL_TYPES_ANY_H_

#include "absl/base/config.h"
#include "absl/utility/utility.h"

#ifdef ABSL_HAVE_STD_ANY

#include <any>  // IWYU pragma: export

namespace absl {
inline namespace lts_2019_08_08 {
using std::any;
using std::any_cast;
using std::bad_any_cast;
using std::make_any;
}  // inline namespace lts_2019_08_08
}  // namespace absl

#else  // ABSL_HAVE_STD_ANY

#include <algorithm>
#include <cstddef>
#include <initializer_list>
#include <memory>
#include <stdexcept>
#include <type_traits>
#include <typeinfo>
#include <utility>

#include "absl/base/macros.h"
#include "absl/meta/type_traits.h"
#include "absl/types/bad_any_cast.h"

// NOTE: This macro is an implementation detail that is undefined at the bottom
// of the file. It is not intended for expansion directly from user code.
#ifdef ABSL_ANY_DETAIL_HAS_RTTI
#error ABSL_ANY_DETAIL_HAS_RTTI cannot be directly set
#elif !defined(__GNUC__) || defined(__GXX_RTTI)
#define ABSL_ANY_DETAIL_HAS_RTTI 1
#endif  // !defined(__GNUC__) || defined(__GXX_RTTI)

namespace absl {
inline namespace lts_2019_08_08 {

namespace any_internal {

template <typename Type>
struct TypeTag {
  constexpr static char dummy_var = 0;
};

template <typename Type>
constexpr char TypeTag<Type>::dummy_var;

// FastTypeId<Type>() evaluates at compile/link-time to a unique pointer for the
// passed in type. These are meant to be good match for keys into maps or
// straight up comparisons.
template<typename Type>
constexpr inline const void* FastTypeId() {
  return &TypeTag<Type>::dummy_var;
}

}  // namespace any_internal

class any;

// swap()
//
// Swaps two `absl::any` values. Equivalent to `x.swap(y) where `x` and `y` are
// `absl::any` types.
void swap(any& x, any& y) noexcept;

// make_any()
//
// Constructs an `absl::any` of type `T` with the given arguments.
template <typename T, typename... Args>
any make_any(Args&&... args);

// Overload of `absl::make_any()` for constructing an `absl::any` type from an
// initializer list.
template <typename T, typename U, typename... Args>
any make_any(std::initializer_list<U> il, Args&&... args);

// any_cast()
//
// Statically casts the value of a `const absl::any` type to the given type.
// This function will throw `absl::bad_any_cast` if the stored value type of the
// `absl::any` does not match the cast.
//
// `any_cast()` can also be used to get a reference to the internal storage iff
// a reference type is passed as its `ValueType`:
//
// Example:
//
//   absl::any my_any = std::vector<int>();
//   absl::any_cast<std::vector<int>&>(my_any).push_back(42);
template <typename ValueType>
ValueType any_cast(const any& operand);

// Overload of `any_cast()` to statically cast the value of a non-const
// `absl::any` type to the given type. This function will throw
// `absl::bad_any_cast` if the stored value type of the `absl::any` does not
// match the cast.
template <typename ValueType>
ValueType any_cast(any& operand);  // NOLINT(runtime/references)

// Overload of `any_cast()` to statically cast the rvalue of an `absl::any`
// type. This function will throw `absl::bad_any_cast` if the stored value type
// of the `absl::any` does not match the cast.
template <typename ValueType>
ValueType any_cast(any&& operand);

// Overload of `any_cast()` to statically cast the value of a const pointer
// `absl::any` type to the given pointer type, or `nullptr` if the stored value
// type of the `absl::any` does not match the cast.
template <typename ValueType>
const ValueType* any_cast(const any* operand) noexcept;

// Overload of `any_cast()` to statically cast the value of a pointer
// `absl::any` type to the given pointer type, or `nullptr` if the stored value
// type of the `absl::any` does not match the cast.
template <typename ValueType>
ValueType* any_cast(any* operand) noexcept;

// -----------------------------------------------------------------------------
// absl::any
// -----------------------------------------------------------------------------
//
// An `absl::any` object provides the facility to either store an instance of a
// type, known as the "contained object", or no value. An `absl::any` is used to
// store values of types that are unknown at compile time. The `absl::any`
// object, when containing a value, must contain a value type; storing a
// reference type is neither desired nor supported.
//
// An `absl::any` can only store a type that is copy-constructable; move-only
// types are not allowed within an `any` object.
//
// Example:
//
//   auto a = absl::any(65);                 // Literal, copyable
//   auto b = absl::any(std::vector<int>()); // Default-initialized, copyable
//   std::unique_ptr<Foo> my_foo;
//   auto c = absl::any(std::move(my_foo));  // Error, not copy-constructable
//
// Note that `absl::any` makes use of decayed types (`absl::decay_t` in this
// context) to remove const-volatile qualifiers (known as "cv qualifiers"),
// decay functions to function pointers, etc. We essentially "decay" a given
// type into its essential type.
//
// `absl::any` makes use of decayed types when determining the basic type `T` of
// the value to store in the any's contained object. In the documentation below,
// we explicitly denote this by using the phrase "a decayed type of `T`".
//
// Example:
//
//   const int a = 4;
//   absl::any foo(a);  // Decay ensures we store an "int", not a "const int&".
//
//   void my_function() {}
//   absl::any bar(my_function);  // Decay ensures we store a function pointer.
//
// `absl::any` is a C++11 compatible version of the C++17 `std::any` abstraction
// and is designed to be a drop-in replacement for code compliant with C++17.
class any {
 private:
  template <typename T>
  struct IsInPlaceType;

 public:
  // Constructors

  // Constructs an empty `absl::any` object (`any::has_value()` will return
  // `false`).
  constexpr any() noexcept;

  // Copy constructs an `absl::any` object with a "contained object" of the
  // passed type of `other` (or an empty `absl::any` if `other.has_value()` is
  // `false`.
  any(const any& other)
      : obj_(other.has_value() ? other.obj_->Clone()
                               : std::unique_ptr<ObjInterface>()) {}

  // Move constructs an `absl::any` object with a "contained object" of the
  // passed type of `other` (or an empty `absl::any` if `other.has_value()` is
  // `false`).
  any(any&& other) noexcept = default;

  // Constructs an `absl::any` object with a "contained object" of the decayed
  // type of `T`, which is initialized via `std::forward<T>(value)`.
  //
  // This constructor will not participate in overload resolution if the
  // decayed type of `T` is not copy-constructible.
  template <
      typename T, typename VT = absl::decay_t<T>,
      absl::enable_if_t<!absl::disjunction<
          std::is_same<any, VT>, IsInPlaceType<VT>,
          absl::negation<std::is_copy_constructible<VT> > >::value>* = nullptr>
  any(T&& value) : obj_(new Obj<VT>(in_place, std::forward<T>(value))) {}

  // Constructs an `absl::any` object with a "contained object" of the decayed
  // type of `T`, which is initialized via `std::forward<T>(value)`.
  template <typename T, typename... Args, typename VT = absl::decay_t<T>,
            absl::enable_if_t<absl::conjunction<
                std::is_copy_constructible<VT>,
                std::is_constructible<VT, Args...>>::value>* = nullptr>
  explicit any(in_place_type_t<T> /*tag*/, Args&&... args)
      : obj_(new Obj<VT>(in_place, std::forward<Args>(args)...)) {}

  // Constructs an `absl::any` object with a "contained object" of the passed
  // type `VT` as a decayed type of `T`. `VT` is initialized as if
  // direct-non-list-initializing an object of type `VT` with the arguments
  // `initializer_list, std::forward<Args>(args)...`.
  template <
      typename T, typename U, typename... Args, typename VT = absl::decay_t<T>,
      absl::enable_if_t<
          absl::conjunction<std::is_copy_constructible<VT>,
                            std::is_constructible<VT, std::initializer_list<U>&,
                                                  Args...>>::value>* = nullptr>
  explicit any(in_place_type_t<T> /*tag*/, std::initializer_list<U> ilist,
               Args&&... args)
      : obj_(new Obj<VT>(in_place, ilist, std::forward<Args>(args)...)) {}

  // Assignment operators

  // Copy assigns an `absl::any` object with a "contained object" of the
  // passed type.
  any& operator=(const any& rhs) {
    any(rhs).swap(*this);
    return *this;
  }

  // Move assigns an `absl::any` object with a "contained object" of the
  // passed type. `rhs` is left in a valid but otherwise unspecified state.
  any& operator=(any&& rhs) noexcept {
    any(std::move(rhs)).swap(*this);
    return *this;
  }

  // Assigns an `absl::any` object with a "contained object" of the passed type.
  template <typename T, typename VT = absl::decay_t<T>,
            absl::enable_if_t<absl::conjunction<
                absl::negation<std::is_same<VT, any>>,
                std::is_copy_constructible<VT>>::value>* = nullptr>
  any& operator=(T&& rhs) {
    any tmp(in_place_type_t<VT>(), std::forward<T>(rhs));
    tmp.swap(*this);
    return *this;
  }

  // Modifiers

  // any::emplace()
  //
  // Emplaces a value within an `absl::any` object by calling `any::reset()`,
  // initializing the contained value as if direct-non-list-initializing an
  // object of type `VT` with the arguments `std::forward<Args>(args)...`, and
  // returning a reference to the new contained value.
  //
  // Note: If an exception is thrown during the call to `VT`'s constructor,
  // `*this` does not contain a value, and any previously contained value has
  // been destroyed.
  template <
      typename T, typename... Args, typename VT = absl::decay_t<T>,
      absl::enable_if_t<std::is_copy_constructible<VT>::value &&
                        std::is_constructible<VT, Args...>::value>* = nullptr>
  VT& emplace(Args&&... args) {
    reset();  // NOTE: reset() is required here even in the world of exceptions.
    Obj<VT>* const object_ptr =
        new Obj<VT>(in_place, std::forward<Args>(args)...);
    obj_ = std::unique_ptr<ObjInterface>(object_ptr);
    return object_ptr->value;
  }

  // Overload of `any::emplace()` to emplace a value within an `absl::any`
  // object by calling `any::reset()`, initializing the contained value as if
  // direct-non-list-initializing an object of type `VT` with the arguments
  // `initializer_list, std::forward<Args>(args)...`, and returning a reference
  // to the new contained value.
  //
  // Note: If an exception is thrown during the call to `VT`'s constructor,
  // `*this` does not contain a value, and any previously contained value has
  // been destroyed. The function shall not participate in overload resolution
  // unless `is_copy_constructible_v<VT>` is `true` and
  // `is_constructible_v<VT, initializer_list<U>&, Args...>` is `true`.
  template <
      typename T, typename U, typename... Args, typename VT = absl::decay_t<T>,
      absl::enable_if_t<std::is_copy_constructible<VT>::value &&
                        std::is_constructible<VT, std::initializer_list<U>&,
                                              Args...>::value>* = nullptr>
  VT& emplace(std::initializer_list<U> ilist, Args&&... args) {
    reset();  // NOTE: reset() is required here even in the world of exceptions.
    Obj<VT>* const object_ptr =
        new Obj<VT>(in_place, ilist, std::forward<Args>(args)...);
    obj_ = std::unique_ptr<ObjInterface>(object_ptr);
    return object_ptr->value;
  }

  // any::reset()
  //
  // Resets the state of the `absl::any` object, destroying the contained object
  // if present.
  void reset() noexcept { obj_ = nullptr; }

  // any::swap()
  //
  // Swaps the passed value and the value of this `absl::any` object.
  void swap(any& other) noexcept { obj_.swap(other.obj_); }

  // Observers

  // any::has_value()
  //
  // Returns `true` if the `any` object has a contained value, otherwise
  // returns `false`.
  bool has_value() const noexcept { return obj_ != nullptr; }

#if ABSL_ANY_DETAIL_HAS_RTTI
  // Returns: typeid(T) if *this has a contained object of type T, otherwise
  // typeid(void).
  const std::type_info& type() const noexcept {
    if (has_value()) {
      return obj_->Type();
    }

    return typeid(void);
  }
#endif  // ABSL_ANY_DETAIL_HAS_RTTI

 private:
  // Tagged type-erased abstraction for holding a cloneable object.
  class ObjInterface {
   public:
    virtual ~ObjInterface() = default;
    virtual std::unique_ptr<ObjInterface> Clone() const = 0;
    virtual const void* ObjTypeId() const noexcept = 0;
#if ABSL_ANY_DETAIL_HAS_RTTI
    virtual const std::type_info& Type() const noexcept = 0;
#endif  // ABSL_ANY_DETAIL_HAS_RTTI
  };

  // Hold a value of some queryable type, with an ability to Clone it.
  template <typename T>
  class Obj : public ObjInterface {
   public:
    template <typename... Args>
    explicit Obj(in_place_t /*tag*/, Args&&... args)
        : value(std::forward<Args>(args)...) {}

    std::unique_ptr<ObjInterface> Clone() const final {
      return std::unique_ptr<ObjInterface>(new Obj(in_place, value));
    }

    const void* ObjTypeId() const noexcept final { return IdForType<T>(); }

#if ABSL_ANY_DETAIL_HAS_RTTI
    const std::type_info& Type() const noexcept final { return typeid(T); }
#endif  // ABSL_ANY_DETAIL_HAS_RTTI

    T value;
  };

  std::unique_ptr<ObjInterface> CloneObj() const {
    if (!obj_) return nullptr;
    return obj_->Clone();
  }

  template <typename T>
  constexpr static const void* IdForType() {
    // Note: This type dance is to make the behavior consistent with typeid.
    using NormalizedType =
        typename std::remove_cv<typename std::remove_reference<T>::type>::type;

    return any_internal::FastTypeId<NormalizedType>();
  }

  const void* GetObjTypeId() const {
    return obj_ ? obj_->ObjTypeId() : any_internal::FastTypeId<void>();
  }

  // `absl::any` nonmember functions //

  // Description at the declaration site (top of file).
  template <typename ValueType>
  friend ValueType any_cast(const any& operand);

  // Description at the declaration site (top of file).
  template <typename ValueType>
  friend ValueType any_cast(any& operand);  // NOLINT(runtime/references)

  // Description at the declaration site (top of file).
  template <typename T>
  friend const T* any_cast(const any* operand) noexcept;

  // Description at the declaration site (top of file).
  template <typename T>
  friend T* any_cast(any* operand) noexcept;

  std::unique_ptr<ObjInterface> obj_;
};

// -----------------------------------------------------------------------------
// Implementation Details
// -----------------------------------------------------------------------------

constexpr any::any() noexcept = default;

template <typename T>
struct any::IsInPlaceType : std::false_type {};

template <typename T>
struct any::IsInPlaceType<in_place_type_t<T>> : std::true_type {};

inline void swap(any& x, any& y) noexcept { x.swap(y); }

// Description at the declaration site (top of file).
template <typename T, typename... Args>
any make_any(Args&&... args) {
  return any(in_place_type_t<T>(), std::forward<Args>(args)...);
}

// Description at the declaration site (top of file).
template <typename T, typename U, typename... Args>
any make_any(std::initializer_list<U> il, Args&&... args) {
  return any(in_place_type_t<T>(), il, std::forward<Args>(args)...);
}

// Description at the declaration site (top of file).
template <typename ValueType>
ValueType any_cast(const any& operand) {
  using U = typename std::remove_cv<
      typename std::remove_reference<ValueType>::type>::type;
  static_assert(std::is_constructible<ValueType, const U&>::value,
                "Invalid ValueType");
  auto* const result = (any_cast<U>)(&operand);
  if (result == nullptr) {
    any_internal::ThrowBadAnyCast();
  }
  return static_cast<ValueType>(*result);
}

// Description at the declaration site (top of file).
template <typename ValueType>
ValueType any_cast(any& operand) {  // NOLINT(runtime/references)
  using U = typename std::remove_cv<
      typename std::remove_reference<ValueType>::type>::type;
  static_assert(std::is_constructible<ValueType, U&>::value,
                "Invalid ValueType");
  auto* result = (any_cast<U>)(&operand);
  if (result == nullptr) {
    any_internal::ThrowBadAnyCast();
  }
  return static_cast<ValueType>(*result);
}

// Description at the declaration site (top of file).
template <typename ValueType>
ValueType any_cast(any&& operand) {
  using U = typename std::remove_cv<
      typename std::remove_reference<ValueType>::type>::type;
  static_assert(std::is_constructible<ValueType, U>::value,
                "Invalid ValueType");
  return static_cast<ValueType>(std::move((any_cast<U&>)(operand)));
}

// Description at the declaration site (top of file).
template <typename T>
const T* any_cast(const any* operand) noexcept {
  return operand && operand->GetObjTypeId() == any::IdForType<T>()
             ? std::addressof(
                   static_cast<const any::Obj<T>*>(operand->obj_.get())->value)
             : nullptr;
}

// Description at the declaration site (top of file).
template <typename T>
T* any_cast(any* operand) noexcept {
  return operand && operand->GetObjTypeId() == any::IdForType<T>()
             ? std::addressof(
                   static_cast<any::Obj<T>*>(operand->obj_.get())->value)
             : nullptr;
}

}  // inline namespace lts_2019_08_08
}  // namespace absl

#undef ABSL_ANY_DETAIL_HAS_RTTI

#endif  // ABSL_HAVE_STD_ANY

#endif  // ABSL_TYPES_ANY_H_
