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 * Guido Tack <tack@gecode.org>
6 *
7 * Contributing authors:
8 * Gregory Crosswhite <gcross@phys.washington.edu>
9 *
10 * Copyright:
11 * Gregory Crosswhite, 2011
12 * Christian Schulte, 2003
13 * Guido Tack, 2004
14 *
15 * This file is part of Gecode, the generic constraint
16 * development environment:
17 * http://www.gecode.org
18 *
19 * Permission is hereby granted, free of charge, to any person obtaining
20 * a copy of this software and associated documentation files (the
21 * "Software"), to deal in the Software without restriction, including
22 * without limitation the rights to use, copy, modify, merge, publish,
23 * distribute, sublicense, and/or sell copies of the Software, and to
24 * permit persons to whom the Software is furnished to do so, subject to
25 * the following conditions:
26 *
27 * The above copyright notice and this permission notice shall be
28 * included in all copies or substantial portions of the Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 *
38 */
39
40#include <iostream>
41#include <sstream>
42
43namespace Gecode {
44
45 /**
46 * \brief Shared array with arbitrary number of elements
47 *
48 * Sharing is implemented by reference counting: the same elements
49 * are shared among several objects.
50 *
51 */
52 template<class T>
53 class SharedArray : public SharedHandle {
54 protected:
55 /// Implementation of object for shared arrays
56 class SAO : public SharedHandle::Object {
57 private:
58 /// Elements
59 T* a;
60 /// Number of elements
61 int n;
62 public:
63 /// Allocate for \a n elements
64 SAO(int n);
65 /// Delete object
66 virtual ~SAO(void);
67
68 /// Access element at position \a i
69 T& operator [](int i);
70 /// Access element at position \a i
71 const T& operator [](int i) const;
72
73 /// Return number of elements
74 int size(void) const;
75
76 /// Return beginning of array (for iterators)
77 T* begin(void);
78 /// Return beginning of array (for iterators)
79 const T* begin(void) const;
80 /// Return end of array (for iterators)
81 T* end(void);
82 /// Return end of array (for iterators)
83 const T* end(void) const;
84 };
85 public:
86 /// \name Associated types
87 //@{
88 /// Type of the view stored in this array
89 typedef T value_type;
90 /// Type of a reference to the value type
91 typedef T& reference;
92 /// Type of a constant reference to the value type
93 typedef const T& const_reference;
94 /// Type of a pointer to the value type
95 typedef T* pointer;
96 /// Type of a read-only pointer to the value type
97 typedef const T* const_pointer;
98 /// Type of the iterator used to iterate through this array's elements
99 typedef T* iterator;
100 /// Type of the iterator used to iterate read-only through this array's elements
101 typedef const T* const_iterator;
102 /// Type of the iterator used to iterate backwards through this array's elements
103 typedef std::reverse_iterator<T*> reverse_iterator;
104 /// Type of the iterator used to iterate backwards and read-only through this array's elements
105 typedef std::reverse_iterator<const T*> const_reverse_iterator;
106 //@}
107
108 /**
109 * \brief Construct as not yet intialized
110 *
111 * The only member functions that can be used on a constructed but not
112 * yet initialized shared array is init and the assignment operator .
113 *
114 */
115 SharedArray(void);
116 /// Initialize as array with \a n elements
117 SharedArray(int n);
118 /**
119 * \brief Initialize as array with \a n elements
120 *
121 * This member function can only be used once and only if the shared
122 * array has been constructed with the default constructor.
123 *
124 */
125 void init(int n);
126 /// Initialize from shared array \a a (share elements)
127 SharedArray(const SharedArray& a);
128 /// Initialize from argument array \a a
129 SharedArray(const ArgArrayBase<T>& a);
130
131 /// Access element at position \a i
132 T& operator [](int i);
133 /// Access element at position \a i
134 const T& operator [](int i) const;
135
136 /// Return number of elements
137 int size(void) const;
138
139 /// Test equality with \a sa
140 bool operator ==(const SharedArray<T>& sa) const;
141
142 /// \name Array iteration
143 //@{
144 /// Return an iterator at the beginning of the array
145 iterator begin(void);
146 /// Return a read-only iterator at the beginning of the array
147 const_iterator begin(void) const;
148 /// Return an iterator past the end of the array
149 iterator end(void);
150 /// Return a read-only iterator past the end of the array
151 const_iterator end(void) const;
152 /// Return a reverse iterator at the end of the array
153 reverse_iterator rbegin(void);
154 /// Return a reverse and read-only iterator at the end of the array
155 const_reverse_iterator rbegin(void) const;
156 /// Return a reverse iterator past the beginning of the array
157 reverse_iterator rend(void);
158 /// Return a reverse and read-only iterator past the beginning of the array
159 const_reverse_iterator rend(void) const;
160 //@}
161 };
162
163 /**
164 * \brief Print array elements enclosed in curly brackets
165 * \relates SharedArray
166 */
167 template<class Char, class Traits, class T>
168 std::basic_ostream<Char,Traits>&
169 operator <<(std::basic_ostream<Char,Traits>& os,
170 const SharedArray<T>& x);
171
172
173 /*
174 * Implementation
175 *
176 */
177
178 /*
179 * Shared arrays
180 *
181 */
182 template<class T>
183 forceinline
184 SharedArray<T>::SAO::SAO(int n0) : n(n0) {
185 a = (n>0) ? heap.alloc<T>(n) : nullptr;
186 }
187
188 template<class T>
189 SharedArray<T>::SAO::~SAO(void) {
190 if (n>0) {
191 heap.free<T>(a,n);
192 }
193 }
194
195 template<class T>
196 forceinline T&
197 SharedArray<T>::SAO::operator [](int i) {
198 assert((i>=0) && (i<n));
199 return a[i];
200 }
201
202 template<class T>
203 forceinline const T&
204 SharedArray<T>::SAO::operator [](int i) const {
205 assert((i>=0) && (i<n));
206 return a[i];
207 }
208
209 template<class T>
210 forceinline int
211 SharedArray<T>::SAO::size(void) const {
212 return n;
213 }
214
215 template<class T>
216 forceinline T*
217 SharedArray<T>::SAO::begin(void) {
218 return a;
219 }
220
221 template<class T>
222 forceinline const T*
223 SharedArray<T>::SAO::begin(void) const {
224 return a;
225 }
226
227 template<class T>
228 forceinline T*
229 SharedArray<T>::SAO::end(void) {
230 return a+n;
231 }
232
233 template<class T>
234 forceinline const T*
235 SharedArray<T>::SAO::end(void) const {
236 return a+n;
237 }
238
239
240 template<class T>
241 forceinline
242 SharedArray<T>::SharedArray(void) {}
243
244 template<class T>
245 forceinline
246 SharedArray<T>::SharedArray(int n)
247 : SharedHandle(new SAO(n)) {}
248
249 template<class T>
250 forceinline
251 SharedArray<T>::SharedArray(const SharedArray<T>& sa)
252 : SharedHandle(sa) {}
253
254 template<class T>
255 forceinline void
256 SharedArray<T>::init(int n) {
257 assert(object() == nullptr);
258 object(new SAO(n));
259 }
260
261 template<class T>
262 forceinline T&
263 SharedArray<T>::operator [](int i) {
264 assert(object() != nullptr);
265 return (*static_cast<SAO*>(object()))[i];
266 }
267
268 template<class T>
269 forceinline const T&
270 SharedArray<T>::operator [](int i) const {
271 assert(object() != nullptr);
272 return (*static_cast<SAO*>(object()))[i];
273 }
274
275 template<class T>
276 inline bool
277 SharedArray<T>::operator ==(const SharedArray<T>& sa) const {
278 if (size() != sa.size())
279 return false;
280 if (object()==sa.object())
281 return true;
282 for (int i=0; i<size(); i++) {
283 if ((*this)[i] != sa[i])
284 return false;
285 }
286 return true;
287 }
288
289 template<class T>
290 forceinline
291 SharedArray<T>::SharedArray(const ArgArrayBase<T>& a)
292 : SharedHandle(new SAO(a.size())) {
293 for (int i=0; i<a.size(); i++)
294 operator [](i)=a[i];
295 }
296
297 template<class T>
298 forceinline int
299 SharedArray<T>::size(void) const {
300 assert(object() != nullptr);
301 return static_cast<SAO*>(object())->size();
302 }
303
304 template<class T>
305 forceinline typename SharedArray<T>::iterator
306 SharedArray<T>::begin(void) {
307 assert(object() != nullptr);
308 return static_cast<SAO*>(object())->begin();
309 }
310
311 template<class T>
312 forceinline typename SharedArray<T>::const_iterator
313 SharedArray<T>::begin(void) const {
314 assert(object() != nullptr);
315 return static_cast<SAO*>(object())->begin();
316 }
317
318 template<class T>
319 forceinline typename SharedArray<T>::iterator
320 SharedArray<T>::end(void) {
321 assert(object() != nullptr);
322 return static_cast<SAO*>(object())->end();
323 }
324
325 template<class T>
326 forceinline typename SharedArray<T>::const_iterator
327 SharedArray<T>::end(void) const {
328 assert(object() != nullptr);
329 return static_cast<SAO*>(object())->end();
330 }
331
332 template<class T>
333 forceinline typename SharedArray<T>::reverse_iterator
334 SharedArray<T>::rbegin(void) {
335 assert(object() != nullptr);
336 return reverse_iterator(static_cast<SAO*>(object())->end());
337 }
338
339 template<class T>
340 forceinline typename SharedArray<T>::const_reverse_iterator
341 SharedArray<T>::rbegin(void) const {
342 assert(object() != nullptr);
343 return const_reverse_iterator(static_cast<SAO*>(object())->end());
344 }
345
346 template<class T>
347 forceinline typename SharedArray<T>::reverse_iterator
348 SharedArray<T>::rend(void) {
349 assert(object() != nullptr);
350 return reverse_iterator(static_cast<SAO*>(object())->begin());
351 }
352
353 template<class T>
354 forceinline typename SharedArray<T>::const_reverse_iterator
355 SharedArray<T>::rend(void) const {
356 assert(object() != nullptr);
357 return const_reverse_iterator(static_cast<SAO*>(object())->begin());
358 }
359
360 template<class Char, class Traits, class T>
361 std::basic_ostream<Char,Traits>&
362 operator <<(std::basic_ostream<Char,Traits>& os,
363 const SharedArray<T>& x) {
364 std::basic_ostringstream<Char,Traits> s;
365 s.copyfmt(os); s.width(0);
366 s << '{';
367 if (x.size() > 0) {
368 s << x[0];
369 for (int i=1; i<x.size(); i++)
370 s << ", " << x[i];
371 }
372 s << '}';
373 return os << s.str();
374 }
375
376}
377
378// STATISTICS: kernel-other