this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.org>
5 *
6 * Copyright:
7 * Christian Schulte, 2010
8 *
9 * This file is part of Gecode, the generic constraint
10 * development environment:
11 * http://www.gecode.org
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining
14 * a copy of this software and associated documentation files (the
15 * "Software"), to deal in the Software without restriction, including
16 * without limitation the rights to use, copy, modify, merge, publish,
17 * distribute, sublicense, and/or sell copies of the Software, and to
18 * permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be
22 * included in all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 *
32 */
33
34namespace Gecode { namespace Iter { namespace Ranges {
35
36 /**
37 * \brief Iterator over range lists
38 *
39 * \ingroup FuncIterRanges
40 */
41 class RangeListIter {
42 protected:
43 /// Range list class
44 class RangeList : public Support::BlockClient<RangeList,Region> {
45 public:
46 /// Minimum and maximum of a range
47 int min, max;
48 /// Next element
49 RangeList* next;
50 };
51 /// Shared object for allocation
52 class RLIO : public Support::BlockAllocator<RangeList,Region> {
53 public:
54 /// Counter used for reference counting
55 unsigned int use_cnt;
56 /// Initialize
57 RLIO(Region& r);
58 };
59 /// Reference to shared object
60 RLIO* rlio;
61 /// Head of range list
62 RangeList* h;
63 /// Current list element
64 RangeList* c;
65 /// Set range lists
66 void set(RangeList* l);
67 /// Get head of current range list
68 RangeList* get(void) const;
69 /// Create new range possibly from freelist \a f and init
70 RangeList* range(int min, int max, RangeList*& f);
71 /// Create new range possibly and init
72 RangeList* range(int min, int max);
73 /// Create new range possibly from freelist \a f and init
74 template<class I>
75 RangeList* range(I& i, RangeList*& f);
76 /// Create new range possibly and init
77 template<class I>
78 RangeList* range(I& i);
79 /// Copy the iterator \a i to a range list
80 template<class I>
81 RangeList* copy(I& i);
82 public:
83 /// \name Constructors and initialization
84 //@{
85 /// Default constructor
86 RangeListIter(void);
87 /// Copy constructor
88 RangeListIter(const RangeListIter& i);
89 /// Initialize
90 RangeListIter(Region& r);
91 /// Initialize
92 void init(Region& r);
93 /// Assignment operator
94 RangeListIter& operator =(const RangeListIter& i);
95 //@}
96
97 /// \name Iteration control
98 //@{
99 /// Test whether iterator is still at a range or done
100 bool operator ()(void) const;
101 /// Move iterator to next range (if possible)
102 void operator ++(void);
103 /// Reset iterator to start
104 void reset(void);
105 //@}
106
107 /// \name Range access
108 //@{
109 /// Return smallest value of range
110 int min(void) const;
111 /// Return largest value of range
112 int max(void) const;
113 /// Return width of range (distance between minimum and maximum)
114 unsigned int width(void) const;
115 //@}
116
117 /// Destructor
118 ~RangeListIter(void);
119 };
120
121
122 forceinline
123 RangeListIter::RLIO::RLIO(Region& r)
124 : Support::BlockAllocator<RangeList,Region>(r), use_cnt(1) {}
125
126
127 forceinline
128 RangeListIter::RangeListIter(void)
129 : rlio(nullptr), h(nullptr), c(nullptr) {}
130
131 forceinline
132 RangeListIter::RangeListIter(Region& r)
133 : rlio(new (r.ralloc(sizeof(RLIO))) RLIO(r)), h(nullptr), c(nullptr) {}
134
135 forceinline void
136 RangeListIter::init(Region& r) {
137 rlio = new (r.ralloc(sizeof(RLIO))) RLIO(r);
138 h = c = nullptr;
139 }
140
141 forceinline
142 RangeListIter::RangeListIter(const RangeListIter& i)
143 : rlio(i.rlio), h(i.h), c(i.c) {
144 if (rlio != nullptr)
145 rlio->use_cnt++;
146 }
147
148 forceinline RangeListIter&
149 RangeListIter::operator =(const RangeListIter& i) {
150 if (&i != this) {
151 if ((rlio != nullptr) && (--rlio->use_cnt == 0)) {
152 Region& r = rlio->allocator();
153 rlio->~RLIO();
154 r.rfree(rlio,sizeof(RLIO));
155 }
156 rlio = i.rlio;
157 if (rlio != nullptr)
158 rlio->use_cnt++;
159 c=i.c; h=i.h;
160 }
161 return *this;
162 }
163
164 forceinline
165 RangeListIter::~RangeListIter(void) {
166 if ((rlio != nullptr) && (--rlio->use_cnt == 0)) {
167 Region& r = rlio->allocator();
168 rlio->~RLIO();
169 r.rfree(rlio,sizeof(RLIO));
170 }
171 }
172
173
174 forceinline void
175 RangeListIter::set(RangeList* l) {
176 h = c = l;
177 }
178
179 forceinline RangeListIter::RangeList*
180 RangeListIter::get(void) const {
181 return h;
182 }
183
184 forceinline RangeListIter::RangeList*
185 RangeListIter::range(int min, int max, RangeList*& f) {
186 RangeList* t;
187 // Take element from freelist if possible
188 if (f != nullptr) {
189 t = f; f = f->next;
190 } else {
191 t = new (*rlio) RangeList;
192 }
193 t->min = min; t->max = max;
194 return t;
195 }
196
197 forceinline RangeListIter::RangeList*
198 RangeListIter::range(int min, int max) {
199 RangeList* t = new (*rlio) RangeList;
200 t->min = min; t->max = max;
201 return t;
202 }
203
204 template<class I>
205 forceinline RangeListIter::RangeList*
206 RangeListIter::range(I& i, RangeList*& f) {
207 return range(i.min(),i.max(),f);
208 }
209
210 template<class I>
211 forceinline RangeListIter::RangeList*
212 RangeListIter::range(I& i) {
213 return range(i.min(),i.max());
214 }
215
216 template<class I>
217 inline RangeListIter::RangeList*
218 RangeListIter::copy(I& i) {
219 RangeList* h;
220 RangeList** c = &h;
221 for ( ; i(); ++i) {
222 RangeList* t = range(i);
223 *c = t; c = &t->next;
224 }
225 *c = nullptr;
226 return h;
227 }
228
229 forceinline bool
230 RangeListIter::operator ()(void) const {
231 return c != nullptr;
232 }
233
234 forceinline void
235 RangeListIter::operator ++(void) {
236 c = c->next;
237 }
238
239 forceinline void
240 RangeListIter::reset(void) {
241 c = h;
242 }
243
244 forceinline int
245 RangeListIter::min(void) const {
246 return c->min;
247 }
248 forceinline int
249 RangeListIter::max(void) const {
250 return c->max;
251 }
252 forceinline unsigned int
253 RangeListIter::width(void) const {
254 return static_cast<unsigned int>(c->max-c->min)+1;
255 }
256
257}}}
258
259// STATISTICS: iter-any
260