// Strictly speaking, this is not necessary, but declaring this allows class // template argument deduction to be used so that it is possible to simply // write `CheckedNumeric(777)` instead of `CheckedNumeric<int>(777)`. // NOLINTNEXTLINE(google-explicit-constructor)
constexpr CheckedNumeric(T value) : state_(value) {}
// This is not an explicit constructor because we implicitly upgrade regular // numerics to CheckedNumerics to make them easier to use. template <typename Src, typename = std::enable_if_t<std::is_arithmetic_v<Src>>> // NOLINTNEXTLINE(google-explicit-constructor)
constexpr CheckedNumeric(Src value) : state_(value) {}
// This is not an explicit constructor because we want a seamless conversion // from StrictNumeric types. template <typename Src> // NOLINTNEXTLINE(google-explicit-constructor)
constexpr CheckedNumeric(StrictNumeric<Src> value)
: state_(static_cast<Src>(value)) {}
// IsValid() - The public API to test if a CheckedNumeric is currently valid. // A range checked destination type can be supplied using the Dst template // parameter. template <typename Dst = T>
constexpr bool IsValid() const { return state_.is_valid() &&
IsValueInRangeForNumericType<Dst>(state_.value());
}
// AssignIfValid(Dst) - Assigns the underlying value if it is currently valid // and is within the range supported by the destination type. Returns true if // successful and false otherwise. template <typename Dst> #ifdefined(__clang__) || defined(__GNUC__)
__attribute__((warn_unused_result)) #elifdefined(_MSC_VER)
_Check_return_ #endif
constexpr bool
AssignIfValid(Dst* result) const { return BASE_NUMERICS_LIKELY(IsValid<Dst>())
? ((*result = static_cast<Dst>(state_.value())), true)
: false;
}
// ValueOrDie() - The primary accessor for the underlying value. If the // current state is not valid it will CHECK and crash. // A range checked destination type can be supplied using the Dst template // parameter, which will trigger a CHECK if the value is not in bounds for // the destination. // The CHECK behavior can be overridden by supplying a handler as a // template parameter, for test code, etc. However, the handler cannot access // the underlying value, and it is not available through other means. template <typename Dst = T, class CheckHandler = CheckOnFailure>
constexpr StrictNumeric<Dst> ValueOrDie() const { return BASE_NUMERICS_LIKELY(IsValid<Dst>())
? static_cast<Dst>(state_.value())
: CheckHandler::template HandleFailure<Dst>();
}
// ValueOrDefault(T default_value) - A convenience method that returns the // current value if the state is valid, and the supplied default_value for // any other state. // A range checked destination type can be supplied using the Dst template // parameter. WARNING: This function may fail to compile or CHECK at runtime // if the supplied default_value is not within range of the destination type. template <typename Dst = T, typename Src>
constexpr StrictNumeric<Dst> ValueOrDefault(const Src default_value) const { return BASE_NUMERICS_LIKELY(IsValid<Dst>())
? static_cast<Dst>(state_.value())
: checked_cast<Dst>(default_value);
}
// Returns a checked numeric of the specified type, cast from the current // CheckedNumeric. If the current state is invalid or the destination cannot // represent the result then the returned CheckedNumeric will be invalid. template <typename Dst>
constexpr CheckedNumeric<typename UnderlyingType<Dst>::type> Cast() const { return *this;
}
// This friend method is available solely for providing more detailed logging // in the tests. Do not implement it in production code, because the // underlying values may change at any time. template <typename U> friend U GetNumericValueForTest(const CheckedNumeric<U>& src);
constexpr CheckedNumeric operator-() const { // Use an optimized code path for a known run-time variable. if (!IsConstantEvaluated() && std::is_signed_v<T> &&
std::is_floating_point_v<T>) { return FastRuntimeNegate();
} // The negation of two's complement int min is int min. constbool is_valid =
IsValid() &&
(!std::is_signed_v<T> || std::is_floating_point_v<T> ||
NegateWrapper(state_.value()) != std::numeric_limits<T>::lowest()); return CheckedNumeric<T>(NegateWrapper(state_.value()), is_valid);
}
// This function is available only for integral types. It returns an unsigned // integer of the same width as the source type, containing the absolute value // of the source, and properly handling signed min.
constexpr CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>
UnsignedAbs() const { return CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>(
SafeUnsignedAbs(state_.value()), state_.is_valid());
}
constexpr CheckedNumeric operator--(int) { // TODO(pkasting): Consider std::exchange() once it's constexpr in C++20. const CheckedNumeric value = *this;
*this -= 1; return value;
}
// These perform the actual math operations on the CheckedNumerics. // Binary arithmetic operations. template <template <typename, typename, typename> class M, typename L, typename R> static constexpr CheckedNumeric MathOp(const L lhs, const R rhs) { using Math = typename MathWrapper<M, L, R>::math;
T result = 0; constbool is_valid =
Wrapper<L>::is_valid(lhs) && Wrapper<R>::is_valid(rhs) &&
Math::Do(Wrapper<L>::value(lhs), Wrapper<R>::value(rhs), &result); return CheckedNumeric<T>(result, is_valid);
}
// Assignment arithmetic operations. template <template <typename, typename, typename> class M, typename R>
constexpr CheckedNumeric& MathOp(const R rhs) { using Math = typename MathWrapper<M, T, R>::math;
T result = 0; // Using T as the destination saves a range check. constbool is_valid =
state_.is_valid() && Wrapper<R>::is_valid(rhs) &&
Math::Do(state_.value(), Wrapper<R>::value(rhs), &result);
*this = CheckedNumeric<T>(result, is_valid); return *this;
}
// These wrappers allow us to handle state the same way for both // CheckedNumeric and POD arithmetic types. template <typename Src> struct Wrapper { static constexpr bool is_valid(Src) { returntrue; } static constexpr Src value(Src value) { return value; }
};
// Convenience wrapper to return a new CheckedNumeric from the provided // arithmetic or CheckedNumericType. template <typename T>
constexpr CheckedNumeric<typename UnderlyingType<T>::type> MakeCheckedNum( const T value) { return value;
}
// These implement the variadic wrapper for the math operations. template <template <typename, typename, typename> class M, typename L, typename R>
constexpr CheckedNumeric<typename MathWrapper<M, L, R>::type> CheckMathOp( const L lhs, const R rhs) { using Math = typename MathWrapper<M, L, R>::math; return CheckedNumeric<typename Math::result_type>::template MathOp<M>(lhs,
rhs);
}
// General purpose wrapper template for arithmetic operations. template <template <typename, typename, typename> class M, typename L, typename R, typename... Args>
constexpr auto CheckMathOp(const L lhs, const R rhs, const Args... args) { return CheckMathOp<M>(CheckMathOp<M>(lhs, rhs), args...);
}
// These are some extra StrictNumeric operators to support simple pointer // arithmetic with our result types. Since wrapping on a pointer is always // bad, we trigger the CHECK condition here. template <typename L, typename R>
L* operator+(L* lhs, const StrictNumeric<R> rhs) { const uintptr_t result = CheckAdd(reinterpret_cast<uintptr_t>(lhs),
CheckMul(sizeof(L), static_cast<R>(rhs)))
.template ValueOrDie<uintptr_t>(); returnreinterpret_cast<L*>(result);
}
using internal::CheckAdd; using internal::CheckAnd; using internal::CheckDiv; using internal::CheckedNumeric; using internal::CheckLsh; using internal::CheckMax; using internal::CheckMin; using internal::CheckMod; using internal::CheckMul; using internal::CheckOr; using internal::CheckRsh; using internal::CheckSub; using internal::CheckXor; using internal::IsValidForType; using internal::MakeCheckedNum; using internal::ValueOrDefaultForType; using internal::ValueOrDieForType;
} // namespace base
#endif// BASE_NUMERICS_CHECKED_MATH_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-08-22)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.