/*
 *  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_BASE_SAFE_CONVERSIONS_IMPL_H_
#define WEBRTC_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_BASE_SAFE_CONVERSIONS_IMPL_H_
