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}
diff --git a/rtc_base/numerics/safe_conversions.h b/rtc_base/numerics/safe_conversions.h
index 58efcaa..5d58672 100644
--- a/rtc_base/numerics/safe_conversions.h
+++ b/rtc_base/numerics/safe_conversions.h
@@ -23,7 +23,7 @@
 // Convenience function that returns true if the supplied value is in range
 // for the destination type.
 template <typename Dst, typename Src>
-inline bool IsValueInRangeForNumericType(Src value) {
+inline constexpr bool IsValueInRangeForNumericType(Src value) {
   return internal::RangeCheck<Dst>(value) == internal::TYPE_VALID;
 }
 
@@ -32,12 +32,12 @@
 // conversion will not overflow or underflow. NaN source will always trigger
 // the [D]CHECK.
 template <typename Dst, typename Src>
-inline Dst checked_cast(Src value) {
+inline constexpr Dst checked_cast(Src value) {
   RTC_CHECK(IsValueInRangeForNumericType<Dst>(value));
   return static_cast<Dst>(value);
 }
 template <typename Dst, typename Src>
-inline Dst dchecked_cast(Src value) {
+inline constexpr Dst dchecked_cast(Src value) {
   RTC_DCHECK(IsValueInRangeForNumericType<Dst>(value));
   return static_cast<Dst>(value);
 }
@@ -46,7 +46,7 @@
 // that the specified numeric conversion will saturate rather than overflow or
 // underflow. NaN assignment to an integral will trigger a RTC_CHECK condition.
 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.
   if (std::numeric_limits<Dst>::is_iec559)
     return static_cast<Dst>(value);
diff --git a/rtc_base/numerics/safe_conversions_impl.h b/rtc_base/numerics/safe_conversions_impl.h
index 9b4f1c6..e924ce3 100644
--- a/rtc_base/numerics/safe_conversions_impl.h
+++ b/rtc_base/numerics/safe_conversions_impl.h
@@ -101,13 +101,13 @@
 // 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; }
+  static constexpr 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) {
+  static constexpr RangeCheckResult Check(Src value) {
     typedef std::numeric_limits<Dst> DstLimits;
     return DstLimits::is_iec559
                ? BASE_NUMERIC_RANGE_CHECK_RESULT(
@@ -122,7 +122,7 @@
 // Unsigned to unsigned narrowing.
 template <typename Dst, typename Src>
 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;
     return BASE_NUMERIC_RANGE_CHECK_RESULT(
         value <= static_cast<Src>(DstLimits::max()), true);
@@ -132,7 +132,7 @@
 // Unsigned to signed.
 template <typename Dst, typename Src>
 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;
     return sizeof(Dst) > sizeof(Src)
                ? TYPE_VALID
@@ -144,14 +144,16 @@
 // 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)
+  typedef std::numeric_limits<Dst> DstLimits;
+  typedef std::numeric_limits<Src> SrcLimits;
+  // Compare based on max_exponent, which we must compute for integrals.
+  static constexpr size_t DstMaxExponent() { return sizeof(Dst) * 8; }
+  static constexpr size_t SrcMaxExponent() {
+    return SrcLimits::is_iec559 ? SrcLimits::max_exponent
+                                : (sizeof(Src) * 8 - 1);
+  }
+  static constexpr RangeCheckResult Check(Src value) {
+    return (DstMaxExponent() >= SrcMaxExponent())
                ? BASE_NUMERIC_RANGE_CHECK_RESULT(true,
                                                  value >= static_cast<Src>(0))
                : BASE_NUMERIC_RANGE_CHECK_RESULT(
@@ -161,7 +163,7 @@
 };
 
 template <typename Dst, typename Src>
-inline RangeCheckResult RangeCheck(Src value) {
+inline constexpr RangeCheckResult RangeCheck(Src value) {
   static_assert(std::numeric_limits<Src>::is_specialized,
                 "argument must be numeric");
   static_assert(std::numeric_limits<Dst>::is_specialized,