// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
// This is not an explicit constructor because we implicitly upgrade regular // numerics to ClampedNumerics to make them easier to use. template <typename Src>
constexpr ClampedNumeric(Src value) // NOLINT(runtime/explicit)
: value_(saturated_cast<T>(value)) {
static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric.");
}
// This is not an explicit constructor because we want a seamless conversion // from StrictNumeric types. template <typename Src>
constexpr ClampedNumeric(
StrictNumeric<Src> value) // NOLINT(runtime/explicit)
: value_(saturated_cast<T>(static_cast<Src>(value))) {}
// Returns a ClampedNumeric of the specified type, cast from the current // ClampedNumeric, and saturated to the destination type. template <typename Dst>
constexpr ClampedNumeric<typename UnderlyingType<Dst>::type> Cast() const { return *this;
}
constexpr ClampedNumeric operator-() const { // The negation of two's complement int min is int min, so that's the // only overflow case where we will saturate. return ClampedNumeric<T>(SaturatedNegWrapper(value_));
}
constexpr ClampedNumeric Abs() const { // The negation of two's complement int min is int min, so that's the // only overflow case where we will saturate. return ClampedNumeric<T>(SaturatedAbsWrapper(value_));
}
// 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 ClampedNumeric<typename UnsignedOrFloatForSize<T>::type>
UnsignedAbs() const { return ClampedNumeric<typename UnsignedOrFloatForSize<T>::type>(
SafeUnsignedAbs(value_));
}
// These perform the actual math operations on the ClampedNumerics. // Binary arithmetic operations. template <template <typename, typename, typename> class M, typename L, typename R> static constexpr ClampedNumeric MathOp(const L lhs, const R rhs) { using Math = typename MathWrapper<M, L, R>::math; return ClampedNumeric<T>(
Math::templateDo<T>(Wrapper<L>::value(lhs), Wrapper<R>::value(rhs)));
}
// Assignment arithmetic operations. template <template <typename, typename, typename> class M, typename R>
constexpr ClampedNumeric& MathOp(const R rhs) { using Math = typename MathWrapper<M, T, R>::math;
*this =
ClampedNumeric<T>(Math::templateDo<T>(value_, Wrapper<R>::value(rhs))); return *this;
}
// This method extracts the raw integer value without saturating it to the // destination type as the conversion operator does. This is useful when // e.g. assigning to an auto type or passing as a deduced template parameter.
constexpr T RawValue() const { return value_; }
private:
T value_;
// These wrappers allow us to handle state the same way for both // ClampedNumeric and POD arithmetic types. template <typename Src> struct Wrapper { static constexpr Src value(Src value) { returnstatic_cast<typename UnderlyingType<Src>::type>(value);
}
};
};
// Convience wrapper to return a new ClampedNumeric from the provided arithmetic // or ClampedNumericType. template <typename T>
constexpr ClampedNumeric<typename UnderlyingType<T>::type> MakeClampedNum( const T value) { return value;
}
#if !BASE_NUMERICS_DISABLE_OSTREAM_OPERATORS // Overload the ostream output operator to make logging work nicely. template <typename T>
std::ostream& operator<<(std::ostream& os, const ClampedNumeric<T>& value) {
os << static_cast<T>(value); return os;
} #endif
// These implement the variadic wrapper for the math operations. template <template <typename, typename, typename> class M, typename L, typename R>
constexpr ClampedNumeric<typename MathWrapper<M, L, R>::type> ClampMathOp( const L lhs, const R rhs) { using Math = typename MathWrapper<M, L, R>::math; return ClampedNumeric<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 ClampedNumeric<typename ResultType<M, L, R, Args...>::type>
ClampMathOp(const L lhs, const R rhs, const Args... args) { return ClampMathOp<M>(ClampMathOp<M>(lhs, rhs), args...);
}
using internal::ClampedNumeric; using internal::MakeClampedNum; using internal::ClampMax; using internal::ClampMin; using internal::ClampAdd; using internal::ClampSub; using internal::ClampMul; using internal::ClampDiv; using internal::ClampMod; using internal::ClampLsh; using internal::ClampRsh; using internal::ClampAnd; using internal::ClampOr; using internal::ClampXor;
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.