/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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
 *
 *      http://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 ART_RUNTIME_BASE_CASTS_H_
#define ART_RUNTIME_BASE_CASTS_H_

#include <assert.h>
#include <limits>
#include <stdint.h>
#include <string.h>
#include <type_traits>

#include "base/logging.h"
#include "base/macros.h"

namespace art {

// Use implicit_cast as a safe version of static_cast or const_cast
// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
// a const pointer to Foo).
// When you use implicit_cast, the compiler checks that the cast is safe.
// Such explicit implicit_casts are necessary in surprisingly many
// situations where C++ demands an exact type match instead of an
// argument type convertible to a target type.
//
// The From type can be inferred, so the preferred syntax for using
// implicit_cast is the same as for static_cast etc.:
//
//   implicit_cast<ToType>(expr)
//
// implicit_cast would have been part of the C++ standard library,
// but the proposal was submitted too late.  It will probably make
// its way into the language in the future.
template<typename To, typename From>
inline To implicit_cast(From const &f) {
  return f;
}

// When you upcast (that is, cast a pointer from type Foo to type
// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
// always succeed.  When you downcast (that is, cast a pointer from
// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
// how do you know the pointer is really of type SubclassOfFoo?  It
// could be a bare Foo, or of type DifferentSubclassOfFoo.  Thus,
// when you downcast, you should use this macro.  In debug mode, we
// use dynamic_cast<> to double-check the downcast is legal (we die
// if it's not).  In normal mode, we do the efficient static_cast<>
// instead.  Thus, it's important to test in debug mode to make sure
// the cast is legal!
//    This is the only place in the code we should use dynamic_cast<>.
// In particular, you SHOULDN'T be using dynamic_cast<> in order to
// do RTTI (eg code like this:
//    if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
//    if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
// You should design the code some other way not to need this.

template<typename To, typename From>     // use like this: down_cast<T*>(foo);
inline To down_cast(From* f) {                   // so we only accept pointers
  static_assert(std::is_base_of<From, typename std::remove_pointer<To>::type>::value,
                "down_cast unsafe as To is not a subtype of From");

  return static_cast<To>(f);
}

template <class Dest, class Source>
inline Dest bit_cast(const Source& source) {
  // Compile time assertion: sizeof(Dest) == sizeof(Source)
  // A compile error here means your Dest and Source have different sizes.
  static_assert(sizeof(Dest) == sizeof(Source), "sizes should be equal");
  Dest dest;
  memcpy(&dest, &source, sizeof(dest));
  return dest;
}

// A version of static_cast that DCHECKs that the value can be precisely represented
// when converting to Dest.
template <typename Dest, typename Source>
inline Dest dchecked_integral_cast(const Source source) {
  DCHECK(
      // Check that the value is within the lower limit of Dest.
      (static_cast<intmax_t>(std::numeric_limits<Dest>::min()) <=
          static_cast<intmax_t>(std::numeric_limits<Source>::min()) ||
          source >= static_cast<Source>(std::numeric_limits<Dest>::min())) &&
      // Check that the value is within the upper limit of Dest.
      (static_cast<uintmax_t>(std::numeric_limits<Dest>::max()) >=
          static_cast<uintmax_t>(std::numeric_limits<Source>::max()) ||
          source <= static_cast<Source>(std::numeric_limits<Dest>::max())))
      << "dchecked_integral_cast failed for " << source
      << " (would be " << static_cast<Dest>(source) << ")";

  return static_cast<Dest>(source);
}

// A version of reinterpret_cast<>() between pointers and int64_t/uint64_t
// that goes through uintptr_t to avoid treating the pointer as "signed."

template <typename Dest, typename Source>
inline Dest reinterpret_cast64(Source source) {
  // This is the overload for casting from int64_t/uint64_t to a pointer.
  static_assert(std::is_same<Source, int64_t>::value || std::is_same<Source, uint64_t>::value,
                "Source must be int64_t or uint64_t.");
  static_assert(std::is_pointer<Dest>::value, "Dest must be a pointer.");
  // Check that we don't lose any non-0 bits here.
  DCHECK_EQ(static_cast<Source>(static_cast<uintptr_t>(source)), source);
  return reinterpret_cast<Dest>(static_cast<uintptr_t>(source));
}

template <typename Dest, typename Source>
inline Dest reinterpret_cast64(Source* ptr) {
  // This is the overload for casting from a pointer to int64_t/uint64_t.
  static_assert(std::is_same<Dest, int64_t>::value || std::is_same<Dest, uint64_t>::value,
                "Dest must be int64_t or uint64_t.");
  static_assert(sizeof(uintptr_t) <= sizeof(Dest), "Expecting at most 64-bit pointers.");
  return static_cast<Dest>(reinterpret_cast<uintptr_t>(ptr));
}

}  // namespace art

#endif  // ART_RUNTIME_BASE_CASTS_H_
