/*
 *  Copyright 2014 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// Borrowed from Chromium's src/base/numerics/safe_conversions_impl.h.

#ifndef RTC_BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
#define RTC_BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_

#include <limits>

namespace rtc {
namespace internal {

enum DstSign { DST_UNSIGNED, DST_SIGNED };

enum SrcSign { SRC_UNSIGNED, SRC_SIGNED };

enum DstRange { OVERLAPS_RANGE, CONTAINS_RANGE };

// Helper templates to statically determine if our destination type can contain
// all values represented by the source type.

template <typename Dst,
          typename Src,
          DstSign IsDstSigned =
              std::numeric_limits<Dst>::is_signed ? DST_SIGNED : DST_UNSIGNED,
          SrcSign IsSrcSigned =
              std::numeric_limits<Src>::is_signed ? SRC_SIGNED : SRC_UNSIGNED>
struct StaticRangeCheck {};

template <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_SIGNED, SRC_SIGNED> {
  typedef std::numeric_limits<Dst> DstLimits;
  typedef std::numeric_limits<Src> SrcLimits;
  // Compare based on max_exponent, which we must compute for integrals.
  static const size_t kDstMaxExponent =
      DstLimits::is_iec559 ? DstLimits::max_exponent : (sizeof(Dst) * 8 - 1);
  static const size_t kSrcMaxExponent =
      SrcLimits::is_iec559 ? SrcLimits::max_exponent : (sizeof(Src) * 8 - 1);
  static const DstRange value =
      kDstMaxExponent >= kSrcMaxExponent ? CONTAINS_RANGE : OVERLAPS_RANGE;
};

template <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED> {
  static const DstRange value =
      sizeof(Dst) >= sizeof(Src) ? CONTAINS_RANGE : OVERLAPS_RANGE;
};

template <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_SIGNED, SRC_UNSIGNED> {
  typedef std::numeric_limits<Dst> DstLimits;
  typedef std::numeric_limits<Src> SrcLimits;
  // Compare based on max_exponent, which we must compute for integrals.
  static const size_t kDstMaxExponent =
      DstLimits::is_iec559 ? DstLimits::max_exponent : (sizeof(Dst) * 8 - 1);
  static const size_t kSrcMaxExponent = sizeof(Src) * 8;
  static const DstRange value =
      kDstMaxExponent >= kSrcMaxExponent ? CONTAINS_RANGE : OVERLAPS_RANGE;
};

template <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_UNSIGNED, SRC_SIGNED> {
  static const DstRange value = OVERLAPS_RANGE;
};

enum RangeCheckResult {
  TYPE_VALID = 0,      // Value can be represented by the destination type.
  TYPE_UNDERFLOW = 1,  // Value would overflow.
  TYPE_OVERFLOW = 2,   // Value would underflow.
  TYPE_INVALID = 3     // Source value is invalid (i.e. NaN).
};

// This macro creates a RangeCheckResult from an upper and lower bound
// check by taking advantage of the fact that only NaN can be out of range in
// both directions at once.
#define BASE_NUMERIC_RANGE_CHECK_RESULT(is_in_upper_bound, is_in_lower_bound) \
  RangeCheckResult(((is_in_upper_bound) ? 0 : TYPE_OVERFLOW) |                \
                   ((is_in_lower_bound) ? 0 : TYPE_UNDERFLOW))

template <typename Dst,
          typename Src,
          DstSign IsDstSigned =
              std::numeric_limits<Dst>::is_signed ? DST_SIGNED : DST_UNSIGNED,
          SrcSign IsSrcSigned =
              std::numeric_limits<Src>::is_signed ? SRC_SIGNED : SRC_UNSIGNED,
          DstRange IsSrcRangeContained = StaticRangeCheck<Dst, Src>::value>
struct RangeCheckImpl {};

// The following templates are for ranges that must be verified at runtime. We
// split it into checks based on signedness to avoid confusing casts and
// compiler warnings on signed an unsigned comparisons.

// Dst range always contains the result: nothing to check.
template <typename Dst, typename Src, DstSign IsDstSigned, SrcSign IsSrcSigned>
struct RangeCheckImpl<Dst, Src, IsDstSigned, IsSrcSigned, CONTAINS_RANGE> {
  static RangeCheckResult Check(Src value) { return TYPE_VALID; }
};

// Signed to signed narrowing.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
  static RangeCheckResult Check(Src value) {
    typedef std::numeric_limits<Dst> DstLimits;
    return DstLimits::is_iec559
               ? BASE_NUMERIC_RANGE_CHECK_RESULT(
                     value <= static_cast<Src>(DstLimits::max()),
                     value >= static_cast<Src>(DstLimits::max() * -1))
               : BASE_NUMERIC_RANGE_CHECK_RESULT(
                     value <= static_cast<Src>(DstLimits::max()),
                     value >= static_cast<Src>(DstLimits::min()));
  }
};

// Unsigned to unsigned narrowing.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
  static RangeCheckResult Check(Src value) {
    typedef std::numeric_limits<Dst> DstLimits;
    return BASE_NUMERIC_RANGE_CHECK_RESULT(
        value <= static_cast<Src>(DstLimits::max()), true);
  }
};

// Unsigned to signed.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
  static RangeCheckResult Check(Src value) {
    typedef std::numeric_limits<Dst> DstLimits;
    return sizeof(Dst) > sizeof(Src)
               ? TYPE_VALID
               : BASE_NUMERIC_RANGE_CHECK_RESULT(
                     value <= static_cast<Src>(DstLimits::max()), true);
  }
};

// Signed to unsigned.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
  static RangeCheckResult Check(Src value) {
    typedef std::numeric_limits<Dst> DstLimits;
    typedef std::numeric_limits<Src> SrcLimits;
    // Compare based on max_exponent, which we must compute for integrals.
    static const size_t kDstMaxExponent = sizeof(Dst) * 8;
    static const size_t kSrcMaxExponent =
        SrcLimits::is_iec559 ? SrcLimits::max_exponent : (sizeof(Src) * 8 - 1);
    return (kDstMaxExponent >= kSrcMaxExponent)
               ? BASE_NUMERIC_RANGE_CHECK_RESULT(true,
                                                 value >= static_cast<Src>(0))
               : BASE_NUMERIC_RANGE_CHECK_RESULT(
                     value <= static_cast<Src>(DstLimits::max()),
                     value >= static_cast<Src>(0));
  }
};

template <typename Dst, typename Src>
inline RangeCheckResult RangeCheck(Src value) {
  static_assert(std::numeric_limits<Src>::is_specialized,
                "argument must be numeric");
  static_assert(std::numeric_limits<Dst>::is_specialized,
                "result must be numeric");
  return RangeCheckImpl<Dst, Src>::Check(value);
}

}  // namespace internal
}  // namespace rtc

#endif  // RTC_BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
