00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __RANGE_H__
00022 #define __RANGE_H__
00023
00024 #include <hn/osdep.h>
00025 #include <hn/utils.h>
00026 #include <boost/logic/tribool.hpp>
00027 #include <set>
00028 #include <limits>
00029
00030 namespace CGComm {
00031 enum {
00032 OP_RANGE = 0x10
00033 };
00034 }
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 template<typename T>
00045 class Range {
00046 public:
00047 typedef T size_type;
00048
00049
00050
00051 template<typename X, typename Y>
00052 Range(const X &begin, const Y &end) : m_begin(begin), m_end(end) {
00053 CHECK_THROW(m_begin <= m_end);
00054 }
00055 template<typename X>
00056 Range(const Range<X> &x) {
00057 m_begin = x.m_begin;
00058 m_end = x.m_end;
00059 }
00060 template<typename X, typename Y>
00061 Range(const std::pair<X, Y> r) : m_begin(r.first), m_end(r.second) {
00062 CHECK_THROW(m_begin <= m_end);
00063 }
00064 Range(std::istream &i) {
00065 m_begin = Utils::getVal<T>(i);
00066 m_end = Utils::getVal<T>(i);
00067 CHECK_THROW(m_end >= m_begin);
00068 }
00069 template<typename X>
00070 Range& operator=(const Range<X> &x) {
00071 m_begin = x.m_begin;
00072 m_end = x.m_end;
00073 }
00074
00075 explicit Range(const T &t) : m_begin(t), m_end(t) {}
00076
00077
00078
00079
00080 template<typename X>
00081 bool operator<(const Range<X> &x) const {
00082 return (m_begin + m_end) / 2 < (x.m_begin + x.m_end) / 2;
00083 }
00084 template<typename X>
00085 bool operator>(const Range<X> &x) const {
00086 return !(*this < x);
00087 }
00088 template<typename X>
00089 bool operator==(const Range<X> &x) const {
00090 return m_begin == x.m_begin && m_end == x.m_end;
00091 }
00092 template<typename X>
00093 bool operator!=(const Range<X> &x) const {
00094 return !(m_begin == x.m_begin && m_end == x.m_end);
00095 }
00096 friend std::ostream& operator<<(std::ostream &o, const Range &r) {
00097 Utils::putVal<uint8_t>(o, CGComm::OP_RANGE);
00098 Utils::putVal<uint16_t>(o, sizeof(T)*2);
00099 Utils::putVal<T>(o, r.m_begin);
00100 Utils::putVal<T>(o, r.m_end);
00101 return o;
00102 }
00103
00104
00105
00106
00107 T begin() const { return m_begin; }
00108 T end() const { return m_end; }
00109 T length() const { return m_end - m_begin + 1; }
00110 void begin(const T &b) {
00111 CHECK_THROW(b <= m_end);
00112 m_begin = b;
00113 }
00114 void end(const T &e) {
00115 CHECK_THROW(e >= m_begin);
00116 m_end = e;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 template<typename X>
00132 void merge(const Range<X> &x) {
00133 if (m_begin > x.m_begin) {
00134 m_begin = x.m_begin;
00135 }
00136 if (m_end < x.m_end) {
00137 m_end = x.m_end;
00138 }
00139 if (m_end + 1 == x.m_begin) {
00140 m_end = x.m_end;
00141 }
00142 if (m_begin - 1 == x.m_end) {
00143 m_begin = x.m_begin;
00144 }
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 template<typename X>
00159 boost::logic::tribool erase(Range<X> *x) {
00160 if (x->m_begin <= m_begin && x->m_end >= m_end) {
00161 return false;
00162 }
00163 if (m_begin >= x->m_begin) {
00164 m_begin = x->m_end + 1;
00165 return true;
00166 } else if (m_end <= x->m_end) {
00167 m_end = x->m_begin - 1;
00168 return true;
00169 }
00170 if (contains(x->m_begin) && contains(x->m_end)) {
00171 X tmp = m_end;
00172 m_end = x->m_begin - 1;
00173 x->m_begin = x->m_end + 1;
00174 x->m_end = tmp;
00175 return boost::indeterminate;
00176 }
00177 return true;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 template<typename X>
00190 bool contains(const Range<X> &x) const {
00191 if (contains(x.m_begin)) {
00192 return true;
00193 } else if (contains(x.m_end)) {
00194 return true;
00195 } else if (x.containsFull(*this)) {
00196 return true;
00197 }
00198 return false;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208 template<typename X>
00209 bool contains(const X &x) const {
00210 return x >= m_begin && x <= m_end;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 template<typename X>
00220 bool containsFull(const Range<X> &x) const {
00221 if (m_begin <= x.m_begin && m_end >= x.m_end) {
00222 return true;
00223 } else {
00224 return false;
00225 }
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 template<typename X>
00237 bool borders(const Range<X> &x) const {
00238 if (m_begin - 1 == x.m_end) {
00239 return true;
00240 }
00241 if (m_end + 1 == x.m_begin) {
00242 return true;
00243 }
00244 return false;
00245 }
00246
00247
00248
00249
00250
00251 template<typename X>
00252 bool contains(const X &x, const X &y) {
00253 return contains(Range(x, y));
00254 }
00255 template<typename X>
00256 bool containsFull(const X &x, const X &y) {
00257 return containsFull(Range(x, y));
00258 }
00259 template<typename X>
00260 boost::logic::tribool erase(const X &x, const X &y) {
00261 return erase(Range(x, y));
00262 }
00263
00264 private:
00265
00266 Range();
00267
00268 T m_begin;
00269 T m_end;
00270
00271
00272 template<typename X> friend class Range;
00273 };
00274
00275
00276
00277 typedef Range<uint64_t> Range64;
00278 typedef Range<uint32_t> Range32;
00279 typedef Range<uint16_t> Range16;
00280 typedef Range<uint8_t> Range8;
00281
00282
00283 #endif