crashpad/util/numeric/checked_range.h
Mark Mentovai 48b1964d1b Use implicit_cast<> instead of static_cast<> whenever possible.
implicit_cast<> only performs a cast in cases where an implicit
conversion would be possible. It’s even safer than static_cast<> It’s an
“explicit implicit” cast, which is not normally necsesary, but is
frequently required when working with the ?: operator, functions like
std::min() and std::max(), and logging and testing macros.

The public style guide does not mention implicit_cast<> only because it
is not part of the standard library, but would otherwise require it in
these situations. Since base does provide implicit_cast<>, it should be
used whenever possible.

The only uses of static_cast<> not converted to implicit_cast<> are
those that require static_cast<>, such as those that assign an integer
constant to a variable of an enum type.

R=rsesek@chromium.org

Review URL: https://codereview.chromium.org/700383007
2014-11-06 16:44:38 -05:00

116 lines
3.7 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. All rights reserved.
//
// 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 "base/basictypes.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/numerics/safe_math.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();
}
private:
ValueType base_;
SizeType size_;
DISALLOW_COPY_AND_ASSIGN(CheckedRange);
};
} // namespace crashpad
#endif // CRASHPAD_UTIL_NUMERIC_CHECKED_RANGE_H_