00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef FILE_RANGE_HPP
00026 #define FILE_RANGE_HPP
00027
00028 template<class T>
00029 struct range
00030 {
00031 T begin;
00032 T end;
00033 range() {};
00034 range(T a,T b):begin(a),end(b) {};
00035
00036 bool operator<(const range<T>& rhs) const
00037 { return begin<rhs.begin; }
00038
00039 bool operator==(const range<T>& rhs) const
00040 { return begin==rhs.begin; }
00041 };
00042
00043 #include <vector>
00044 #include <algorithm>
00045
00046 template <class T>
00047 class range_set
00048 {
00049 private:
00050 typedef std::vector< range<T> > TSet;
00051 TSet set;
00052 public:
00053 struct range_comp
00054 {
00055 bool operator()(const range<T>& a,const range<T>& b)
00056 { return a.end < b.begin; }
00057 };
00058
00059 typedef typename TSet::value_type value_type;
00060 typedef typename TSet::const_reference reference;
00061 typedef typename TSet::const_reference const_reference;
00062 typedef typename TSet::const_iterator iterator;
00063 typedef typename TSet::const_iterator const_iterator;
00064 typedef typename TSet::size_type size_type;
00065 typedef typename TSet::difference_type difference_type;
00066 typedef typename TSet::const_reverse_iterator reverse_iterator;
00067 typedef typename TSet::const_reverse_iterator const_reverse_iterator;
00068
00069
00070
00071 const_iterator begin () const { return set.begin(); }
00072 const_iterator end () const { return set.end(); }
00073 const_reverse_iterator rbegin () const { return set.rbegin(); }
00074 const_reverse_iterator rend () const { return set.rend(); }
00075
00076
00077 bool empty () const { return set.empty(); }
00078 size_type size () const { return set.size(); }
00079 size_type max_size () const { return set.max_size(); }
00080
00081
00082
00083 bool insert (const value_type&);
00084
00085 void erase (iterator i)
00086 { set.erase(const_cast<typename TSet::iterator>(i)); }
00087 void erase (const value_type&);
00088 void erase (iterator a, iterator b)
00089 { set.erase(const_cast<typename TSet::iterator>(a),const_cast<typename TSet::iterator>(b)); }
00090 void swap (range_set<T>& rhs) { set.swap(rhs.set); }
00091
00092
00093
00094
00095
00096
00097
00098 };
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 template <class T>
00122 bool range_set<T>::insert(const value_type& value)
00123 {
00124
00125 if (value.begin >= value.end)
00126 return true;
00127
00128 typename TSet::iterator i = std::lower_bound(set.begin(),set.end(),value,range_comp());
00129
00130
00131 if (i==set.end() || value.end < (*i).begin)
00132 {
00133 set.insert(i,value);
00134 return false;
00135 }
00136
00137
00138 bool res = true;
00139 if (value.begin < (*i).begin)
00140 {
00141 (*i).begin = value.begin;
00142 res = false;
00143 }
00144
00145
00146 if (value.end >= (*i).end)
00147 {
00148
00149 T end = value.end;
00150 typename TSet::iterator ii = i;
00151 while(++ii != set.end())
00152 {
00153 if (end >=(*ii).begin && end<=(*ii).end)
00154 end = (*ii).end;
00155 if (end < (*ii).end)
00156 break;
00157 }
00158
00159
00160 (*i).end = end;
00161
00162
00163 set.erase(++i,ii);
00164
00165
00166 return false;
00167 }
00168 return res;
00169 }
00170
00171 template <class T>
00172 void range_set<T>::erase (const value_type& value)
00173 {
00174
00175 if (value.begin >= value.end)
00176 return;
00177
00178 typename TSet::iterator i = std::lower_bound(set.begin(),set.end(),value,range_comp());
00179
00180 if (i==set.end())
00181 return;
00182
00183
00184 if ( value.end <= (*i).begin )
00185 return;
00186
00187
00188 if ( value.begin > (*i).begin )
00189 {
00190
00191 if ( value.end < (*i).end)
00192 {
00193 T begin = (*i).begin;
00194 (*i).begin = value.end;
00195 set.insert(i,value_type(begin,value.begin));
00196 return;
00197 }
00198 (*i).end = value.begin;
00199 ++i;
00200 }
00201
00202
00203 typename TSet::iterator ii = i;
00204 while( ii != set.end() && value.end >= (*ii).end )
00205 ++ii;
00206
00207
00208 if ( value.end >= (*ii).begin )
00209 (*ii).begin = value.end;
00210
00211
00212 set.erase(i,ii);
00213 }
00214
00215 #endif //FILE_RANGE_HPP