Generated on Wed Nov 1 15:04:41 2006 for Gecode by doxygen 1.4.5

ranges-inter.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Christian Schulte, 2004
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:05:50 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3515 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  *
00020  */
00021 
00022 #include <algorithm>
00023 
00024 namespace Gecode { namespace Iter { namespace Ranges {
00025 
00032   template <class I, class J>
00033   class Inter : public MinMax {
00034   protected:
00036     I i;
00038     J j;
00039   public:
00041 
00042 
00043     Inter(void);
00045     Inter(I& i, J& j);
00047     void init(I& i, J& j);
00049 
00051 
00052 
00053     void operator++(void);
00055   };
00056 
00057 
00064   template <class I>
00065   class NaryInter : public MinMax {
00066   protected:
00068     I* is;
00070     int n;
00071   public:
00073 
00074 
00075     NaryInter(void);
00077     NaryInter(I* i, int n);
00079     void init(I* i, int n);
00081 
00083 
00084 
00085     void operator++(void);
00087   };
00088 
00089 
00090   /*
00091    * Binary intersection
00092    *
00093    */
00094 
00095   template <class I, class J>
00096   inline void
00097   Inter<I,J>::operator++(void) {
00098     if (!i() || !j()) goto done;
00099     do {
00100       while (i() && (i.max() < j.min())) ++i;
00101       if (!i()) goto done;
00102       while (j() && (j.max() < i.min())) ++j;
00103       if (!j()) goto done;
00104     } while (i.max() < j.min());
00105     // Now the intervals overlap: consume the smaller interval
00106     ma = std::min(i.max(),j.max());
00107     mi = std::max(i.min(),j.min());
00108     if (i.max() < j.max()) ++i; else ++j;
00109     return;
00110   done:
00111     finish();
00112   }
00113 
00114   template <class I, class J>
00115   forceinline
00116   Inter<I,J>::Inter(void) {}
00117 
00118   template <class I, class J>
00119   forceinline
00120   Inter<I,J>::Inter(I& i0, J& j0)
00121     : i(i0), j(j0) {
00122     operator++();
00123   }
00124 
00125   template <class I, class J>
00126   forceinline void
00127   Inter<I,J>::init(I& i0, J& j0) {
00128     i = i0; j = j0;
00129     operator++();
00130   }
00131 
00132 
00133   /*
00134    * Nary intersection
00135    *
00136    */
00137 
00138   template <class I>
00139   inline void
00140   NaryInter<I>::operator++(void) {
00141     // The next interval to be returned must have a hole
00142     // between it and the previously returned range.
00143     mi = ma+2;
00144     ma = is[0].max();
00145     // Intersect with all other intervals
00146   restart:
00147     for (int i = n; i--;) {
00148       // Skip intervals that are too small
00149       while (is[i]() && (is[i].max() < mi))
00150         ++is[i];
00151       if (!is[i]())
00152         goto done;
00153 
00154       if (is[i].min() > ma) {
00155         mi=is[i].min();
00156         ma=is[i].max();
00157         goto restart;
00158       }
00159       // Now the intervals overlap
00160       if (mi < is[i].min())
00161         mi = is[i].min();
00162       if (ma > is[i].max()) {
00163         ma = is[i].max();
00164       }
00165     }
00166     return;
00167   done:
00168     finish();
00169   }
00170 
00171   template <class I>
00172   forceinline
00173   NaryInter<I>::NaryInter(void) {}
00174 
00175   template <class I>
00176   inline
00177   NaryInter<I>::NaryInter(I* is0, int n0)
00178     : is(is0), n(n0) {
00179     if (!is[0]()) {
00180       finish();
00181     } else {
00182       ma=is[0].min()-2;
00183       operator++();
00184     }
00185   }
00186 
00187   template <class I>
00188   inline void
00189   NaryInter<I>::init(I* is0, int n0) {
00190     is = is0; n = n0;
00191     if (!is[0]()) {
00192       finish();
00193     } else {
00194       ma=is[0].min()-2;
00195       operator++();
00196     }
00197   }
00198 
00199 }}}
00200 
00201 // STATISTICS: iter-any
00202