// 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 <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 range’s base and size to \a base and \a size,
  //!     respectively.
  void SetRange(ValueType base, SizeType size) {
    base_ = base;
    size_ = size;
  }

  //! \brief The range’s base.
  ValueType base() const { return base_; }

  //! \brief The range’s size.
  SizeType size() const { return size_; }

  //! \brief The range’s 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 range’s 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 range’s base is greater
  //! than or equal to the containing range’s base, and the contained range’s
  //! end is less than or equal to the containing range’s 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_
