/*
 *  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 WEBRTC_RTC_BASE_SAFE_CONVERSIONS_IMPL_H_
#define WEBRTC_RTC_BASE_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  // WEBRTC_RTC_BASE_SAFE_CONVERSIONS_IMPL_H_
