mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
Mark checked_cast, dchecked_cast, and saturated_cast as constexpr
to allow use them in other constexpr functions. c++14 extends what can be in constexpr function making this change possible. Bug: None Change-Id: I6ae55b0b9b936021b57aa83ea5dd77d73be511a3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/159026 Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#29743}
This commit is contained in:
parent
fd80438111
commit
2bc811ea07
2 changed files with 19 additions and 17 deletions
|
@ -23,7 +23,7 @@ namespace rtc {
|
||||||
// Convenience function that returns true if the supplied value is in range
|
// Convenience function that returns true if the supplied value is in range
|
||||||
// for the destination type.
|
// for the destination type.
|
||||||
template <typename Dst, typename Src>
|
template <typename Dst, typename Src>
|
||||||
inline bool IsValueInRangeForNumericType(Src value) {
|
inline constexpr bool IsValueInRangeForNumericType(Src value) {
|
||||||
return internal::RangeCheck<Dst>(value) == internal::TYPE_VALID;
|
return internal::RangeCheck<Dst>(value) == internal::TYPE_VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,12 +32,12 @@ inline bool IsValueInRangeForNumericType(Src value) {
|
||||||
// conversion will not overflow or underflow. NaN source will always trigger
|
// conversion will not overflow or underflow. NaN source will always trigger
|
||||||
// the [D]CHECK.
|
// the [D]CHECK.
|
||||||
template <typename Dst, typename Src>
|
template <typename Dst, typename Src>
|
||||||
inline Dst checked_cast(Src value) {
|
inline constexpr Dst checked_cast(Src value) {
|
||||||
RTC_CHECK(IsValueInRangeForNumericType<Dst>(value));
|
RTC_CHECK(IsValueInRangeForNumericType<Dst>(value));
|
||||||
return static_cast<Dst>(value);
|
return static_cast<Dst>(value);
|
||||||
}
|
}
|
||||||
template <typename Dst, typename Src>
|
template <typename Dst, typename Src>
|
||||||
inline Dst dchecked_cast(Src value) {
|
inline constexpr Dst dchecked_cast(Src value) {
|
||||||
RTC_DCHECK(IsValueInRangeForNumericType<Dst>(value));
|
RTC_DCHECK(IsValueInRangeForNumericType<Dst>(value));
|
||||||
return static_cast<Dst>(value);
|
return static_cast<Dst>(value);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ inline Dst dchecked_cast(Src value) {
|
||||||
// that the specified numeric conversion will saturate rather than overflow or
|
// that the specified numeric conversion will saturate rather than overflow or
|
||||||
// underflow. NaN assignment to an integral will trigger a RTC_CHECK condition.
|
// underflow. NaN assignment to an integral will trigger a RTC_CHECK condition.
|
||||||
template <typename Dst, typename Src>
|
template <typename Dst, typename Src>
|
||||||
inline Dst saturated_cast(Src value) {
|
inline constexpr Dst saturated_cast(Src value) {
|
||||||
// Optimization for floating point values, which already saturate.
|
// Optimization for floating point values, which already saturate.
|
||||||
if (std::numeric_limits<Dst>::is_iec559)
|
if (std::numeric_limits<Dst>::is_iec559)
|
||||||
return static_cast<Dst>(value);
|
return static_cast<Dst>(value);
|
||||||
|
|
|
@ -101,13 +101,13 @@ struct RangeCheckImpl {};
|
||||||
// Dst range always contains the result: nothing to check.
|
// Dst range always contains the result: nothing to check.
|
||||||
template <typename Dst, typename Src, DstSign IsDstSigned, SrcSign IsSrcSigned>
|
template <typename Dst, typename Src, DstSign IsDstSigned, SrcSign IsSrcSigned>
|
||||||
struct RangeCheckImpl<Dst, Src, IsDstSigned, IsSrcSigned, CONTAINS_RANGE> {
|
struct RangeCheckImpl<Dst, Src, IsDstSigned, IsSrcSigned, CONTAINS_RANGE> {
|
||||||
static RangeCheckResult Check(Src value) { return TYPE_VALID; }
|
static constexpr RangeCheckResult Check(Src value) { return TYPE_VALID; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Signed to signed narrowing.
|
// Signed to signed narrowing.
|
||||||
template <typename Dst, typename Src>
|
template <typename Dst, typename Src>
|
||||||
struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
|
struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
|
||||||
static RangeCheckResult Check(Src value) {
|
static constexpr RangeCheckResult Check(Src value) {
|
||||||
typedef std::numeric_limits<Dst> DstLimits;
|
typedef std::numeric_limits<Dst> DstLimits;
|
||||||
return DstLimits::is_iec559
|
return DstLimits::is_iec559
|
||||||
? BASE_NUMERIC_RANGE_CHECK_RESULT(
|
? BASE_NUMERIC_RANGE_CHECK_RESULT(
|
||||||
|
@ -122,7 +122,7 @@ struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
|
||||||
// Unsigned to unsigned narrowing.
|
// Unsigned to unsigned narrowing.
|
||||||
template <typename Dst, typename Src>
|
template <typename Dst, typename Src>
|
||||||
struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
|
struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
|
||||||
static RangeCheckResult Check(Src value) {
|
static constexpr RangeCheckResult Check(Src value) {
|
||||||
typedef std::numeric_limits<Dst> DstLimits;
|
typedef std::numeric_limits<Dst> DstLimits;
|
||||||
return BASE_NUMERIC_RANGE_CHECK_RESULT(
|
return BASE_NUMERIC_RANGE_CHECK_RESULT(
|
||||||
value <= static_cast<Src>(DstLimits::max()), true);
|
value <= static_cast<Src>(DstLimits::max()), true);
|
||||||
|
@ -132,7 +132,7 @@ struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
|
||||||
// Unsigned to signed.
|
// Unsigned to signed.
|
||||||
template <typename Dst, typename Src>
|
template <typename Dst, typename Src>
|
||||||
struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
|
struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
|
||||||
static RangeCheckResult Check(Src value) {
|
static constexpr RangeCheckResult Check(Src value) {
|
||||||
typedef std::numeric_limits<Dst> DstLimits;
|
typedef std::numeric_limits<Dst> DstLimits;
|
||||||
return sizeof(Dst) > sizeof(Src)
|
return sizeof(Dst) > sizeof(Src)
|
||||||
? TYPE_VALID
|
? TYPE_VALID
|
||||||
|
@ -144,14 +144,16 @@ struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
|
||||||
// Signed to unsigned.
|
// Signed to unsigned.
|
||||||
template <typename Dst, typename Src>
|
template <typename Dst, typename Src>
|
||||||
struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
|
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<Dst> DstLimits;
|
typedef std::numeric_limits<Src> SrcLimits;
|
||||||
typedef std::numeric_limits<Src> SrcLimits;
|
// Compare based on max_exponent, which we must compute for integrals.
|
||||||
// Compare based on max_exponent, which we must compute for integrals.
|
static constexpr size_t DstMaxExponent() { return sizeof(Dst) * 8; }
|
||||||
static const size_t kDstMaxExponent = sizeof(Dst) * 8;
|
static constexpr size_t SrcMaxExponent() {
|
||||||
static const size_t kSrcMaxExponent =
|
return SrcLimits::is_iec559 ? SrcLimits::max_exponent
|
||||||
SrcLimits::is_iec559 ? SrcLimits::max_exponent : (sizeof(Src) * 8 - 1);
|
: (sizeof(Src) * 8 - 1);
|
||||||
return (kDstMaxExponent >= kSrcMaxExponent)
|
}
|
||||||
|
static constexpr RangeCheckResult Check(Src value) {
|
||||||
|
return (DstMaxExponent() >= SrcMaxExponent())
|
||||||
? BASE_NUMERIC_RANGE_CHECK_RESULT(true,
|
? BASE_NUMERIC_RANGE_CHECK_RESULT(true,
|
||||||
value >= static_cast<Src>(0))
|
value >= static_cast<Src>(0))
|
||||||
: BASE_NUMERIC_RANGE_CHECK_RESULT(
|
: BASE_NUMERIC_RANGE_CHECK_RESULT(
|
||||||
|
@ -161,7 +163,7 @@ struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Dst, typename Src>
|
template <typename Dst, typename Src>
|
||||||
inline RangeCheckResult RangeCheck(Src value) {
|
inline constexpr RangeCheckResult RangeCheck(Src value) {
|
||||||
static_assert(std::numeric_limits<Src>::is_specialized,
|
static_assert(std::numeric_limits<Src>::is_specialized,
|
||||||
"argument must be numeric");
|
"argument must be numeric");
|
||||||
static_assert(std::numeric_limits<Dst>::is_specialized,
|
static_assert(std::numeric_limits<Dst>::is_specialized,
|
||||||
|
|
Loading…
Reference in a new issue