Commit 83c9d1ca authored by Dão Gottwald's avatar Dão Gottwald
Browse files

merge backout

parents 348c2b9f 5e32254e
Loading
Loading
Loading
Loading
+34 −24
Original line number Diff line number Diff line
@@ -209,6 +209,8 @@ struct PositionOfSignBit

template<typename IntegerType>
struct MinValue
{
    static IntegerType value()
    {
      // Bitwise ops may return a larger type, that's why we cast explicitly.
      // In C++, left bit shifts on signed values is undefined by the standard
@@ -216,20 +218,23 @@ struct MinValue
      // Notice that signed-to-unsigned conversions are always well-defined in
      // the standard as the value congruent to 2**n, as expected. By contrast,
      // unsigned-to-signed is only well-defined if the value is representable.
    static const IntegerType value =
        IsSigned<IntegerType>::value
      return IsSigned<IntegerType>::value
             ? IntegerType(typename UnsignedType<IntegerType>::Type(1)
                             << PositionOfSignBit<IntegerType>::value)
             : IntegerType(0);
    }
};

template<typename IntegerType>
struct MaxValue
{
    static IntegerType value()
    {
      // Tricksy, but covered by the unit test.
    // Relies heavily on the type of MinValue<IntegerType>::value
      // Relies heavily on the return type of MinValue<IntegerType>::value()
      // being IntegerType.
    static const IntegerType value = ~MinValue<IntegerType>::value;
      return ~MinValue<IntegerType>::value();
    }
};

/*
@@ -273,7 +278,8 @@ struct IsInRangeImpl<T, U, true, true>
{
    static bool run(U x)
    {
      return x <= MaxValue<T>::value && x >= MinValue<T>::value;
      return x <= MaxValue<T>::value() &&
             x >= MinValue<T>::value();
    }
};

@@ -282,7 +288,7 @@ struct IsInRangeImpl<T, U, false, false>
{
    static bool run(U x)
    {
      return x <= MaxValue<T>::value;
      return x <= MaxValue<T>::value();
    }
};

@@ -291,7 +297,9 @@ struct IsInRangeImpl<T, U, true, false>
{
    static bool run(U x)
    {
      return sizeof(T) > sizeof(U) || x <= U(MaxValue<T>::value);
      return sizeof(T) > sizeof(U)
             ? true
             : x <= U(MaxValue<T>::value());
    }
};

@@ -302,7 +310,7 @@ struct IsInRangeImpl<T, U, false, true>
    {
      return sizeof(T) >= sizeof(U)
             ? x >= 0
             : x >= 0 && x <= U(MaxValue<T>::value);
             : x >= 0 && x <= U(MaxValue<T>::value());
    }
};

@@ -358,8 +366,8 @@ struct IsMulValidImpl<T, true, false>
{
    static bool run(T x, T y)
    {
      const T max = MaxValue<T>::value;
      const T min = MinValue<T>::value;
      const T max = MaxValue<T>::value();
      const T min = MinValue<T>::value();

      if (x == 0 || y == 0)
        return true;
@@ -382,7 +390,8 @@ struct IsMulValidImpl<T, false, false>
{
    static bool run(T x, T y)
    {
      return y == 0 ||  x <= MaxValue<T>::value / y;
      return y == 0 ||
             x <= MaxValue<T>::value() / y;
    }
};

@@ -398,8 +407,9 @@ inline bool
IsDivValid(T x, T y)
{
  // Keep in mind that in the signed case, min/-1 is invalid because abs(min)>max.
  return y != 0 &&
         !(IsSigned<T>::value && x == MinValue<T>::value && y == T(-1));
  return IsSigned<T>::value
         ? (y != 0) && (x != MinValue<T>::value() || y != T(-1))
         : y != 0;
}

// This is just to shut up msvc warnings about negating unsigned ints.
+5 −5
Original line number Diff line number Diff line
@@ -96,8 +96,8 @@ void test()
  VERIFY(sizeof(unsignedT) == sizeof(T));
  VERIFY(detail::IsSigned<unsignedT>::value == false);

  const CheckedInt<T> max(detail::MaxValue<T>::value);
  const CheckedInt<T> min(detail::MinValue<T>::value);
  const CheckedInt<T> max(detail::MaxValue<T>::value());
  const CheckedInt<T> min(detail::MinValue<T>::value());

  // Check min() and max(), since they are custom implementations and a mistake there
  // could potentially NOT be caught by any other tests... while making everything wrong!
@@ -394,10 +394,10 @@ void test()
    if (isUSigned) \
      VERIFY_IS_VALID_IF(CheckedInt<T>(U(-1)), isTSigned); \
    if (sizeof(U) > sizeof(T)) \
      VERIFY_IS_INVALID(CheckedInt<T>(U(detail::MaxValue<T>::value) + 1)); \
    VERIFY_IS_VALID_IF(CheckedInt<T>(detail::MaxValue<U>::value), \
      VERIFY_IS_INVALID(CheckedInt<T>(U(detail::MaxValue<T>::value())+1)); \
    VERIFY_IS_VALID_IF(CheckedInt<T>(detail::MaxValue<U>::value()), \
      (sizeof(T) > sizeof(U) || ((sizeof(T) == sizeof(U)) && (isUSigned || !isTSigned)))); \
    VERIFY_IS_VALID_IF(CheckedInt<T>(detail::MinValue<U>::value), \
    VERIFY_IS_VALID_IF(CheckedInt<T>(detail::MinValue<U>::value()), \
      isUSigned == false ? 1 : \
      bool(isTSigned) == false ? 0 : \
      sizeof(T) >= sizeof(U)); \