Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/math/interval.h

Go to the documentation of this file.
00001 //  Copyright (C) 2001--2002  Petter Urkedal
00002 //
00003 //  This file is free software; you can redistribute it and/or modify
00004 //  it under the terms of the GNU General Public License as published by
00005 //  the Free Software Foundation; either version 2 of the License, or
00006 //  (at your option) any later version.
00007 //
00008 //  This file is distributed in the hope that it will be useful,
00009 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //  GNU General Public License for more details.
00012 //
00013 //  You should have received a copy of the GNU General Public License
00014 //  along with this program; if not, write to the Free Software
00015 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 //
00017 //  As a special exception, you may use this file as part of a free
00018 //  software library without restriction.  Specifically, if other files
00019 //  instantiate templates or use macros or inline functions from this
00020 //  file, or you compile this file and link it with other files to
00021 //  produce an executable, this file does not by itself cause the
00022 //  resulting executable to be covered by the GNU General Public
00023 //  License.  This exception does not however invalidate any other
00024 //  reasons why the executable file might be covered by the GNU General
00025 //  Public License.
00026 //
00027 //  $Id: interval.h,v 1.2 2002/08/24 13:52:14 petter_urkedal Exp $
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   /** \class interval_base interval.h more/math/interval.h
00040       Helper for interval classes. */
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   /** \class open_internal interval.h more/math/internal.h
00078       A continuous interval which does not contain its extremums. */
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   /** \class left_interval interval.h more/math/interval.h
00107       A continuous interval which contains its infimum but not its
00108       supremum. */
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   /** \class right_interval interval.h more/math/interval.h
00137       A continuous interval which contains its supremum but not its
00138       infimum. */
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   /** \class closed_interval interval.h more/math/interval.h
00166       A continuous interval which contains both extremums. */
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   /** \class interval interval.h more/math/interval.h
00195       A continuous interval. That is, connected 1d set of reals.
00196       \c T should be (quasi-)continuous type, such as a float. */
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

Generated on Sat Sep 7 19:11:18 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.