SafeMin/SafeMax: Fix wrong return type when given two enum arguments

And add tests that catch it.

BUG=webrtc:7459

Review-Url: https://codereview.webrtc.org/2916083003
Cr-Commit-Position: refs/heads/master@{#18407}
This commit is contained in:
kwiberg 2017-06-02 04:24:11 -07:00 committed by Commit Bot
parent 2ff5b8347a
commit dbb497af84
2 changed files with 29 additions and 18 deletions

View File

@ -153,13 +153,15 @@ struct TypeOr {
} // namespace safe_minmax_impl
template <typename R = safe_minmax_impl::DefaultType,
typename T1 = safe_minmax_impl::DefaultType,
typename T2 = safe_minmax_impl::DefaultType,
typename R2 = typename safe_minmax_impl::TypeOr<
R,
typename safe_minmax_impl::UnderlyingType<
typename safe_minmax_impl::MType<T1, T2>::min_t>::type>::type>
template <
typename R = safe_minmax_impl::DefaultType,
typename T1 = safe_minmax_impl::DefaultType,
typename T2 = safe_minmax_impl::DefaultType,
typename R2 = typename safe_minmax_impl::TypeOr<
R,
typename safe_minmax_impl::MType<
typename safe_minmax_impl::UnderlyingType<T1>::type,
typename safe_minmax_impl::UnderlyingType<T2>::type>::min_t>::type>
constexpr R2 SafeMin(T1 a, T2 b) {
static_assert(IsIntlike<T1>::value || std::is_floating_point<T1>::value,
"The first argument must be integral or floating-point");
@ -168,13 +170,15 @@ constexpr R2 SafeMin(T1 a, T2 b) {
return safe_cmp::Lt(a, b) ? static_cast<R2>(a) : static_cast<R2>(b);
}
template <typename R = safe_minmax_impl::DefaultType,
typename T1 = safe_minmax_impl::DefaultType,
typename T2 = safe_minmax_impl::DefaultType,
typename R2 = typename safe_minmax_impl::TypeOr<
R,
typename safe_minmax_impl::UnderlyingType<
typename safe_minmax_impl::MType<T1, T2>::max_t>::type>::type>
template <
typename R = safe_minmax_impl::DefaultType,
typename T1 = safe_minmax_impl::DefaultType,
typename T2 = safe_minmax_impl::DefaultType,
typename R2 = typename safe_minmax_impl::TypeOr<
R,
typename safe_minmax_impl::MType<
typename safe_minmax_impl::UnderlyingType<T1>::type,
typename safe_minmax_impl::UnderlyingType<T2>::type>::max_t>::type>
constexpr R2 SafeMax(T1 a, T2 b) {
static_assert(IsIntlike<T1>::value || std::is_floating_point<T1>::value,
"The first argument must be integral or floating-point");

View File

@ -62,12 +62,19 @@ static_assert(TypeCheckMinMax<uint64_t, uint8_t, uint8_t, uint64_t>(), "");
static_assert(TypeCheckMinMax<uint64_t, int64_t, int64_t, uint64_t>(), "");
static_assert(TypeCheckMinMax<uint64_t, uint64_t, uint64_t, uint64_t>(), "");
// SafeMin/SafeMax: Check that we can use enum types.
enum DefaultE { kFoo = -17 };
enum UInt8E : uint8_t { kBar = 17 };
static_assert(TypeCheckMinMax<unsigned, DefaultE, int, unsigned>(), "");
static_assert(TypeCheckMinMax<unsigned, UInt8E, uint8_t, unsigned>(), "");
static_assert(TypeCheckMinMax<DefaultE, UInt8E, int, int>(), "");
// SafeMin/SafeMax: Check that we can use enum types.
static_assert(TypeCheckMinMax<unsigned, unsigned, unsigned, unsigned>(), "");
static_assert(TypeCheckMinMax<unsigned, DefaultE, int, unsigned>(), "");
static_assert(TypeCheckMinMax<unsigned, UInt8E, uint8_t, unsigned>(), "");
static_assert(TypeCheckMinMax<DefaultE, unsigned, int, unsigned>(), "");
static_assert(TypeCheckMinMax<DefaultE, DefaultE, int, int>(), "");
static_assert(TypeCheckMinMax<DefaultE, UInt8E, int, int>(), "");
static_assert(TypeCheckMinMax< UInt8E, unsigned, uint8_t, unsigned>(), "");
static_assert(TypeCheckMinMax< UInt8E, DefaultE, int, int>(), "");
static_assert(TypeCheckMinMax< UInt8E, UInt8E, uint8_t, uint8_t>(), "");
using ld = long double;