kicad/thirdparty/sentry-native/external/crashpad/util/numeric/checked_range.h

141 lines
4.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2014 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CRASHPAD_UTIL_NUMERIC_CHECKED_RANGE_H_
#define CRASHPAD_UTIL_NUMERIC_CHECKED_RANGE_H_
#include <limits>
#include <tuple>
#include "base/check.h"
#include "base/numerics/safe_conversions.h"
#include "base/numerics/safe_math.h"
#include "util/misc/implicit_cast.h"
namespace crashpad {
//! \brief Ensures that a range, composed of a base and size, does not overflow
//! its data type.
template <typename ValueType, typename SizeType = ValueType>
class CheckedRange {
public:
CheckedRange(ValueType base, SizeType size) {
static_assert(!std::numeric_limits<SizeType>::is_signed,
"SizeType must be unsigned");
SetRange(base, size);
}
//! \brief Sets the ranges base and size to \a base and \a size,
//! respectively.
void SetRange(ValueType base, SizeType size) {
base_ = base;
size_ = size;
}
//! \brief The ranges base.
ValueType base() const { return base_; }
//! \brief The ranges size.
SizeType size() const { return size_; }
//! \brief The ranges end (its base plus its size).
ValueType end() const { return base_ + size_; }
//! \brief Returns the validity of the range.
//!
//! \return `true` if the range is valid, `false` otherwise.
//!
//! A range is valid if its size can be converted to the ranges data type
//! without data loss, and if its end (base plus size) can be computed without
//! overflowing its data type.
bool IsValid() const {
if (!base::IsValueInRangeForNumericType<ValueType, SizeType>(size_)) {
return false;
}
base::CheckedNumeric<ValueType> checked_end(base_);
checked_end += implicit_cast<ValueType>(size_);
return checked_end.IsValid();
}
//! \brief Returns whether the range contains another value.
//!
//! \param[in] value The (possibly) contained value.
//!
//! \return `true` if the range contains \a value, `false` otherwise.
//!
//! A range contains a value if the value is greater than or equal to its
//! base, and less than its end (base plus size).
//!
//! This method must only be called if IsValid() would return `true`.
bool ContainsValue(ValueType value) const {
DCHECK(IsValid());
return value >= base() && value < end();
}
//! \brief Returns whether the range contains another range.
//!
//! \param[in] that The (possibly) contained range.
//!
//! \return `true` if `this` range, the containing range, contains \a that,
//! the contained range. `false` otherwise.
//!
//! A range contains another range when the contained ranges base is greater
//! than or equal to the containing ranges base, and the contained ranges
//! end is less than or equal to the containing ranges end.
//!
//! This method must only be called if IsValid() would return `true` for both
//! CheckedRange objects involved.
bool ContainsRange(const CheckedRange<ValueType, SizeType>& that) const {
DCHECK(IsValid());
DCHECK(that.IsValid());
return that.base() >= base() && that.end() <= end();
}
//! \brief Returns whether the range overlaps another range.
//!
//! \param[in] that The (possibly) overlapping range.
//!
//! \return `true` if `this` range, the first range, overlaps \a that,
//! the provided range. `false` otherwise.
//!
//! Ranges are considered to be closed-open [base, end) for this test. Zero
//! length ranges are never considered to overlap another range.
//!
//! This method must only be called if IsValid() would return `true` for both
//! CheckedRange objects involved.
bool OverlapsRange(const CheckedRange<ValueType, SizeType>& that) const {
DCHECK(IsValid());
DCHECK(that.IsValid());
if (size() == 0 || that.size() == 0)
return false;
return base() < that.end() && that.base() < end();
}
bool operator<(const CheckedRange& other) const {
return std::tie(base_, size_) < std::tie(other.base_, other.size_);
}
private:
ValueType base_;
SizeType size_;
};
} // namespace crashpad
#endif // CRASHPAD_UTIL_NUMERIC_CHECKED_RANGE_H_