00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef PPL_DB_Row_inlines_hh
00024 #define PPL_DB_Row_inlines_hh 1
00025
00026 #include <cassert>
00027 #include <algorithm>
00028 #include <iostream>
00029 #include "checked.defs.hh"
00030
00031 namespace Parma_Polyhedra_Library {
00032
00033 template <typename T>
00034 inline void*
00035 DB_Row_Impl_Handler<T>::Impl::operator new(const size_t fixed_size,
00036 const dimension_type capacity) {
00037 #if CXX_SUPPORTS_FLEXIBLE_ARRAYS
00038 return ::operator new(fixed_size + capacity*sizeof(T));
00039 #else
00040 assert(capacity >= 1);
00041 return ::operator new(fixed_size + (capacity-1)*sizeof(T));
00042 #endif
00043 }
00044
00045 template <typename T>
00046 inline void
00047 DB_Row_Impl_Handler<T>::Impl::operator delete(void* p) {
00048 ::operator delete(p);
00049 }
00050
00051 template <typename T>
00052 inline void
00053 DB_Row_Impl_Handler<T>::Impl::operator delete(void* p, dimension_type) {
00054 ::operator delete(p);
00055 }
00056
00057 template <typename T>
00058 inline dimension_type
00059 DB_Row_Impl_Handler<T>::Impl::max_size() {
00060 return size_t(-1)/sizeof(T);
00061 }
00062
00063 template <typename T>
00064 inline dimension_type
00065 DB_Row_Impl_Handler<T>::Impl::size() const {
00066 return size_;
00067 }
00068
00069 template <typename T>
00070 inline void
00071 DB_Row_Impl_Handler<T>::Impl::set_size(const dimension_type new_sz) {
00072 size_ = new_sz;
00073 }
00074
00075 template <typename T>
00076 inline void
00077 DB_Row_Impl_Handler<T>::Impl::bump_size() {
00078 ++size_;
00079 }
00080
00081 template <typename T>
00082 inline
00083 DB_Row_Impl_Handler<T>::Impl::Impl()
00084 : size_(0) {
00085 }
00086
00087 template <typename T>
00088 inline
00089 DB_Row_Impl_Handler<T>::Impl::~Impl() {
00090 shrink(0);
00091 }
00092
00093 template <typename T>
00094 inline
00095 DB_Row_Impl_Handler<T>::DB_Row_Impl_Handler()
00096 : impl(0) {
00097 #if EXTRA_ROW_DEBUG
00098 capacity_ = 0;
00099 #endif
00100 }
00101
00102 template <typename T>
00103 template <typename U>
00104 void
00105 DB_Row_Impl_Handler<T>::Impl::construct_upward_approximation(const U& y) {
00106 const dimension_type y_size = y.size();
00107 #if CXX_SUPPORTS_FLEXIBLE_ARRAYS
00108
00109 for (dimension_type i = 0; i < y_size; ++i) {
00110 construct(vec_[i], y[i], ROUND_UP);
00111 bump_size();
00112 }
00113 #else
00114 assert(y_size > 0);
00115 if (y_size > 0) {
00116 vec_[0] = y[0];
00117 bump_size();
00118
00119 for (dimension_type i = 1; i < y_size; ++i) {
00120 construct(vec_[i], y[i], ROUND_UP);
00121 bump_size();
00122 }
00123 }
00124 #endif
00125 }
00126
00127 template <typename T>
00128 inline
00129 DB_Row_Impl_Handler<T>::~DB_Row_Impl_Handler() {
00130 delete impl;
00131 }
00132
00133 template <typename T>
00134 inline T&
00135 DB_Row_Impl_Handler<T>::Impl::operator[](const dimension_type k) {
00136 assert(k < size());
00137 return vec_[k];
00138 }
00139
00140 template <typename T>
00141 inline const T&
00142 DB_Row_Impl_Handler<T>::Impl::operator[](const dimension_type k) const {
00143 assert(k < size());
00144 return vec_[k];
00145 }
00146
00147 template <typename T>
00148 inline dimension_type
00149 DB_Row<T>::max_size() {
00150 return DB_Row_Impl_Handler<T>::Impl::max_size();
00151 }
00152
00153 template <typename T>
00154 inline dimension_type
00155 DB_Row<T>::size() const {
00156 return this->impl->size();
00157 }
00158
00159 #if EXTRA_ROW_DEBUG
00160 template <typename T>
00161 inline dimension_type
00162 DB_Row<T>::capacity() const {
00163 return this->capacity_;
00164 }
00165 #endif // EXTRA_ROW_DEBUG
00166
00167 template <typename T>
00168 inline
00169 DB_Row<T>::DB_Row()
00170 : DB_Row_Impl_Handler<T>() {
00171 }
00172
00173 template <typename T>
00174 inline void
00175 DB_Row<T>::allocate(
00176 #if CXX_SUPPORTS_FLEXIBLE_ARRAYS
00177 const
00178 #endif
00179 dimension_type capacity) {
00180 DB_Row<T>& x = *this;
00181 assert(capacity <= max_size());
00182 #if !CXX_SUPPORTS_FLEXIBLE_ARRAYS
00183 if (capacity == 0)
00184 ++capacity;
00185 #endif
00186 assert(x.impl == 0);
00187 x.impl = new (capacity) typename DB_Row_Impl_Handler<T>::Impl();
00188 #if EXTRA_ROW_DEBUG
00189 assert(x.capacity_ == 0);
00190 x.capacity_ = capacity;
00191 #endif
00192 }
00193
00194 template <typename T>
00195 inline void
00196 DB_Row<T>::expand_within_capacity(const dimension_type new_size) {
00197 DB_Row<T>& x = *this;
00198 assert(x.impl);
00199 #if EXTRA_ROW_DEBUG
00200 assert(new_size <= x.capacity_);
00201 #endif
00202 x.impl->expand_within_capacity(new_size);
00203 }
00204
00205 template <typename T>
00206 inline void
00207 DB_Row<T>::copy_construct_coefficients(const DB_Row& y) {
00208 DB_Row<T>& x = *this;
00209 assert(x.impl && y.impl);
00210 #if EXTRA_ROW_DEBUG
00211 assert(y.size() <= x.capacity_);
00212 #endif
00213 x.impl->copy_construct_coefficients(*(y.impl));
00214 }
00215
00216 template <typename T>
00217 template <typename U>
00218 inline void
00219 DB_Row<T>::construct_upward_approximation(const DB_Row<U>& y,
00220 const dimension_type capacity) {
00221 DB_Row<T>& x = *this;
00222 assert(y.size() <= capacity && capacity <= max_size());
00223 allocate(capacity);
00224 assert(y.impl);
00225 x.impl->construct_upward_approximation(*(y.impl));
00226 }
00227
00228 template <typename T>
00229 inline void
00230 DB_Row<T>::construct(const dimension_type sz,
00231 const dimension_type capacity) {
00232 assert(sz <= capacity && capacity <= max_size());
00233 allocate(capacity);
00234 expand_within_capacity(sz);
00235 }
00236
00237 template <typename T>
00238 inline void
00239 DB_Row<T>::construct(const dimension_type sz) {
00240 construct(sz, sz);
00241 }
00242
00243 template <typename T>
00244 inline
00245 DB_Row<T>::DB_Row(const dimension_type sz,
00246 const dimension_type capacity)
00247 : DB_Row_Impl_Handler<T>() {
00248 construct(sz, capacity);
00249 }
00250
00251 template <typename T>
00252 inline
00253 DB_Row<T>::DB_Row(const dimension_type sz) {
00254 construct(sz);
00255 }
00256
00257 template <typename T>
00258 inline
00259 DB_Row<T>::DB_Row(const DB_Row& y)
00260 : DB_Row_Impl_Handler<T>() {
00261 if (y.impl) {
00262 allocate(compute_capacity(y.size(), max_size()));
00263 copy_construct_coefficients(y);
00264 }
00265 }
00266
00267 template <typename T>
00268 inline
00269 DB_Row<T>::DB_Row(const DB_Row& y,
00270 const dimension_type capacity)
00271 : DB_Row_Impl_Handler<T>() {
00272 assert(y.impl);
00273 assert(y.size() <= capacity && capacity <= max_size());
00274 allocate(capacity);
00275 copy_construct_coefficients(y);
00276 }
00277
00278 template <typename T>
00279 inline
00280 DB_Row<T>::DB_Row(const DB_Row& y,
00281 const dimension_type sz,
00282 const dimension_type capacity)
00283 : DB_Row_Impl_Handler<T>() {
00284 assert(y.impl);
00285 assert(y.size() <= sz && sz <= capacity && capacity <= max_size());
00286 allocate(capacity);
00287 copy_construct_coefficients(y);
00288 expand_within_capacity(sz);
00289 }
00290
00291 template <typename T>
00292 inline
00293 DB_Row<T>::~DB_Row() {
00294 }
00295
00296 template <typename T>
00297 inline void
00298 DB_Row<T>::shrink(const dimension_type new_size) {
00299 DB_Row<T>& x = *this;
00300 assert(x.impl);
00301 x.impl->shrink(new_size);
00302 }
00303
00304 template <typename T>
00305 inline void
00306 DB_Row<T>::swap(DB_Row& y) {
00307 DB_Row<T>& x = *this;
00308 std::swap(x.impl, y.impl);
00309 #if EXTRA_ROW_DEBUG
00310 std::swap(x.capacity_, y.capacity_);
00311 #endif
00312 }
00313
00314 template <typename T>
00315 inline void
00316 DB_Row<T>::assign(DB_Row& y) {
00317 DB_Row<T>& x = *this;
00318 x.impl = y.impl;
00319 #if EXTRA_ROW_DEBUG
00320 x.capacity_ = y.capacity_;
00321 #endif
00322 }
00323
00324 template <typename T>
00325 inline DB_Row<T>&
00326 DB_Row<T>::operator=(const DB_Row& y) {
00327
00328 DB_Row tmp(y);
00329
00330 swap(tmp);
00331
00332 return *this;
00333 }
00334
00335 template <typename T>
00336 inline T&
00337 DB_Row<T>::operator[](const dimension_type k) {
00338 DB_Row<T>& x = *this;
00339 return (*x.impl)[k];
00340 }
00341
00342 template <typename T>
00343 inline const T&
00344 DB_Row<T>::operator[](const dimension_type k) const {
00345 const DB_Row<T>& x = *this;
00346 return (*x.impl)[k];
00347 }
00348
00349 template <typename T>
00350 inline void
00351 DB_Row_Impl_Handler<T>::
00352 Impl::expand_within_capacity(const dimension_type new_size) {
00353 assert(size() <= new_size && new_size <= max_size());
00354 #if !CXX_SUPPORTS_FLEXIBLE_ARRAYS
00355
00356 if (size() == 0 && new_size > 0)
00357 bump_size();
00358 #endif
00359
00360 for (dimension_type i = size(); i < new_size; ++i) {
00361 new (&vec_[i]) T(PLUS_INFINITY);
00362 bump_size();
00363 }
00364 }
00365
00366 template <typename T>
00367 void
00368 DB_Row_Impl_Handler<T>::Impl::shrink(dimension_type new_size) {
00369 const dimension_type old_size = size();
00370 assert(new_size <= old_size);
00371
00372 set_size(new_size);
00373 #if !CXX_SUPPORTS_FLEXIBLE_ARRAYS
00374
00375 if (new_size == 0)
00376 ++new_size;
00377 #endif
00378
00379
00380 for (dimension_type i = old_size; i-- > new_size; )
00381 vec_[i].~T();
00382 }
00383
00384 template <typename T>
00385 void
00386 DB_Row_Impl_Handler<T>::Impl::copy_construct_coefficients(const Impl& y) {
00387 const dimension_type y_size = y.size();
00388 #if CXX_SUPPORTS_FLEXIBLE_ARRAYS
00389
00390 for (dimension_type i = 0; i < y_size; ++i) {
00391 new (&vec_[i]) T(y.vec_[i]);
00392 bump_size();
00393 }
00394 #else
00395 assert(y_size > 0);
00396 if (y_size > 0) {
00397 vec_[0] = y.vec_[0];
00398 bump_size();
00399
00400 for (dimension_type i = 1; i < y_size; ++i) {
00401 new (&vec_[i]) T(y.vec_[i]);
00402 bump_size();
00403 }
00404 }
00405 #endif
00406 }
00407
00408 template <typename T>
00409 typename DB_Row<T>::iterator
00410 DB_Row<T>::begin() {
00411 DB_Row<T>& x = *this;
00412 return iterator(x.impl->vec_);
00413 }
00414
00415 template <typename T>
00416 typename DB_Row<T>::iterator
00417 DB_Row<T>::end() {
00418 DB_Row<T>& x = *this;
00419 return iterator(x.impl->vec_ + x.impl->size_);
00420 }
00421
00422 template <typename T>
00423 typename DB_Row<T>::const_iterator
00424 DB_Row<T>::begin() const {
00425 const DB_Row<T>& x = *this;
00426 return const_iterator(x.impl->vec_);
00427 }
00428
00429 template <typename T>
00430 typename DB_Row<T>::const_iterator
00431 DB_Row<T>::end() const {
00432 const DB_Row<T>& x = *this;
00433 return const_iterator(x.impl->vec_ + x.impl->size_);
00434 }
00435
00436 template <typename T>
00437 inline bool
00438 DB_Row<T>::OK(const dimension_type row_size,
00439 const dimension_type
00440 #if EXTRA_ROW_DEBUG
00441 row_capacity
00442 #endif
00443 ) const {
00444 #ifndef NDEBUG
00445 using std::endl;
00446 using std::cerr;
00447 #endif
00448
00449 const DB_Row<T>& x = *this;
00450
00451 bool is_broken = false;
00452 #if EXTRA_ROW_DEBUG
00453 # if !CXX_SUPPORTS_FLEXIBLE_ARRAYS
00454 if (x.capacity_ == 0) {
00455 cerr << "Illegal row capacity: is 0, should be at least 1"
00456 << endl;
00457 is_broken = true;
00458 }
00459 else if (x.capacity_ == 1 && row_capacity == 0)
00460
00461 ;
00462 else
00463 # endif
00464 if (x.capacity_ != row_capacity) {
00465 cerr << "DB_Row capacity mismatch: is " << x.capacity_
00466 << ", should be " << row_capacity << "."
00467 << endl;
00468 is_broken = true;
00469 }
00470 #endif
00471 if (x.size() != row_size) {
00472 #ifndef NDEBUG
00473 cerr << "DB_Row size mismatch: is " << x.size()
00474 << ", should be " << row_size << "."
00475 << endl;
00476 #endif
00477 is_broken = true;
00478 }
00479 #if EXTRA_ROW_DEBUG
00480 if (x.capacity_ < x.size()) {
00481 #ifndef NDEBUG
00482 cerr << "DB_Row is completely broken: capacity is " << x.capacity_
00483 << ", size is " << x.size() << "."
00484 << endl;
00485 #endif
00486 is_broken = true;
00487 }
00488 #endif
00489
00490 for (dimension_type i = x.size(); i-- > 0; ) {
00491 const T& element = x[i];
00492
00493 if (!element.OK()) {
00494 is_broken = true;
00495 break;
00496 }
00497
00498 if (is_not_a_number(element)) {
00499 #ifndef NDEBUG
00500 cerr << "Not-a-number found in DB_Row."
00501 << endl;
00502 #endif
00503 is_broken = true;
00504 break;
00505 }
00506 }
00507
00508 return !is_broken;
00509 }
00510
00511
00513 template <typename T>
00514 inline bool
00515 operator==(const DB_Row<T>& x, const DB_Row<T>& y) {
00516 if (x.size() != y.size())
00517 return false;
00518 for (dimension_type i = x.size(); i-- > 0; )
00519 if (x[i] != y[i])
00520 return false;
00521 return true;
00522 }
00523
00525 template <typename T>
00526 inline bool
00527 operator!=(const DB_Row<T>& x, const DB_Row<T>& y) {
00528 return !(x == y);
00529 }
00530
00531 }
00532
00533
00534 namespace std {
00535
00537 template <typename T>
00538 inline void
00539 swap(Parma_Polyhedra_Library::DB_Row<T>& x,
00540 Parma_Polyhedra_Library::DB_Row<T>& y) {
00541 x.swap(y);
00542 }
00543
00545 template <typename T>
00546 inline void
00547 iter_swap(typename std::vector<Parma_Polyhedra_Library::DB_Row<T> >
00548 ::iterator x,
00549 typename std::vector<Parma_Polyhedra_Library::DB_Row<T> >
00550 ::iterator y) {
00551 swap(*x, *y);
00552 }
00553
00554 }
00555
00556 #endif // !defined(PPL_DB_Row_inlines_hh)