//
// 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.
//
// -----------------------------------------------------------------------------
// File: casts.h
// -----------------------------------------------------------------------------
//
// This header file defines casting templates to fit use cases not covered by
// the standard casts provided in the C++ standard. As with all cast operations,
// use these with caution and only if alternatives do not exist.

#ifndef ABSL_BASE_CASTS_H_
#define ABSL_BASE_CASTS_H_

#include <cstring>
#include <memory>
#include <type_traits>
#include <typeinfo>
#include <utility>

#if __has_include(<version>)
#include <version>  // For __cpp_lib_bit_cast.
#endif

#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
#include <bit>  // For std::bit_cast.
#endif  // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/base/options.h"
#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// implicit_cast()
//
// Performs an implicit conversion between types following the language
// rules for implicit conversion; if an implicit conversion is otherwise
// allowed by the language in the given context, this function performs such an
// implicit conversion.
//
// Example:
//
//   // If the context allows implicit conversion:
//   From from;
//   To to = from;
//
//   // Such code can be replaced by:
//   implicit_cast<To>(from);
//
// An `implicit_cast()` may also be used to annotate numeric type conversions
// that, although safe, may produce compiler warnings (such as `long` to `int`).
// Additionally, an `implicit_cast()` is also useful within return statements to
// indicate a specific implicit conversion is being undertaken.
//
// Example:
//
//   return implicit_cast<double>(size_in_bytes) / capacity_;
//
// Annotating code with `implicit_cast()` allows you to explicitly select
// particular overloads and template instantiations, while providing a safer
// cast than `reinterpret_cast()` or `static_cast()`.
//
// Additionally, an `implicit_cast()` can be used to allow upcasting within a
// type hierarchy where incorrect use of `static_cast()` could accidentally
// allow downcasting.
//
// Finally, an `implicit_cast()` can be used to perform implicit conversions
// from unrelated types that otherwise couldn't be implicitly cast directly;
// C++ will normally only implicitly cast "one step" in such conversions.
//
// That is, if C is a type which can be implicitly converted to B, with B being
// a type that can be implicitly converted to A, an `implicit_cast()` can be
// used to convert C to B (which the compiler can then implicitly convert to A
// using language rules).
//
// Example:
//
//   // Assume an object C is convertible to B, which is implicitly convertible
//   // to A
//   A a = implicit_cast<B>(C);
//
// Such implicit cast chaining may be useful within template logic.
template <typename To>
constexpr std::enable_if_t<
    !type_traits_internal::IsView<std::enable_if_t<
        !std::is_reference_v<To>, std::remove_cv_t<To>>>::value,
    To>
implicit_cast(absl::type_identity_t<To> to) {
  return to;
}
template <typename To>
constexpr std::enable_if_t<
    type_traits_internal::IsView<std::enable_if_t<!std::is_reference_v<To>,
                                                  std::remove_cv_t<To>>>::value,
    To>
implicit_cast(absl::type_identity_t<To> to ABSL_ATTRIBUTE_LIFETIME_BOUND) {
  return to;
}
template <typename To>
constexpr std::enable_if_t<std::is_reference_v<To>, To> implicit_cast(
    absl::type_identity_t<To> to ABSL_ATTRIBUTE_LIFETIME_BOUND) {
  return std::forward<absl::type_identity_t<To>>(to);
}

// bit_cast()
//
// Creates a value of the new type `Dest` whose representation is the same as
// that of the argument, which is of (deduced) type `Source` (a "bitwise cast";
// every bit in the value representation of the result is equal to the
// corresponding bit in the object representation of the source). Source and
// destination types must be of the same size, and both types must be trivially
// copyable.
//
// As with most casts, use with caution. A `bit_cast()` might be needed when you
// need to treat a value as the value of some other type, for example, to access
// the individual bits of an object which are not normally accessible through
// the object's type, such as for working with the binary representation of a
// floating point value:
//
//   float f = 3.14159265358979;
//   int i = bit_cast<int>(f);
//   // i = 0x40490fdb
//
// Reinterpreting and accessing a value directly as a different type (as shown
// below) usually results in undefined behavior.
//
// Example:
//
//   // WRONG
//   float f = 3.14159265358979;
//   int i = reinterpret_cast<int&>(f);    // Wrong
//   int j = *reinterpret_cast<int*>(&f);  // Equally wrong
//   int k = *bit_cast<int*>(&f);          // Equally wrong
//
// Reinterpret-casting results in undefined behavior according to the ISO C++
// specification, section [basic.lval]. Roughly, this section says: if an object
// in memory has one type, and a program accesses it with a different type, the
// result is undefined behavior for most "different type".
//
// Using bit_cast on a pointer and then dereferencing it is no better than using
// reinterpret_cast. You should only use bit_cast on the value itself.
//
// Such casting results in type punning: holding an object in memory of one type
// and reading its bits back using a different type. A `bit_cast()` avoids this
// issue by copying the object representation to a new value, which avoids
// introducing this undefined behavior (since the original value is never
// accessed in the wrong way).
//
// The requirements of `absl::bit_cast` are more strict than that of
// `std::bit_cast` unless compiler support is available. Specifically, without
// compiler support, this implementation also requires `Dest` to be
// default-constructible. In C++20, `absl::bit_cast` is replaced by
// `std::bit_cast`.
#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L

using std::bit_cast;

