00001 #ifndef GRAL_GB_SEQUENCE_INTEGER_RANGE_H
00002 #define GRAL_GB_SEQUENCE_INTEGER_RANGE_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "Geometry/interval.h"
00019 #include "Container/sequence-algorithms.h"
00020 #include "Utility/checked-istream.h"
00021 #include "Utility/pre-post-conditions.h"
00022
00023 #include <ctype.h>
00024 #include <iostream>
00025 #include <vector>
00026
00027 namespace GrAL { namespace sequence {
00028
00036 template<class INT> class integer_range {
00037 typedef interval<INT> interval_type;
00038 typedef INT element_type;
00039 std::vector<interval_type> intervals;
00040 public:
00042 integer_range() {}
00044 integer_range(INT i) { intervals.push_back(interval_type(i,i));}
00046 integer_range(interval_type iv) { if(!iv.empty()) intervals.push_back(iv);}
00048 template<class IT>
00049 integer_range(IT b, IT e) { init(b,e);}
00050
00052 bool empty() const { return intervals.empty();}
00054 void clear() { intervals.clear();}
00055
00057 typedef typename std::vector<interval_type>::const_iterator interval_iterator;
00059 interval_iterator begin_interval() const { return intervals.begin();}
00061 interval_iterator end_interval() const { return intervals.end();}
00062
00064 element_type low() const {return intervals.front().low();}
00066 element_type high() const {return intervals.back() .high();}
00067
00068
00069 struct const_iterator {
00070 typedef const_iterator self;
00071 typedef integer_range<INT> integer_range_type;
00072 typedef INT value_type;
00073
00074 interval_iterator interval;
00075 int i;
00076
00077 const_iterator() {}
00078 const_iterator(interval_iterator interval_, int i_) : interval(interval_), i(i_) {}
00079 value_type operator*() const { return (*interval).low() + i;}
00080 self & operator++() {
00081 ++i;
00082 if(i > (*interval).high() - (*interval).low()) {
00083 ++interval;
00084 i = 0;
00085 }
00086 return *this;
00087 }
00088 bool operator==(self const& rhs) const { return interval == rhs.interval && i == rhs.i;}
00089 bool operator!=(self const& rhs) const { return !(*this == rhs);}
00090 bool operator< (self const& rhs) const { return interval < rhs.interval || (interval == rhs.interval && i < rhs.i);}
00091 };
00092 const_iterator begin() const { return const_iterator(begin_interval(), 0);}
00093 const_iterator end () const { return const_iterator(end_interval(), 0);}
00094
00099 template<class IT>
00100 void init(IT b, IT e);
00104 void push_back(element_type i) {
00105 REQUIRE(empty() || i > high(), "i=" << i,1);
00106 if(empty() || i > 1 + high())
00107 intervals.push_back(interval_type(i,i));
00108 else
00109 intervals.back() = interval_type(intervals.back().low(), i);
00110 }
00112 bool contains(INT i) const {
00113 for(interval_iterator iv = begin_interval(); iv != end_interval(); ++iv)
00114 if(iv->contains(i))
00115 return true;
00116 return false;
00117 }
00118 void read(std::istream& in);
00119 private:
00120
00121 bool read_interval(std::istream& in, interval_type& iv, bool& end);
00122
00123 bool read_number (std::istream& in, INT & i);
00124
00125 };
00126
00130 template<class INT>
00131 std::istream& operator>>(std::istream& in, integer_range<INT> & r)
00132 { r.read(in); return in;}
00133
00139 template<class INT>
00140 std::ostream& operator<<(std::ostream& out, integer_range<INT> const& r)
00141 {
00142 for(typename integer_range<INT>::interval_iterator iv = r.begin_interval(); iv != r.end_interval(); ++iv) {
00143 if(iv != r.begin_interval())
00144 out << ',';
00145 out << iv->l() << '-' << iv->r();
00146 }
00147 return out;
00148 }
00149
00150
00151 template<class INT>
00152 template<class IT>
00153 void integer_range<INT>::init(IT b, IT e)
00154 {
00155 std::vector<element_type> elements(b,e);
00156 sequence::sort_and_make_unique(elements);
00157 typename std::vector<element_type>::iterator
00158 interval_beg = elements.begin(),
00159 interval_end = elements.begin();
00160
00161 while(interval_beg != elements.end()) {
00162
00163
00164 int n = 0;
00165 while(interval_end != elements.end() &&
00166 *interval_end <= n + *interval_beg) {
00167 ++interval_end;
00168 ++n;
00169 }
00170
00171 intervals.push_back(interval_type(* interval_beg,
00172 *(interval_end-1)));
00173 interval_beg = interval_end;
00174 }
00175 }
00176
00177
00178
00179
00180 template<class INT>
00181 void integer_range<INT>::read(std::istream& in)
00182 {
00183 clear();
00184 interval_type iv;
00185 bool end = false;
00186 while(!end && read_interval(in,iv,end) ) {
00187 if(! iv.empty())
00188 intervals.push_back(iv);
00189 }
00190 }
00191
00192 template<class INT>
00193 bool integer_range<INT>::read_number (std::istream& in, INT & i)
00194 {
00195 checked_istream checked_in(in);
00196 return (checked_in >> i);
00197 }
00198
00199 template<class INT>
00200 bool integer_range<INT>::read_interval(std::istream& in, typename integer_range<INT>::interval_type & iv, bool& end)
00201 {
00202 INT low, high;
00203 bool res = true;
00204 if(! (in >> low)) {
00205 end = true;
00206 return false;
00207 }
00208 high = low;
00209 char next = '\0';
00210
00211 if(in.eof() || ! in.get(next)) {
00212 end = true;
00213 in.clear();
00214 }
00215 else {
00216 if(next == '-') {
00217 res = read_number(in, high);
00218 if(res) {
00219 if(in.get(next) && next != ',') {
00220 if(! isspace(next)) {
00221 res = false;
00222 }
00223 else {
00224 end = true;
00225 }
00226 in.putback(next);
00227 }
00228 }
00229 }
00230 else if( next == ',') {
00231 res = true;
00232 if(in.get(next)) {
00233 end = ! (isdigit(next) || next == '-' || next == '+');
00234 in.putback(next);
00235 }
00236 }
00237 else if(isspace(next)) {
00238 res = true;
00239 end = true;
00240 in.putback(next);
00241 }
00242 else {
00243 res = false;
00244 end = true;
00245
00246 }
00247 }
00248 iv = interval_type(low,high);
00249 return res;
00250 }
00251
00252
00253 } }
00254
00255 #endif
00256