1 /* DB_Row class implementation: inline functions.
2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4
5 This file is part of the Parma Polyhedra Library (PPL).
6
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23
24 #ifndef PPL_DB_Row_inlines_hh
25 #define PPL_DB_Row_inlines_hh 1
26
27 #include "checked_defs.hh"
28 #include "assertions.hh"
29 #include <cstddef>
30 #include <limits>
31 #include <algorithm>
32 #include <iostream>
33
34 namespace Parma_Polyhedra_Library {
35
36 template <typename T>
37 inline void*
operator new(const size_t fixed_size,const dimension_type capacity)38 DB_Row_Impl_Handler<T>::Impl::operator new(const size_t fixed_size,
39 const dimension_type capacity) {
40 #if PPL_CXX_SUPPORTS_ZERO_LENGTH_ARRAYS
41 return ::operator new(fixed_size + capacity*sizeof(T));
42 #else
43 PPL_ASSERT(capacity >= 1);
44 return ::operator new(fixed_size + (capacity-1)*sizeof(T));
45 #endif
46 }
47
48 template <typename T>
49 inline void
operator delete(void * p)50 DB_Row_Impl_Handler<T>::Impl::operator delete(void* p) {
51 ::operator delete(p);
52 }
53
54 template <typename T>
55 inline void
operator delete(void * p,dimension_type)56 DB_Row_Impl_Handler<T>::Impl::operator delete(void* p, dimension_type) {
57 ::operator delete(p);
58 }
59
60 template <typename T>
61 inline memory_size_type
62 DB_Row_Impl_Handler<T>::Impl
total_memory_in_bytes(dimension_type capacity) const63 ::total_memory_in_bytes(dimension_type capacity) const {
64 return
65 sizeof(*this)
66 + capacity*sizeof(T)
67 #if !PPL_CXX_SUPPORTS_ZERO_LENGTH_ARRAYS
68 - 1*sizeof(T)
69 #endif
70 + external_memory_in_bytes();
71 }
72
73 template <typename T>
74 inline memory_size_type
total_memory_in_bytes() const75 DB_Row_Impl_Handler<T>::Impl::total_memory_in_bytes() const {
76 // In general, this is a lower bound, as the capacity of *this
77 // may be strictly greater than `size_'
78 return total_memory_in_bytes(size_);
79 }
80
81 template <typename T>
82 inline dimension_type
max_size()83 DB_Row_Impl_Handler<T>::Impl::max_size() {
84 return std::numeric_limits<size_t>::max() / sizeof(T);
85 }
86
87 template <typename T>
88 inline dimension_type
size() const89 DB_Row_Impl_Handler<T>::Impl::size() const {
90 return size_;
91 }
92
93 template <typename T>
94 inline void
set_size(const dimension_type new_sz)95 DB_Row_Impl_Handler<T>::Impl::set_size(const dimension_type new_sz) {
96 size_ = new_sz;
97 }
98
99 template <typename T>
100 inline void
bump_size()101 DB_Row_Impl_Handler<T>::Impl::bump_size() {
102 ++size_;
103 }
104
105 template <typename T>
106 inline
Impl()107 DB_Row_Impl_Handler<T>::Impl::Impl()
108 : size_(0) {
109 }
110
111 template <typename T>
112 inline
~Impl()113 DB_Row_Impl_Handler<T>::Impl::~Impl() {
114 shrink(0);
115 }
116
117 template <typename T>
118 inline
DB_Row_Impl_Handler()119 DB_Row_Impl_Handler<T>::DB_Row_Impl_Handler()
120 : impl(0) {
121 #if PPL_DB_ROW_EXTRA_DEBUG
122 capacity_ = 0;
123 #endif
124 }
125
126 template <typename T>
127 inline
~DB_Row_Impl_Handler()128 DB_Row_Impl_Handler<T>::~DB_Row_Impl_Handler() {
129 delete impl;
130 }
131
132 template <typename T>
133 inline T&
operator [](const dimension_type k)134 DB_Row_Impl_Handler<T>::Impl::operator[](const dimension_type k) {
135 PPL_ASSERT(k < size());
136 return vec_[k];
137 }
138
139 template <typename T>
140 inline const T&
operator [](const dimension_type k) const141 DB_Row_Impl_Handler<T>::Impl::operator[](const dimension_type k) const {
142 PPL_ASSERT(k < size());
143 return vec_[k];
144 }
145
146 template <typename T>
147 inline dimension_type
max_size()148 DB_Row<T>::max_size() {
149 return DB_Row_Impl_Handler<T>::Impl::max_size();
150 }
151
152 template <typename T>
153 inline dimension_type
size() const154 DB_Row<T>::size() const {
155 return this->impl->size();
156 }
157
158 #if PPL_DB_ROW_EXTRA_DEBUG
159 template <typename T>
160 inline dimension_type
capacity() const161 DB_Row<T>::capacity() const {
162 return this->capacity_;
163 }
164 #endif // PPL_DB_ROW_EXTRA_DEBUG
165
166 template <typename T>
167 inline
DB_Row()168 DB_Row<T>::DB_Row()
169 : DB_Row_Impl_Handler<T>() {
170 }
171
172 template <typename T>
173 inline void
allocate(const dimension_type capacity)174 DB_Row<T>::allocate(
175 #if PPL_CXX_SUPPORTS_ZERO_LENGTH_ARRAYS
176 const
177 #endif
178 dimension_type capacity) {
179 DB_Row<T>& x = *this;
180 PPL_ASSERT(capacity <= max_size());
181 #if !PPL_CXX_SUPPORTS_ZERO_LENGTH_ARRAYS
182 if (capacity == 0) {
183 ++capacity;
184 }
185 #endif
186 PPL_ASSERT(x.impl == 0);
187 x.impl = new(capacity) typename DB_Row_Impl_Handler<T>::Impl();
188 #if PPL_DB_ROW_EXTRA_DEBUG
189 PPL_ASSERT(x.capacity_ == 0);
190 x.capacity_ = capacity;
191 #endif
192 }
193
194 template <typename T>
195 inline void
expand_within_capacity(const dimension_type new_size)196 DB_Row<T>::expand_within_capacity(const dimension_type new_size) {
197 DB_Row<T>& x = *this;
198 PPL_ASSERT(x.impl);
199 #if PPL_DB_ROW_EXTRA_DEBUG
200 PPL_ASSERT(new_size <= x.capacity_);
201 #endif
202 x.impl->expand_within_capacity(new_size);
203 }
204
205 template <typename T>
206 inline void
copy_construct_coefficients(const DB_Row & y)207 DB_Row<T>::copy_construct_coefficients(const DB_Row& y) {
208 DB_Row<T>& x = *this;
209 PPL_ASSERT(x.impl && y.impl);
210 #if PPL_DB_ROW_EXTRA_DEBUG
211 PPL_ASSERT(y.size() <= x.capacity_);
212 #endif
213 x.impl->copy_construct_coefficients(*(y.impl));
214 }
215
216 template <typename T>
217 template <typename U>
218 inline void
construct_upward_approximation(const DB_Row<U> & y,const dimension_type capacity)219 DB_Row<T>::construct_upward_approximation(const DB_Row<U>& y,
220 const dimension_type capacity) {
221 DB_Row<T>& x = *this;
222 PPL_ASSERT(y.size() <= capacity && capacity <= max_size());
223 allocate(capacity);
224 PPL_ASSERT(y.impl);
225 x.impl->construct_upward_approximation(*(y.impl));
226 }
227
228 template <typename T>
229 inline void
construct(const dimension_type sz,const dimension_type capacity)230 DB_Row<T>::construct(const dimension_type sz,
231 const dimension_type capacity) {
232 PPL_ASSERT(sz <= capacity && capacity <= max_size());
233 allocate(capacity);
234 expand_within_capacity(sz);
235 }
236
237 template <typename T>
238 inline void
construct(const dimension_type sz)239 DB_Row<T>::construct(const dimension_type sz) {
240 construct(sz, sz);
241 }
242
243 template <typename T>
244 inline
DB_Row(const dimension_type sz,const dimension_type capacity)245 DB_Row<T>::DB_Row(const dimension_type sz,
246 const dimension_type capacity)
247 : DB_Row_Impl_Handler<T>() {
248 construct(sz, capacity);
249 }
250
251 template <typename T>
252 inline
DB_Row(const dimension_type sz)253 DB_Row<T>::DB_Row(const dimension_type sz) {
254 construct(sz);
255 }
256
257 template <typename T>
258 inline
DB_Row(const DB_Row & y)259 DB_Row<T>::DB_Row(const DB_Row& y)
260 : DB_Row_Impl_Handler<T>() {
261 if (y.impl != 0) {
262 allocate(compute_capacity(y.size(), max_size()));
263 copy_construct_coefficients(y);
264 }
265 }
266
267 template <typename T>
268 inline
DB_Row(const DB_Row & y,const dimension_type capacity)269 DB_Row<T>::DB_Row(const DB_Row& y,
270 const dimension_type capacity)
271 : DB_Row_Impl_Handler<T>() {
272 PPL_ASSERT(y.impl);
273 PPL_ASSERT(y.size() <= capacity && capacity <= max_size());
274 allocate(capacity);
275 copy_construct_coefficients(y);
276 }
277
278 template <typename T>
279 inline
DB_Row(const DB_Row & y,const dimension_type sz,const dimension_type capacity)280 DB_Row<T>::DB_Row(const DB_Row& y,
281 const dimension_type sz,
282 const dimension_type capacity)
283 : DB_Row_Impl_Handler<T>() {
284 PPL_ASSERT(y.impl);
285 PPL_ASSERT(y.size() <= sz && sz <= capacity && capacity <= max_size());
286 allocate(capacity);
287 copy_construct_coefficients(y);
288 expand_within_capacity(sz);
289 }
290
291 template <typename T>
292 inline
~DB_Row()293 DB_Row<T>::~DB_Row() {
294 }
295
296 template <typename T>
297 inline void
shrink(const dimension_type new_size)298 DB_Row<T>::shrink(const dimension_type new_size) {
299 DB_Row<T>& x = *this;
300 PPL_ASSERT(x.impl);
301 x.impl->shrink(new_size);
302 }
303
304 template <typename T>
305 inline void
m_swap(DB_Row & y)306 DB_Row<T>::m_swap(DB_Row& y) {
307 using std::swap;
308 DB_Row<T>& x = *this;
309 swap(x.impl, y.impl);
310 #if PPL_DB_ROW_EXTRA_DEBUG
311 swap(x.capacity_, y.capacity_);
312 #endif
313 }
314
315 template <typename T>
316 inline void
assign(DB_Row & y)317 DB_Row<T>::assign(DB_Row& y) {
318 DB_Row<T>& x = *this;
319 x.impl = y.impl;
320 #if PPL_DB_ROW_EXTRA_DEBUG
321 x.capacity_ = y.capacity_;
322 #endif
323 }
324
325 template <typename T>
326 inline DB_Row<T>&
operator =(const DB_Row & y)327 DB_Row<T>::operator=(const DB_Row& y) {
328 DB_Row tmp(y);
329 m_swap(tmp);
330 return *this;
331 }
332
333 template <typename T>
334 inline T&
operator [](const dimension_type k)335 DB_Row<T>::operator[](const dimension_type k) {
336 DB_Row<T>& x = *this;
337 return (*x.impl)[k];
338 }
339
340 template <typename T>
341 inline const T&
operator [](const dimension_type k) const342 DB_Row<T>::operator[](const dimension_type k) const {
343 const DB_Row<T>& x = *this;
344 return (*x.impl)[k];
345 }
346
347 template <typename T>
348 inline typename DB_Row<T>::iterator
begin()349 DB_Row<T>::begin() {
350 DB_Row<T>& x = *this;
351 return iterator(x.impl->vec_);
352 }
353
354 template <typename T>
355 inline typename DB_Row<T>::iterator
end()356 DB_Row<T>::end() {
357 DB_Row<T>& x = *this;
358 return iterator(x.impl->vec_ + x.impl->size_);
359 }
360
361 template <typename T>
362 inline typename DB_Row<T>::const_iterator
begin() const363 DB_Row<T>::begin() const {
364 const DB_Row<T>& x = *this;
365 return const_iterator(x.impl->vec_);
366 }
367
368 template <typename T>
369 inline typename DB_Row<T>::const_iterator
end() const370 DB_Row<T>::end() const {
371 const DB_Row<T>& x = *this;
372 return const_iterator(x.impl->vec_ + x.impl->size_);
373 }
374
375 template <typename T>
376 inline memory_size_type
external_memory_in_bytes(dimension_type capacity) const377 DB_Row<T>::external_memory_in_bytes(dimension_type capacity) const {
378 const DB_Row<T>& x = *this;
379 return x.impl->total_memory_in_bytes(capacity);
380 }
381
382 template <typename T>
383 inline memory_size_type
total_memory_in_bytes(dimension_type capacity) const384 DB_Row<T>::total_memory_in_bytes(dimension_type capacity) const {
385 return sizeof(*this) + external_memory_in_bytes(capacity);
386 }
387
388 template <typename T>
389 inline memory_size_type
external_memory_in_bytes() const390 DB_Row<T>::external_memory_in_bytes() const {
391 const DB_Row<T>& x = *this;
392 #if PPL_DB_ROW_EXTRA_DEBUG
393 return x.impl->total_memory_in_bytes(x.capacity_);
394 #else
395 return x.impl->total_memory_in_bytes();
396 #endif
397 }
398
399 template <typename T>
400 inline memory_size_type
total_memory_in_bytes() const401 DB_Row<T>::total_memory_in_bytes() const {
402 return sizeof(*this) + external_memory_in_bytes();
403 }
404
405 /*! \relates DB_Row */
406 template <typename T>
407 inline bool
operator !=(const DB_Row<T> & x,const DB_Row<T> & y)408 operator!=(const DB_Row<T>& x, const DB_Row<T>& y) {
409 return !(x == y);
410 }
411
412 /*! \relates DB_Row */
413 template <typename T>
414 inline void
swap(DB_Row<T> & x,DB_Row<T> & y)415 swap(DB_Row<T>& x, DB_Row<T>& y) {
416 x.m_swap(y);
417 }
418
419 /*! \relates DB_Row */
420 template <typename T>
421 inline void
iter_swap(typename std::vector<DB_Row<T>>::iterator x,typename std::vector<DB_Row<T>>::iterator y)422 iter_swap(typename std::vector<DB_Row<T> >::iterator x,
423 typename std::vector<DB_Row<T> >::iterator y) {
424 swap(*x, *y);
425 }
426
427 } // namespace Parma_Polyhedra_Library
428
429 #endif // !defined(PPL_DB_Row_inlines_hh)
430