00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PPL_DB_Row_inlines_hh
00025 #define PPL_DB_Row_inlines_hh 1
00026
00027 #include "checked.defs.hh"
00028 #include "assert.hh"
00029 #include <cstddef>
00030 #include <limits>
00031 #include <algorithm>
00032 #include <iostream>
00033
00034 namespace Parma_Polyhedra_Library {
00035
00036 template <typename T>
00037 inline void*
00038 DB_Row_Impl_Handler<T>::Impl::operator new(const size_t fixed_size,
00039 const dimension_type capacity) {
00040 #if PPL_CXX_SUPPORTS_FLEXIBLE_ARRAYS
00041 return ::operator new(fixed_size + capacity*sizeof(T));
00042 #else
00043 PPL_ASSERT(capacity >= 1);
00044 return ::operator new(fixed_size + (capacity-1)*sizeof(T));
00045 #endif
00046 }
00047
00048 template <typename T>
00049 inline void
00050 DB_Row_Impl_Handler<T>::Impl::operator delete(void* p) {
00051 ::operator delete(p);
00052 }
00053
00054 template <typename T>
00055 inline void
00056 DB_Row_Impl_Handler<T>::Impl::operator delete(void* p, dimension_type) {
00057 ::operator delete(p);
00058 }
00059
00060 template <typename T>
00061 inline memory_size_type
00062 DB_Row_Impl_Handler<T>::Impl
00063 ::total_memory_in_bytes(dimension_type capacity) const {
00064 return
00065 sizeof(*this)
00066 + capacity*sizeof(T)
00067 #if !PPL_CXX_SUPPORTS_FLEXIBLE_ARRAYS
00068 - 1*sizeof(T)
00069 #endif
00070 + external_memory_in_bytes();
00071 }
00072
00073 template <typename T>
00074 inline memory_size_type
00075 DB_Row_Impl_Handler<T>::Impl::total_memory_in_bytes() const {
00076
00077
00078 return total_memory_in_bytes(size_);
00079 }
00080
00081 template <typename T>
00082 inline dimension_type
00083 DB_Row_Impl_Handler<T>::Impl::max_size() {
00084 return std::numeric_limits<size_t>::max() / sizeof(T);
00085 }
00086
00087 template <typename T>
00088 inline dimension_type
00089 DB_Row_Impl_Handler<T>::Impl::size() const {
00090 return size_;
00091 }
00092
00093 template <typename T>
00094 inline void
00095 DB_Row_Impl_Handler<T>::Impl::set_size(const dimension_type new_sz) {
00096 size_ = new_sz;
00097 }
00098
00099 template <typename T>
00100 inline void
00101 DB_Row_Impl_Handler<T>::Impl::bump_size() {
00102 ++size_;
00103 }
00104
00105 template <typename T>
00106 inline
00107 DB_Row_Impl_Handler<T>::Impl::Impl()
00108 : size_(0) {
00109 }
00110
00111 template <typename T>
00112 inline
00113 DB_Row_Impl_Handler<T>::Impl::~Impl() {
00114 shrink(0);
00115 }
00116
00117 template <typename T>
00118 inline
00119 DB_Row_Impl_Handler<T>::DB_Row_Impl_Handler()
00120 : impl(0) {
00121 #if PPL_DB_ROW_EXTRA_DEBUG
00122 capacity_ = 0;
00123 #endif
00124 }
00125
00126 template <typename T>
00127 inline
00128 DB_Row_Impl_Handler<T>::~DB_Row_Impl_Handler() {
00129 delete impl;
00130 }
00131
00132 template <typename T>
00133 inline T&
00134 DB_Row_Impl_Handler<T>::Impl::operator[](const dimension_type k) {
00135 PPL_ASSERT(k < size());
00136 return vec_[k];
00137 }
00138
00139 template <typename T>
00140 inline const T&
00141 DB_Row_Impl_Handler<T>::Impl::operator[](const dimension_type k) const {
00142 PPL_ASSERT(k < size());
00143 return vec_[k];
00144 }
00145
00146 template <typename T>
00147 inline dimension_type
00148 DB_Row<T>::max_size() {
00149 return DB_Row_Impl_Handler<T>::Impl::max_size();
00150 }
00151
00152 template <typename T>
00153 inline dimension_type
00154 DB_Row<T>::size() const {
00155 return this->impl->size();
00156 }
00157
00158 #if PPL_DB_ROW_EXTRA_DEBUG
00159 template <typename T>
00160 inline dimension_type
00161 DB_Row<T>::capacity() const {
00162 return this->capacity_;
00163 }
00164 #endif // PPL_DB_ROW_EXTRA_DEBUG
00165
00166 template <typename T>
00167 inline
00168 DB_Row<T>::DB_Row()
00169 : DB_Row_Impl_Handler<T>() {
00170 }
00171
00172 template <typename T>
00173 inline void
00174 DB_Row<T>::allocate(
00175 #if PPL_CXX_SUPPORTS_FLEXIBLE_ARRAYS
00176 const
00177 #endif
00178 dimension_type capacity) {
00179 DB_Row<T>& x = *this;
00180 PPL_ASSERT(capacity <= max_size());
00181 #if !PPL_CXX_SUPPORTS_FLEXIBLE_ARRAYS
00182 if (capacity == 0)
00183 ++capacity;
00184 #endif
00185 PPL_ASSERT(x.impl == 0);
00186 x.impl = new (capacity) typename DB_Row_Impl_Handler<T>::Impl();
00187 #if PPL_DB_ROW_EXTRA_DEBUG
00188 PPL_ASSERT(x.capacity_ == 0);
00189 x.capacity_ = capacity;
00190 #endif
00191 }
00192
00193 template <typename T>
00194 inline void
00195 DB_Row<T>::expand_within_capacity(const dimension_type new_size) {
00196 DB_Row<T>& x = *this;
00197 PPL_ASSERT(x.impl);
00198 #if PPL_DB_ROW_EXTRA_DEBUG
00199 PPL_ASSERT(new_size <= x.capacity_);
00200 #endif
00201 x.impl->expand_within_capacity(new_size);
00202 }
00203
00204 template <typename T>
00205 inline void
00206 DB_Row<T>::copy_construct_coefficients(const DB_Row& y) {
00207 DB_Row<T>& x = *this;
00208 PPL_ASSERT(x.impl && y.impl);
00209 #if PPL_DB_ROW_EXTRA_DEBUG
00210 PPL_ASSERT(y.size() <= x.capacity_);
00211 #endif
00212 x.impl->copy_construct_coefficients(*(y.impl));
00213 }
00214
00215 template <typename T>
00216 template <typename U>
00217 inline void
00218 DB_Row<T>::construct_upward_approximation(const DB_Row<U>& y,
00219 const dimension_type capacity) {
00220 DB_Row<T>& x = *this;
00221 PPL_ASSERT(y.size() <= capacity && capacity <= max_size());
00222 allocate(capacity);
00223 PPL_ASSERT(y.impl);
00224 x.impl->construct_upward_approximation(*(y.impl));
00225 }
00226
00227 template <typename T>
00228 inline void
00229 DB_Row<T>::construct(const dimension_type sz,
00230 const dimension_type capacity) {
00231 PPL_ASSERT(sz <= capacity && capacity <= max_size());
00232 allocate(capacity);
00233 expand_within_capacity(sz);
00234 }
00235
00236 template <typename T>
00237 inline void
00238 DB_Row<T>::construct(const dimension_type sz) {
00239 construct(sz, sz);
00240 }
00241
00242 template <typename T>
00243 inline
00244 DB_Row<T>::DB_Row(const dimension_type sz,
00245 const dimension_type capacity)
00246 : DB_Row_Impl_Handler<T>() {
00247 construct(sz, capacity);
00248 }
00249
00250 template <typename T>
00251 inline
00252 DB_Row<T>::DB_Row(const dimension_type sz) {
00253 construct(sz);
00254 }
00255
00256 template <typename T>
00257 inline
00258 DB_Row<T>::DB_Row(const DB_Row& y)
00259 : DB_Row_Impl_Handler<T>() {
00260 if (y.impl) {
00261 allocate(compute_capacity(y.size(), max_size()));
00262 copy_construct_coefficients(y);
00263 }
00264 }
00265
00266 template <typename T>
00267 inline
00268 DB_Row<T>::DB_Row(const DB_Row& y,
00269 const dimension_type capacity)
00270 : DB_Row_Impl_Handler<T>() {
00271 PPL_ASSERT(y.impl);
00272 PPL_ASSERT(y.size() <= capacity && capacity <= max_size());
00273 allocate(capacity);
00274 copy_construct_coefficients(y);
00275 }
00276
00277 template <typename T>
00278 inline
00279 DB_Row<T>::DB_Row(const DB_Row& y,
00280 const dimension_type sz,
00281 const dimension_type capacity)
00282 : DB_Row_Impl_Handler<T>() {
00283 PPL_ASSERT(y.impl);
00284 PPL_ASSERT(y.size() <= sz && sz <= capacity && capacity <= max_size());
00285 allocate(capacity);
00286 copy_construct_coefficients(y);
00287 expand_within_capacity(sz);
00288 }
00289
00290 template <typename T>
00291 inline
00292 DB_Row<T>::~DB_Row() {
00293 }
00294
00295 template <typename T>
00296 inline void
00297 DB_Row<T>::shrink(const dimension_type new_size) {
00298 DB_Row<T>& x = *this;
00299 PPL_ASSERT(x.impl);
00300 x.impl->shrink(new_size);
00301 }
00302
00303 template <typename T>
00304 inline void
00305 DB_Row<T>::swap(DB_Row& y) {
00306 DB_Row<T>& x = *this;
00307 std::swap(x.impl, y.impl);
00308 #if PPL_DB_ROW_EXTRA_DEBUG
00309 std::swap(x.capacity_, y.capacity_);
00310 #endif
00311 }
00312
00313 template <typename T>
00314 inline void
00315 DB_Row<T>::assign(DB_Row& y) {
00316 DB_Row<T>& x = *this;
00317 x.impl = y.impl;
00318 #if PPL_DB_ROW_EXTRA_DEBUG
00319 x.capacity_ = y.capacity_;
00320 #endif
00321 }
00322
00323 template <typename T>
00324 inline DB_Row<T>&
00325 DB_Row<T>::operator=(const DB_Row& y) {
00326
00327 DB_Row tmp(y);
00328
00329 swap(tmp);
00330
00331 return *this;
00332 }
00333
00334 template <typename T>
00335 inline T&
00336 DB_Row<T>::operator[](const dimension_type k) {
00337 DB_Row<T>& x = *this;
00338 return (*x.impl)[k];
00339 }
00340
00341 template <typename T>
00342 inline const T&
00343 DB_Row<T>::operator[](const dimension_type k) const {
00344 const DB_Row<T>& x = *this;
00345 return (*x.impl)[k];
00346 }
00347
00348 template <typename T>
00349 inline typename DB_Row<T>::iterator
00350 DB_Row<T>::begin() {
00351 DB_Row<T>& x = *this;
00352 return iterator(x.impl->vec_);
00353 }
00354
00355 template <typename T>
00356 inline typename DB_Row<T>::iterator
00357 DB_Row<T>::end() {
00358 DB_Row<T>& x = *this;
00359 return iterator(x.impl->vec_ + x.impl->size_);
00360 }
00361
00362 template <typename T>
00363 inline typename DB_Row<T>::const_iterator
00364 DB_Row<T>::begin() const {
00365 const DB_Row<T>& x = *this;
00366 return const_iterator(x.impl->vec_);
00367 }
00368
00369 template <typename T>
00370 inline typename DB_Row<T>::const_iterator
00371 DB_Row<T>::end() const {
00372 const DB_Row<T>& x = *this;
00373 return const_iterator(x.impl->vec_ + x.impl->size_);
00374 }
00375
00376 template <typename T>
00377 inline memory_size_type
00378 DB_Row<T>::external_memory_in_bytes(dimension_type capacity) const {
00379 const DB_Row<T>& x = *this;
00380 return x.impl->total_memory_in_bytes(capacity);
00381 }
00382
00383 template <typename T>
00384 inline memory_size_type
00385 DB_Row<T>::total_memory_in_bytes(dimension_type capacity) const {
00386 return sizeof(*this) + external_memory_in_bytes(capacity);
00387 }
00388
00389 template <typename T>
00390 inline memory_size_type
00391 DB_Row<T>::external_memory_in_bytes() const {
00392 const DB_Row<T>& x = *this;
00393 #if PPL_DB_ROW_EXTRA_DEBUG
00394 return x.impl->total_memory_in_bytes(x.capacity_);
00395 #else
00396 return x.impl->total_memory_in_bytes();
00397 #endif
00398 }
00399
00400 template <typename T>
00401 inline memory_size_type
00402 DB_Row<T>::total_memory_in_bytes() const {
00403 return sizeof(*this) + external_memory_in_bytes();
00404 }
00405
00407 template <typename T>
00408 inline bool
00409 operator!=(const DB_Row<T>& x, const DB_Row<T>& y) {
00410 return !(x == y);
00411 }
00412
00413 }
00414
00415
00416 namespace std {
00417
00419 template <typename T>
00420 inline void
00421 swap(Parma_Polyhedra_Library::DB_Row<T>& x,
00422 Parma_Polyhedra_Library::DB_Row<T>& y) {
00423 x.swap(y);
00424 }
00425
00427 template <typename T>
00428 inline void
00429 iter_swap(typename std::vector<Parma_Polyhedra_Library::DB_Row<T> >
00430 ::iterator x,
00431 typename std::vector<Parma_Polyhedra_Library::DB_Row<T> >
00432 ::iterator y) {
00433 swap(*x, *y);
00434 }
00435
00436 }
00437
00438 #endif // !defined(PPL_DB_Row_inlines_hh)