/*
 * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_METAPROGRAMMING_PRIMITIVECONVERSIONS_HPP
#define SHARE_METAPROGRAMMING_PRIMITIVECONVERSIONS_HPP

#include "memory/allStatic.hpp"
#include "metaprogramming/enableIf.hpp"
#include "utilities/globalDefinitions.hpp"
#include <type_traits>

class PrimitiveConversions : public AllStatic {

  // True if types are the same size and either is integral.
  template<typename To, typename From>
  static constexpr bool check_cast() {
    return (sizeof(To) == sizeof(From)) &&
           (std::is_integral<To>::value || std::is_integral<From>::value);
  }

public:
  // template<typename To, typename From> To cast(From x)
  //
  // Return a value of type To with the same value representation as x.
  //
  // To and From must be of the same size.
  //
  // At least one of To or From must be an integral type.  The other must
  // be an integral, enum, floating point, or pointer type.

  // integer -> integer
  // Use static_cast for conversion.  See C++14 4.7 Integral
  // conversions. If To is signed and From unsigned, the result is
  // implementation-defined.  All supported platforms provide two's
  // complement behavior, and that behavior is required by C++20.
  // Using an lvalue to reference cast (see C++03 3.10/15) involves a
  // reinterpret_cast, which prevents constexpr support.
  template<typename To, typename From,
           ENABLE_IF(sizeof(To) == sizeof(From)),
           ENABLE_IF(std::is_integral<To>::value),
           ENABLE_IF(std::is_integral<From>::value)>
  static constexpr To cast(From x) {
    return static_cast<To>(x);
  }

  // integer -> enum, enum -> integer
  // Use the enum's underlying type for integer -> integer cast.
  template<typename To, typename From,
           ENABLE_IF(check_cast<To, From>()),
           ENABLE_IF(std::is_enum<To>::value)>
  static constexpr To cast(From x) {
    return static_cast<To>(cast<std::underlying_type_t<To>>(x));
  }

  template<typename To, typename From,
           ENABLE_IF(check_cast<To, From>()),
           ENABLE_IF(std::is_enum<From>::value)>
  static constexpr To cast(From x) {
    return cast<To>(static_cast<std::underlying_type_t<From>>(x));
  }

  // integer -> pointer, pointer -> integer
  // Use reinterpret_cast, so no constexpr support.
  template<typename To, typename From,
           ENABLE_IF(check_cast<To, From>()),
           ENABLE_IF(std::is_pointer<To>::value || std::is_pointer<From>::value)>
  static To cast(From x) {
    return reinterpret_cast<To>(x);
  }

  // integer -> floating point, floating point -> integer
  // Use the union trick.  The union trick is technically UB, but is
  // widely and well supported, producing good code.  In some cases,
  // such as gcc, that support is explicitly documented.  Using memcpy
  // is the correct method, but some compilers produce wretched code
  // for that method, even at maximal optimization levels.  Neither
  // the union trick nor memcpy provides constexpr support.
  template<typename To, typename From,
           ENABLE_IF(check_cast<To, From>()),
           ENABLE_IF(std::is_floating_point<To>::value ||
                     std::is_floating_point<From>::value)>
  static To cast(From x) {
    union { From from; To to; } converter = { x };
    return converter.to;
  }

  // Support thin wrappers over primitive types and other conversions.
  // If derived from std::true_type, provides representational conversion
  // from T to some other type.  When true, must provide
  // - Value: typedef for T.
  // - Decayed: typedef for decayed type.
  // - static Decayed decay(T x): return value of type Decayed with
  //   the same value representation as x.
  // - static T recover(Decayed x): return a value of type T with the
  //   same value representation as x.
  template<typename T, typename Enable = void>
  struct Translate : public std::false_type {};
};

// Enum types translate to/from their underlying type.
template<typename T>
struct PrimitiveConversions::Translate<T, std::enable_if_t<std::is_enum<T>::value>>
  : public std::true_type
{
  using Value = T;
  using Decayed = std::underlying_type_t<T>;

  static constexpr Decayed decay(Value x) { return static_cast<Decayed>(x); }
  static constexpr Value recover(Decayed x) { return static_cast<Value>(x); }
};

// jfloat and jdouble translation to integral types

template<>
struct PrimitiveConversions::Translate<jdouble> : public std::true_type {
  typedef double Value;
  typedef int64_t Decayed;

  static Decayed decay(Value x) { return PrimitiveConversions::cast<Decayed>(x); }
  static Value recover(Decayed x) { return PrimitiveConversions::cast<Value>(x); }
};

template<>
struct PrimitiveConversions::Translate<jfloat> : public std::true_type {
  typedef float Value;
  typedef int32_t Decayed;

  static Decayed decay(Value x) { return PrimitiveConversions::cast<Decayed>(x); }
  static Value recover(Decayed x) { return PrimitiveConversions::cast<Value>(x); }
};

#endif // SHARE_METAPROGRAMMING_PRIMITIVECONVERSIONS_HPP