#else  // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L

template <typename Dest, typename Source,
          std::enable_if_t<sizeof(Dest) == sizeof(Source) &&
                               std::is_trivially_copyable_v<Source> &&
                               std::is_trivially_copyable_v<Dest>
#if !ABSL_HAVE_BUILTIN(__builtin_bit_cast)
                               && std::is_default_constructible_v<Dest>
#endif  // !ABSL_HAVE_BUILTIN(__builtin_bit_cast)
                           ,
                           int> = 0>
#if ABSL_HAVE_BUILTIN(__builtin_bit_cast)
inline constexpr Dest bit_cast(const Source& source) {
  return __builtin_bit_cast(Dest, source);
}
#else  // ABSL_HAVE_BUILTIN(__builtin_bit_cast)
inline Dest bit_cast(const Source& source) {
  Dest dest;
  memcpy(static_cast<void*>(std::addressof(dest)),
         static_cast<const void*>(std::addressof(source)), sizeof(dest));
  return dest;
}
#endif  // ABSL_HAVE_BUILTIN(__builtin_bit_cast)

#endif  // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L

namespace base_internal {

[[noreturn]] ABSL_ATTRIBUTE_NOINLINE void BadDownCastCrash(
    const char* source_type, const char* target_type);

template <typename To, typename From>
inline void ValidateDownCast(From* f) {
  // Assert only if RTTI is enabled and in debug mode or hardened asserts are
  // enabled.
#if defined(ABSL_INTERNAL_HAS_RTTI) && \
    (!defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1))
  // Suppress erroneous nonnull comparison warning on older GCC.
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull-compare"
#endif
  if (ABSL_PREDICT_FALSE(f != nullptr && dynamic_cast<To>(f) == nullptr)) {
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
    absl::base_internal::BadDownCastCrash(
        typeid(*f).name(), typeid(std::remove_pointer_t<To>).name());
  }
#else
  (void)f;  // Denote this as "used" to avoid warning
#endif
}

}  // namespace base_internal

// An "upcast", i.e. a conversion from a pointer to an object to a pointer to a
// base subobject, always succeeds if the base is unambiguous and accessible,
// and so it's fine to use implicit_cast.
//
// A "downcast", i.e. a conversion from a pointer to an object to a pointer
// to a more-derived object that may contain the original object as a base
// subobject, cannot safely be done using static_cast, because you do not
// generally know whether the source object is really the base subobject of
// a containing, more-derived object of the target type. Thus, when you
// downcast in a polymorphic type hierarchy, you should use the following
// function template.
//
// This function only returns null when the input is null. In debug mode, we
// use dynamic_cast to double-check whether the downcast is legal (we die if
// it's not). In normal mode, we do the efficient static_cast instead. Because
// the process will die in debug mode, it's important to test to make sure the
// cast is legal before calling this function!
//
// dynamic_cast should be avoided except as allowed by the style guide
// (https://google.github.io/styleguide/cppguide.html#Run-Time_Type_Information__RTTI_).

template <typename To, typename From>  // use like this: down_cast<T*>(foo);
[[nodiscard]]
inline To down_cast(From* f) {  // so we only accept pointers
  static_assert(std::is_pointer_v<To>, "target type not a pointer");
  // dynamic_cast allows casting to the same type or a more cv-qualified
  // version of the same type without them being polymorphic.
  if constexpr (!std::is_same_v<std::remove_cv_t<std::remove_pointer_t<To>>,
                                std::remove_cv_t<From>>) {
    static_assert(std::is_polymorphic_v<From>,
                  "source type must be polymorphic");
    static_assert(std::is_polymorphic_v<std::remove_pointer_t<To>>,
                  "target type must be polymorphic");
  }
  static_assert(
      std::is_convertible_v<std::remove_cv_t<std::remove_pointer_t<To>>*,
                            std::remove_cv_t<From>*>,
      "target type not derived from source type");

  absl::base_internal::ValidateDownCast<To>(f);

  return static_cast<To>(f);
}

// Overload of down_cast for references. Use like this:
// absl::down_cast<T&>(foo). The code is slightly convoluted because we're still
// using the pointer form of dynamic cast. (The reference form throws an
// exception if it fails.)
//
// There's no need for a special const overload either for the pointer
// or the reference form. If you call down_cast with a const T&, the
// compiler will just bind From to const T.
template <typename To, typename From>
[[nodiscard]]
inline To down_cast(From& f) {
  static_assert(std::is_lvalue_reference_v<To>, "target type not a reference");
  // dynamic_cast allows casting to the same type or a more cv-qualified
  // version of the same type without them being polymorphic.
  if constexpr (!std::is_same_v<std::remove_cv_t<std::remove_reference_t<To>>,
                                std::remove_cv_t<From>>) {
    static_assert(std::is_polymorphic_v<From>,
                  "source type must be polymorphic");
    static_assert(std::is_polymorphic_v<std::remove_reference_t<To>>,
                  "target type must be polymorphic");
  }
  static_assert(
      std::is_convertible_v<std::remove_cv_t<std::remove_reference_t<To>>*,
                            std::remove_cv_t<From>*>,
      "target type not derived from source type");

  absl::base_internal::ValidateDownCast<std::remove_reference_t<To>*>(
      std::addressof(f));

  return static_cast<To>(f);
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_CASTS_H_
