Generated on Mon Aug 25 11:35:39 2008 for Gecode by doxygen 1.5.6

ranges-inter.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2004
00008  *
00009  *  Last modified:
00010  *     $Date: 2007-09-11 15:58:22 +0200 (Tue, 11 Sep 2007) $ by $Author: schulte $
00011  *     $Revision: 4973 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include <algorithm>
00039 
00040 namespace Gecode { namespace Iter { namespace Ranges {
00041 
00047   template <class I, class J>
00048   class Inter : public MinMax {
00049   protected:
00051     I i;
00053     J j;
00054   public:
00056 
00057 
00058     Inter(void);
00060     Inter(I& i, J& j);
00062     void init(I& i, J& j);
00064 
00066 
00067 
00068     void operator++(void);
00070   };
00071 
00072 
00078   template <class I>
00079   class NaryInter : public MinMax {
00080   protected:
00082     I* is;
00084     int n;
00085   public:
00087 
00088 
00089     NaryInter(void);
00091     NaryInter(I* i, int n);
00093     void init(I* i, int n);
00095 
00097 
00098 
00099     void operator++(void);
00101   };
00102 
00103 
00104   /*
00105    * Binary intersection
00106    *
00107    */
00108 
00109   template <class I, class J>
00110   inline void
00111   Inter<I,J>::operator++(void) {
00112     if (!i() || !j()) goto done;
00113     do {
00114       while (i() && (i.max() < j.min())) ++i;
00115       if (!i()) goto done;
00116       while (j() && (j.max() < i.min())) ++j;
00117       if (!j()) goto done;
00118     } while (i.max() < j.min());
00119     // Now the intervals overlap: consume the smaller interval
00120     ma = std::min(i.max(),j.max());
00121     mi = std::max(i.min(),j.min());
00122     if (i.max() < j.max()) ++i; else ++j;
00123     return;
00124   done:
00125     finish();
00126   }
00127 
00128   template <class I, class J>
00129   forceinline
00130   Inter<I,J>::Inter(void) {}
00131 
00132   template <class I, class J>
00133   forceinline
00134   Inter<I,J>::Inter(I& i0, J& j0)
00135     : i(i0), j(j0) {
00136     operator++();
00137   }
00138 
00139   template <class I, class J>
00140   forceinline void
00141   Inter<I,J>::init(I& i0, J& j0) {
00142     i = i0; j = j0;
00143     operator++();
00144   }
00145 
00146 
00147   /*
00148    * Nary intersection
00149    *
00150    */
00151 
00152   template <class I>
00153   inline void
00154   NaryInter<I>::operator++(void) {
00155     // The next interval to be returned must have a hole
00156     // between it and the previously returned range.
00157     mi = ma+2;
00158     ma = is[0].max();
00159     // Intersect with all other intervals
00160   restart:
00161     for (int i = n; i--;) {
00162       // Skip intervals that are too small
00163       while (is[i]() && (is[i].max() < mi))
00164         ++is[i];
00165       if (!is[i]())
00166         goto done;
00167 
00168       if (is[i].min() > ma) {
00169         mi=is[i].min();
00170         ma=is[i].max();
00171         goto restart;
00172       }
00173       // Now the intervals overlap
00174       if (mi < is[i].min())
00175         mi = is[i].min();
00176       if (ma > is[i].max()) {
00177         ma = is[i].max();
00178       }
00179     }
00180     return;
00181   done:
00182     finish();
00183   }
00184 
00185   template <class I>
00186   forceinline
00187   NaryInter<I>::NaryInter(void) {}
00188 
00189   template <class I>
00190   inline
00191   NaryInter<I>::NaryInter(I* is0, int n0)
00192     : is(is0), n(n0) {
00193     if (!is[0]()) {
00194       finish();
00195     } else {
00196       ma=is[0].min()-2;
00197       operator++();
00198     }
00199   }
00200 
00201   template <class I>
00202   inline void
00203   NaryInter<I>::init(I* is0, int n0) {
00204     is = is0; n = n0;
00205     if (!is[0]()) {
00206       finish();
00207     } else {
00208       ma=is[0].min()-2;
00209       operator++();
00210     }
00211   }
00212 
00213 }}}
00214 
00215 // STATISTICS: iter-any
00216