/* * Copyright 2013-2020 Software Radio Systems Limited * * This file is part of srsLTE. * * srsLTE is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * srsLTE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * A copy of the GNU Affero General Public License can be found in * the LICENSE file in the top-level directory of this distribution * and at http://www.gnu.org/licenses/. * */ #ifndef SRSLTE_INTERVAL_H #define SRSLTE_INTERVAL_H #include #include namespace srslte { /// Representation of an interval between two numeric-types in the math representation [start, stop) template class interval { // TODO: older compilers may not have defined this C++11 trait. #if (defined(__clang__) && (__clang_major__ >= 5)) || (defined(__GNUG__) && (__GNUC__ >= 5)) static_assert(std::is_trivially_copyable::value, "Expected to be trivially copyable"); #endif public: T start; T stop; interval() : start(T{}), stop(T{}) {} interval(T start_, T stop_) : start(start_), stop(stop_) {} bool empty() const { return stop <= start; } T length() const { return stop > start ? stop - start : 0; } void set_length(T len) { stop = start + len; } void displace_by(int offset) { start += offset; stop += offset; } void displace_to(T start_point) { stop = start_point + length(); start = start_point; } bool overlaps(interval other) const { return start < other.stop and other.start < stop; } bool contains(T point) const { return start <= point and point < stop; } std::string to_string() const { std::string s = "[" + std::to_string(start) + "," + std::to_string(stop) + ")"; return s; } }; template bool operator==(const interval& lhs, const interval& rhs) { return lhs.start == rhs.start and lhs.stop == rhs.stop; } template bool operator!=(const interval& lhs, const interval& rhs) { return not(lhs == rhs); } template bool operator<(const interval& lhs, const interval& rhs) { return lhs.start < rhs.start or (lhs.start == rhs.start and lhs.stop < rhs.stop); } //! Union of intervals template interval operator|(const interval& lhs, const interval& rhs) { if (not lhs.overlaps(rhs)) { return interval{}; } return {std::min(lhs.start, rhs.start), std::max(lhs.stop, rhs.stop)}; } template interval make_union(const interval& lhs, const interval& rhs) { return lhs | rhs; } //! Intersection of intervals template interval operator&(const interval& lhs, const interval& rhs) { if (not lhs.overlaps(rhs)) { return interval{}; } return interval{std::max(lhs.start, rhs.start), std::min(lhs.stop, rhs.stop)}; } template interval make_intersection(const interval& lhs, const interval& rhs) { return lhs & rhs; } template std::ostream& operator<<(std::ostream& out, const interval& interv) { out << interv.to_string(); return out; } } // namespace srslte #endif // SRSLTE_INTERVAL_H