File indexing completed on 2024-03-24 17:26:38
0001 /* 0002 This file is part of the Okteta Core library, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2003, 2007-2008 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #ifndef OKTETA_RANGE_HPP 0010 #define OKTETA_RANGE_HPP 0011 0012 namespace Okteta { 0013 0014 /** This template describes a range. 0015 * A range is something with a start and an end. 0016 * The start is a value relative before the end. 0017 * The distance cannot be estimated. 0018 * 0019 * @author Friedrich W. H. Kossebau 0020 */ 0021 template <typename T> 0022 class Range 0023 { 0024 public: 0025 Range(T S, T E) 0026 : Start(S) 0027 , End(E) 0028 {} 0029 Range() 0030 : Start(null()) 0031 , End(null()) 0032 {} 0033 Range(const Range& R) = default; 0034 ~Range() = default; 0035 0036 public: 0037 Range& operator=(const Range& R) = default; 0038 0039 public: 0040 bool operator==(const Range& R) const 0041 { return (Start == R.Start && End == R.End) || (!isValid() && !R.isValid()); } 0042 bool operator!=(const Range& R) const 0043 { return ((Start != R.Start) || (End != R.End)) && (isValid() || R.isValid()); } 0044 0045 public: // modification access 0046 /** sets the first and the last index of the range */ 0047 void set(T S, T E) { Start = S; End = E; } 0048 /** sets the first and the last index of the range */ 0049 void set(const Range& R) { Start = R.Start; End = R.End; } 0050 /** sets the first index of the range */ 0051 void setStart(T S) { Start = S; } 0052 /** sets the last index of the range */ 0053 void setEnd(T E) { End = E; } 0054 /** sets the range to null */ 0055 void unset() { Start = End = null(); } 0056 /** restricts the range to Limit. If one of both ranges is invalid the behaviour is undefined */ 0057 void restrictTo(const Range& Limit) 0058 { if (Start < Limit.start()) {Start = Limit.start();} if (End > Limit.end()) {End = Limit.end();}} 0059 /** restricts the start to Limit. If the range is invalid the behaviour is undefined */ 0060 void restrictStartTo(T Limit) { if (Start < Limit) {Start = Limit;}} 0061 /** restricts the end to Limit. If the range is invalid the behaviour is undefined */ 0062 void restrictEndTo(T Limit) { if (End > Limit) {End = Limit;}} 0063 /** extends the range to Limit. If one of both is invalid the behaviour is undefined */ 0064 void extendTo(const Range& Limit) 0065 { if (Start > Limit.start()) {Start = Limit.start();} if (End < Limit.end()) {End = Limit.end();}} 0066 /** extends the start to Limit. If the range is invalid the behaviour is undefined */ 0067 void extendStartTo(T Limit) { if (Start > Limit) {Start = Limit;}} 0068 /** extends the end to Limit. If the range is invalid the behaviour is undefined */ 0069 void extendEndTo(T Limit) { if (End < Limit) {End = Limit;}} 0070 /** moves the start by D. If the range is invalid the behaviour is undefined */ 0071 void moveStartBy(T D) { Start += D; } 0072 /** moves the end by D. If the range is invalid the behaviour is undefined */ 0073 void moveEndBy(T D) { End += D; } 0074 /** moves the range by D. If the range is invalid the behaviour is undefined */ 0075 void moveBy(T D) { Start += D; End += D; } 0076 0077 public: // value access 0078 /** @return start */ 0079 T start() const { return Start; } 0080 /** @return end */ 0081 T end() const { return End; } 0082 0083 public: // logic access 0084 /** returns true if Value is covered */ 0085 bool includes(T Value) const { return Start <= Value && Value <= End; } 0086 /** returns true if Value is covered and not at a side */ 0087 bool includesInside(T Value) const { return Start < Value && Value < End; } 0088 /** returns true if range is behind index. if range is invalid the behaviour is undefined */ 0089 bool startsBehind(T Value) const { return Value < Start; } 0090 /** returns true is the range starts before index. If the range is invalid the behaviour is undefined */ 0091 bool startsBefore(T Value) const { return Start < Value; } 0092 /** returns true if the range ends later than index. If the range is invalid the behaviour is undefined */ 0093 bool endsBehind(T Value) const { return Value < End; } 0094 /** returns true if range is before index. if range is invalid the behaviour is undefined */ 0095 bool endsBefore(T Value) const { return End < Value; } 0096 0097 /** returns true is the range covers R. If one of both is invalid the behaviour is undefined */ 0098 bool includes(const Range& R) const { return R.End <= End && Start <= R.Start; } 0099 /** returns true is the range covers R. If one of both is invalid the behaviour is undefined */ 0100 bool includesInside(const Range& R) const { return R.End < End && Start < R.Start; } 0101 /** returns true is the range ends before R starts. If one of both is invalid the behaviour is undefined */ 0102 bool endsBefore(const Range& R) const { return End < R.Start; } 0103 /** returns true is the range starts later than R ends. If one of both is invalid the behaviour is undefined */ 0104 bool startsBehind(const Range& R) const { return R.End < Start; } 0105 /** returns true is the range starts prior than R. If one of both is invalid the behaviour is undefined */ 0106 bool startsBefore(const Range& R) const { return Start < R.Start; } 0107 /** returns true is the range ends later than R. If one of both is invalid the behaviour is undefined */ 0108 bool endsBehind(const Range& R) const { return R.End < End; } 0109 /** returns true is the range shares at least one index with R. If one of both is invalid the behaviour is undefined */ 0110 bool overlaps(const Range& R) const { return Start <= R.End && R.Start <= End; } 0111 0112 // TODO: this is wrong, a empty range is valid, too 0113 /** returns true if the range covers at least one index */ 0114 bool isValid() const { return Start != null() && Start <= End; } 0115 /** returns true if the range has not been set */ 0116 bool isEmpty() const { return Start == null() && End == null(); } 0117 0118 protected: 0119 /** delivers a null element. Should be specialiced for complexer types. */ 0120 const T null() const { return T(-1);} 0121 0122 protected: 0123 /** first value of the range */ 0124 T Start; 0125 /** last value of the range */ 0126 T End; 0127 }; 0128 0129 } 0130 0131 #endif