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
00026
00027
00028
00029
00030 #ifndef MORE_MATH_INTERVAL_H
00031 #define MORE_MATH_INTERVAL_H
00032
00033 #include <functional>
00034 #include <iosfwd>
00035
00036 namespace more {
00037 namespace math {
00038
00039
00040
00041 template<typename T>
00042 struct interval_base
00043 {
00044 typedef T element_type;
00045
00046 protected:
00047 interval_base() {}
00048 interval_base(T x, T y) : m_inf(x), m_sup(y) {}
00049
00050 public:
00051 T const& inf() const { return m_inf; }
00052 T const& sup() const { return m_sup; }
00053 T& inf() { return m_inf; }
00054 T& sup() { return m_sup; }
00055 friend T const& inf(interval_base const& I) { return I.m_inf; }
00056 friend T const& sup(interval_base const& I) { return I.m_sup; }
00057 void set_inf(T const& x) { m_inf = x; }
00058 void set_sup(T const& x) { m_sup = x; }
00059
00060 protected:
00061 template<typename CharT, typename Traits>
00062 void print(std::basic_ostream<CharT, Traits>& os, bool, bool) const;
00063 template<typename CharT, typename Traits>
00064 void scan(std::basic_istream<CharT, Traits>& is, bool&, bool&);
00065
00066 private:
00067 T m_inf, m_sup;
00068 };
00069
00070 template<typename T>
00071 inline T length(interval_base<T> const& I) { return sup(I) - inf(I); }
00072 template<typename T>
00073 inline T center(interval_base<T> const& I) { return .5*(sup(I) + inf(I)); }
00074
00075 template<typename T, typename Less> struct interval;
00076
00077
00078
00079 template<typename T, typename Less = std::less<T> >
00080 struct open_interval : interval_base<T>
00081 {
00082 open_interval() {}
00083 open_interval(T x, T y) : interval_base<T>(x, y) {}
00084 open_interval(T x, T y, Less l) : interval_base<T>(x, y), less(l) {}
00085
00086 bool operator==(open_interval const& rhs) const {
00087 return inf() == rhs.inf() && sup() == rhs.sup();
00088 }
00089 bool operator!=(open_interval const& rhs) const {
00090 return !(*this == rhs);
00091 }
00092
00093 bool is_left_closed() const { return false; }
00094 bool is_right_closed() const { return false; }
00095
00096 bool find(T const& v) {
00097 if (!less(inf(), v)) return false;
00098 if (!less(v, sup())) return false;
00099 return true;
00100 }
00101 private:
00102 Less less;
00103 friend class interval<T, Less>;
00104 };
00105
00106
00107
00108
00109 template<typename T, typename Less = std::less<T> >
00110 struct left_interval : interval_base<T>
00111 {
00112 left_interval() {}
00113 left_interval(T x, T y) : interval_base<T>(x, y) {}
00114 left_interval(T x, T y, Less l) : interval_base<T>(x, y), less(l) {}
00115
00116 bool operator==(left_interval const& rhs) const {
00117 return inf() == rhs.inf() && sup() == rhs.sup();
00118 }
00119 bool operator!=(left_interval const& rhs) const {
00120 return !(*this == rhs);
00121 }
00122
00123 bool is_left_closed() const { return true; }
00124 bool is_right_closed() const { return false; }
00125
00126 bool find(T const& v) {
00127 if (less(v, inf())) return false;
00128 if (!less(v, sup())) return false;
00129 return true;
00130 }
00131 private:
00132 Less less;
00133 friend class interval<T, Less>;
00134 };
00135
00136
00137
00138
00139 template<typename T, typename Less = std::less<T> >
00140 struct right_interval : interval_base<T> {
00141 right_interval() {}
00142 right_interval(T x, T y) : interval_base<T>(x, y) {}
00143 right_interval(T x, T y, Less l) : interval_base<T>(x, y), less(l) {}
00144
00145 bool operator==(right_interval const& rhs) const {
00146 return inf() == rhs.inf() && sup() == rhs.sup();
00147 }
00148 bool operator!=(right_interval const& rhs) const {
00149 return !(*this == rhs);
00150 }
00151
00152 bool is_left_closed() const { return false; }
00153 bool is_right_closed() const { return true; }
00154
00155 bool find(T const& v) {
00156 if (!less(inf(), v)) return false;
00157 if (less(sup(), v)) return false;
00158 return true;
00159 }
00160 private:
00161 Less less;
00162 friend class interval<T, Less>;
00163 };
00164
00165
00166
00167 template<typename T, typename Less = std::less<T> >
00168 struct closed_interval : interval_base<T>
00169 {
00170 closed_interval() {}
00171 closed_interval(T x, T y) : interval_base<T>(x, y) {}
00172 closed_interval(T x, T y, Less l) : interval_base<T>(x, y), less(l) {}
00173
00174 bool operator==(closed_interval const& rhs) const {
00175 return inf() == rhs.inf() && sup() == rhs.sup();
00176 }
00177 bool operator!=(closed_interval const& rhs) const {
00178 return !(*this == rhs);
00179 }
00180
00181 bool is_left_closed() const { return true; }
00182 bool is_right_closed() const { return true; }
00183
00184 bool find(T const& v) {
00185 if (less(v, inf())) return false;
00186 if (less(sup(), v)) return false;
00187 return true;
00188 }
00189 private:
00190 Less less;
00191 friend class interval<T, Less>;
00192 };
00193
00194
00195
00196
00197 template< typename T, typename Less = std::less<T> >
00198 struct interval : interval_base<T>
00199 {
00200 interval() {}
00201 interval(T const& x, bool has_x, T const& y, bool has_y)
00202 : interval_base<T>(x, y), bb(has_x + 2*has_y) {}
00203 interval(T const& x, bool has_x, T const& y, bool has_y, Less l)
00204 : interval_base<T>(x, y), bb(has_x + 2*has_y), less(l) {}
00205
00206 interval(open_interval<T, Less> const& I)
00207 : interval_base<T>(I), bb(0), less(I.less) {}
00208 interval(left_interval<T, Less> const& I)
00209 : interval_base<T>(I), bb(1), less(I.less) {}
00210 interval(right_interval<T, Less> const& I)
00211 : interval_base<T>(I), bb(2), less(I.less) {}
00212 interval(closed_interval<T, Less> const& I)
00213 : interval_base<T>(I), bb(3), less(I.less) {}
00214
00215 bool operator==(interval const& rhs) const {
00216 return inf() == rhs.inf() && sup() == rhs.sup() && bb == rhs.bb;
00217 }
00218 bool operator!=(interval const& rhs) const { return !(*this == rhs); }
00219
00220 bool is_left_closed() const { return bb & 1; }
00221 bool is_right_closed() const { return bb & 2; }
00222
00223 bool find(T const& v) {
00224 if (is_left_closed()) {
00225 if (less(v, inf())) return false;
00226 } else {
00227 if (!less(inf(), v)) return false;
00228 }
00229 if (is_right_closed()) {
00230 if (less(sup(), v)) return false;
00231 } else {
00232 if (!less(v, sup())) return false;
00233 }
00234 return true;
00235 }
00236
00237 template<typename CharT, typename Traits>
00238 friend inline std::basic_ostream<CharT, Traits>&
00239 operator<<(std::basic_ostream<CharT, Traits>& os,
00240 interval const& x) {
00241 x.print(os, x.is_left_closed(), x.is_right_closed());
00242 return os;
00243 }
00244
00245 template<typename CharT, typename Traits>
00246 friend inline std::basic_istream<CharT, Traits>&
00247 operator>>(std::basic_istream<CharT, Traits>& is,
00248 interval& x) {
00249 bool lt_c, rt_c;
00250 x.scan(is, lt_c, rt_c);
00251 x.bb = lt_c + 2*rt_c;
00252 return is;
00253 }
00254
00255 private:
00256 unsigned char bb;
00257 Less less;
00258 };
00259
00260 template<typename T, typename Less>
00261 interval<T, Less>
00262 make_interval(T const& x, bool lt,
00263 T const& y, bool rt, Less less = std::less<T>())
00264 {
00265 return interval<T, Less>(x, lt, y, rt, less);
00266 }
00267
00268 template<typename T>
00269 interval<T>
00270 make_interval(T const& x, bool lt, T const& y, bool rt)
00271 {
00272 return interval<T>(x, lt, y, rt);
00273 }
00274
00275
00276 }
00277 using namespace math;
00278 }
00279
00280 #include <more/bits/interval.tcc>
00281 #endif