ranges-append.hpp
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: 2010-07-14 17:46:18 +0200 (Wed, 14 Jul 2010) $ by $Author: schulte $ 00011 * $Revision: 11192 $ 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 namespace Gecode { namespace Iter { namespace Ranges { 00039 00049 template<class I, class J> 00050 class Append : public MinMax { 00051 protected: 00053 I i; 00055 J j; 00056 private: 00057 IsRangeIter<I> constraintI; IsRangeIter<J> constraintJ; 00058 public: 00060 00061 00062 Append(void); 00064 Append(I& i, J& j); 00066 void init(I& i, J& j); 00068 00070 00071 00072 void operator ++(void); 00074 }; 00075 00076 00086 template<class I> 00087 class NaryAppend : public MinMax { 00089 IsRangeIter<I> _checkI; 00090 protected: 00092 I* r; 00094 int n; 00096 int active; 00097 public: 00099 00100 00101 NaryAppend(void); 00103 NaryAppend(I* i, int n); 00105 void init(I* i, int n); 00107 00109 00110 00111 void operator ++(void); 00113 }; 00114 00115 00116 /* 00117 * Binary Append 00118 * 00119 */ 00120 00121 template<class I, class J> 00122 inline void 00123 Append<I,J>::operator ++(void) { 00124 if (i()) { 00125 mi = i.min(); ma = i.max(); 00126 ++i; 00127 if (!i() && j() && (j.min() == ma+1)) { 00128 ma = j.max(); 00129 ++j; 00130 } 00131 } else if (j()) { 00132 mi = j.min(); ma = j.max(); 00133 ++j; 00134 } else { 00135 finish(); 00136 } 00137 } 00138 00139 00140 template<class I, class J> 00141 forceinline 00142 Append<I,J>::Append(void) {} 00143 00144 template<class I, class J> 00145 forceinline 00146 Append<I,J>::Append(I& i0, J& j0) 00147 : i(i0), j(j0) { 00148 if (i() || j()) 00149 operator ++(); 00150 else 00151 finish(); 00152 } 00153 00154 template<class I, class J> 00155 forceinline void 00156 Append<I,J>::init(I& i0, J& j0) { 00157 i = i0; j = j0; 00158 if (i() || j()) 00159 operator ++(); 00160 else 00161 finish(); 00162 } 00163 00164 00165 /* 00166 * Nary Append 00167 * 00168 */ 00169 00170 template<class I> 00171 inline void 00172 NaryAppend<I>::operator ++(void) { 00173 mi = r[active].min(); 00174 ma = r[active].max(); 00175 ++r[active]; 00176 while (!r[active]()) { 00177 //Skip empty iterators: 00178 do { 00179 active++; 00180 if (active >= n) { 00181 finish(); return; 00182 } 00183 } while (!r[active]()); 00184 if (r[active].min() == ma+1){ 00185 ma = r[active].max(); 00186 ++r[active]; 00187 } else { 00188 return; 00189 } 00190 } 00191 } 00192 00193 template<class I> 00194 forceinline 00195 NaryAppend<I>::NaryAppend(void) {} 00196 00197 template<class I> 00198 inline 00199 NaryAppend<I>::NaryAppend(I* r0, int n0) 00200 : r(r0), n(n0), active(0) { 00201 while (active < n && !r[active]()) 00202 active++; 00203 if (active < n){ 00204 operator ++(); 00205 } else { 00206 finish(); 00207 } 00208 } 00209 00210 template<class I> 00211 inline void 00212 NaryAppend<I>::init(I* r0, int n0) { 00213 r = r0; n = n0; active = 0; 00214 while (active < n && !r[active]()) 00215 active++; 00216 if (active < n){ 00217 operator ++(); 00218 } else { 00219 finish(); 00220 } 00221 } 00222 00223 }}} 00224 00225 // STATISTICS: iter-any 00226