blob: f7f4fa56c06834456abacd49355b4cc372346cb2 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include <cinttypes>
#include <cstddef>
#include <limits>
#include <range/range.h>
#include <zircon/assert.h>
namespace range {
template <typename T> Range<T>::Range(T start, T end) {
start_ = start;
end_ = end;
}
template <typename T> bool Range<T>::operator==(Range<T> const& y) const {
return (start() == y.start()) && (end() == y.end());
}
template <typename T> bool Range<T>::operator!=(Range<T> const& y) const {
return (start() != y.start()) || (end() != y.end());
}
template <typename T> T Range<T>::length() const {
if (end_ <= start_) {
return T(0);
}
return end_ - start_;
}
template <typename T> bool Overlap(const Range<T>& x, const Range<T>& y) {
if (x.length() == 0 || y.length() == 0) {
return false;
}
T max_start = std::max(x.start(), y.start());
T min_end = std::min(x.end(), y.end());
return max_start < min_end;
}
template <typename T> bool Adjacent(const Range<T>& x, const Range<T>& y) {
if (x.length() == 0 || y.length() == 0) {
return false;
}
if (Overlap(x, y)) {
return false;
}
T max_start = std::max(x.start(), y.start());
T min_end = std::min(x.end(), y.end());
return max_start == min_end;
}
template <typename T> bool Mergable(const Range<T>& x, const Range<T>& y) {
return Adjacent(x, y) || Overlap(x, y);
}
template <typename T>
fit::result<Range<T>, zx_status_t> Merge(const Range<T>& x, const Range<T>& y) {
if (!Mergable(x, y)) {
return fit::error<zx_status_t>(ZX_ERR_OUT_OF_RANGE);
}
T merged_start = std::min(x.start(), y.start());
T merged_end = std::max(x.end(), y.end());
return fit::ok(Range<T>(merged_start, merged_end));
}
template class Range<uint64_t>;
template bool Overlap<uint64_t>(const Range<uint64_t>& x, const Range<uint64_t>& y);
template bool Adjacent<uint64_t>(const Range<uint64_t>& x, const Range<uint64_t>& y);
template bool Mergable<uint64_t>(const Range<uint64_t>& x, const Range<uint64_t>& y);
template fit::result<Range<uint64_t>, zx_status_t> Merge(const Range<uint64_t>& x,
const Range<uint64_t>& y);
} // namespace range