1 /* DB_Row class declaration. 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_defs_hh 25 #define PPL_DB_Row_defs_hh 1 26 27 #include "DB_Row_types.hh" 28 #include "globals_types.hh" 29 #include "Ptr_Iterator_defs.hh" 30 #include <cstddef> 31 #include <vector> 32 33 #ifndef PPL_DB_ROW_EXTRA_DEBUG 34 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG 35 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 36 /*! \brief 37 When PPL_DB_ROW_EXTRA_DEBUG evaluates to <CODE>true</CODE>, each instance 38 of the class DB_Row carries its own capacity; this enables extra 39 consistency checks to be performed. 40 \ingroup PPL_CXX_interface 41 */ 42 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 43 #define PPL_DB_ROW_EXTRA_DEBUG 1 44 #else // !defined(PPL_ABI_BREAKING_EXTRA_DEBUG) 45 #define PPL_DB_ROW_EXTRA_DEBUG 0 46 #endif // !defined(PPL_ABI_BREAKING_EXTRA_DEBUG) 47 #endif // !defined(PPL_DB_ROW_EXTRA_DEBUG) 48 49 50 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 51 //! The handler of the actual DB_Row implementation. 52 /*! \ingroup PPL_CXX_interface 53 Exception-safety is the only responsibility of this class: it has 54 to ensure that its \p impl member is correctly deallocated. 55 */ 56 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 57 template <typename T> 58 class Parma_Polyhedra_Library::DB_Row_Impl_Handler { 59 public: 60 //! Default constructor. 61 DB_Row_Impl_Handler(); 62 63 //! Destructor. 64 ~DB_Row_Impl_Handler(); 65 66 class Impl; 67 68 //! A pointer to the actual implementation. 69 Impl* impl; 70 71 #if PPL_DB_ROW_EXTRA_DEBUG 72 //! The capacity of \p impl (only available during debugging). 73 dimension_type capacity_; 74 #endif // PPL_DB_ROW_EXTRA_DEBUG 75 76 private: 77 //! Private and unimplemented: copy construction is not allowed. 78 DB_Row_Impl_Handler(const DB_Row_Impl_Handler&); 79 80 //! Private and unimplemented: copy assignment is not allowed. 81 DB_Row_Impl_Handler& operator=(const DB_Row_Impl_Handler&); 82 }; 83 84 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 85 //! The base class for the single rows of matrices. 86 /*! \ingroup PPL_CXX_interface 87 The class template DB_Row<T> allows for the efficient representation of 88 the single rows of a DB_Matrix. It contains elements of type T stored 89 as a vector. The class T is a family of extended numbers that 90 must provide representation for 91 \f$ -\infty \f$, \f$0\f$,\f$ +\infty \f$ (and, consequently for <EM>nan</EM>, 92 <EM>not a number</EM>, since this arises as the ``result'' of 93 undefined sums like \f$ +\infty + (-\infty) \f$). 94 95 The class T must provide the following methods: 96 97 \code 98 T() 99 \endcode 100 is the default constructor: no assumption is made on the particular 101 object constructed, provided <CODE>T().OK()</CODE> gives <CODE>true</CODE> 102 (see below). 103 \code 104 ~T() 105 \endcode 106 is the destructor. 107 \code 108 bool is_nan() const 109 \endcode 110 returns <CODE>true</CODE> if and only \p *this represents 111 the <EM>not a number</EM> value. 112 \code 113 bool OK() const 114 \endcode 115 returns <CODE>true</CODE> if and only if \p *this satisfies all 116 its invariants. 117 */ 118 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 119 template <typename T> 120 class Parma_Polyhedra_Library::DB_Row : private DB_Row_Impl_Handler<T> { 121 public: 122 //! Pre-constructs a row: construction must be completed by construct(). 123 DB_Row(); 124 125 //! \name Post-constructors. 126 //@{ 127 //! Constructs properly a default-constructed element. 128 /*! 129 Builds a row with size \p sz and minimum capacity. 130 */ 131 void construct(dimension_type sz); 132 133 //! Constructs properly a default-constructed element. 134 /*! 135 \param sz 136 The size of the row that will be constructed. 137 138 \param capacity 139 The minimum capacity of the row that will be constructed. 140 141 The row that we are constructing has a minimum capacity of 142 (i.e., it can contain at least) \p elements, \p sz of which 143 will be constructed now. 144 */ 145 void construct(dimension_type sz, dimension_type capacity); 146 147 //! Constructs properly a conservative approximation of \p y. 148 /*! 149 \param y 150 A row containing the elements whose upward approximations will 151 be used to properly construct \p *this. 152 153 \param capacity 154 The capacity of the constructed row. 155 156 It is assumed that \p capacity is greater than or equal to the 157 size of \p y. 158 */ 159 template <typename U> 160 void construct_upward_approximation(const DB_Row<U>& y, 161 dimension_type capacity); 162 163 //@} 164 165 //! Tight constructor: resizing will require reallocation. 166 DB_Row(dimension_type sz); 167 168 //! Sizing constructor with capacity. 169 DB_Row(dimension_type sz, dimension_type capacity); 170 171 //! Ordinary copy constructor. 172 DB_Row(const DB_Row& y); 173 174 //! Copy constructor with specified capacity. 175 /*! 176 It is assumed that \p capacity is greater than or equal to \p y size. 177 */ 178 DB_Row(const DB_Row& y, dimension_type capacity); 179 180 //! Copy constructor with specified size and capacity. 181 /*! 182 It is assumed that \p sz is greater than or equal to the size of \p y 183 and, of course, that \p sz is less than or equal to \p capacity. 184 Any new position is initialized to \f$+\infty\f$. 185 */ 186 DB_Row(const DB_Row& y, dimension_type sz, dimension_type capacity); 187 188 //! Destructor. 189 ~DB_Row(); 190 191 //! Assignment operator. 192 DB_Row& operator=(const DB_Row& y); 193 194 //! Swaps \p *this with \p y. 195 void m_swap(DB_Row& y); 196 197 //! Assigns the implementation of \p y to \p *this. 198 void assign(DB_Row& y); 199 200 /*! \brief 201 Allocates memory for a default constructed DB_Row object, 202 allowing for \p capacity coefficients at most. 203 204 It is assumed that no allocation has been performed before 205 (otherwise, a memory leak will occur). 206 After execution, the size of the DB_Row object is zero. 207 */ 208 void allocate(dimension_type capacity); 209 210 //! Expands the row to size \p new_size. 211 /*! 212 Adds new positions to the implementation of the row 213 obtaining a new row with size \p new_size. 214 It is assumed that \p new_size is between the current size 215 and capacity of the row. The new positions are initialized 216 to \f$+\infty\f$. 217 */ 218 void expand_within_capacity(dimension_type new_size); 219 220 //! Shrinks the row by erasing elements at the end. 221 /*! 222 Destroys elements of the row implementation 223 from position \p new_size to the end. 224 It is assumed that \p new_size is not greater than the current size. 225 */ 226 void shrink(dimension_type new_size); 227 228 //! Returns the size() of the largest possible DB_Row. 229 static dimension_type max_size(); 230 231 //! Gives the number of coefficients currently in use. 232 dimension_type size() const; 233 234 //! \name Subscript operators. 235 //@{ 236 //! Returns a reference to the element of the row indexed by \p k. 237 T& operator[](dimension_type k); 238 239 //! Returns a constant reference to the element of the row indexed by \p k. 240 const T& operator[](dimension_type k) const; 241 //@} 242 243 //! A (non const) random access iterator to access the row's elements. 244 typedef Implementation::Ptr_Iterator<T*> iterator; 245 246 //! A const random access iterator to access the row's elements. 247 typedef Implementation::Ptr_Iterator<const T*> const_iterator; 248 249 /*! \brief 250 Returns the const iterator pointing to the first element, 251 if \p *this is not empty; 252 otherwise, returns the past-the-end const iterator. 253 */ 254 iterator begin(); 255 256 //! Returns the past-the-end iterator. 257 iterator end(); 258 259 /*! \brief 260 Returns the const iterator pointing to the first element, 261 if \p *this is not empty; 262 otherwise, returns the past-the-end const iterator. 263 */ 264 const_iterator begin() const; 265 266 //! Returns the past-the-end const iterator. 267 const_iterator end() const; 268 269 /*! \brief 270 Returns a lower bound to the total size in bytes of the memory 271 occupied by \p *this. 272 */ 273 memory_size_type total_memory_in_bytes() const; 274 275 /*! \brief 276 Returns a lower bound to the size in bytes of the memory 277 managed by \p *this. 278 */ 279 memory_size_type external_memory_in_bytes() const; 280 281 /*! \brief 282 Returns the total size in bytes of the memory occupied by \p *this, 283 provided the capacity of \p *this is given by \p capacity. 284 */ 285 memory_size_type total_memory_in_bytes(dimension_type capacity) const; 286 287 /*! \brief 288 Returns the size in bytes of the memory managed by \p *this, 289 provided the capacity of \p *this is given by \p capacity. 290 */ 291 memory_size_type external_memory_in_bytes(dimension_type capacity) const; 292 293 //! Checks if all the invariants are satisfied. 294 bool OK(dimension_type row_size, dimension_type row_capacity) const; 295 296 private: 297 template <typename U> friend class Parma_Polyhedra_Library::DB_Row; 298 299 //! Exception-safe copy construction mechanism for coefficients. 300 void copy_construct_coefficients(const DB_Row& y); 301 302 #if PPL_DB_ROW_EXTRA_DEBUG 303 //! Returns the capacity of the row (only available during debugging). 304 dimension_type capacity() const; 305 #endif // PPL_DB_ROW_EXTRA_DEBUG 306 }; 307 308 namespace Parma_Polyhedra_Library { 309 310 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 311 //! Swaps \p x with \p y. 312 /*! \relates DB_Row */ 313 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 314 template <typename T> 315 void swap(DB_Row<T>& x, DB_Row<T>& y); 316 317 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 318 //! Swaps objects referred by \p x and \p y. 319 /*! \relates DB_Row */ 320 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 321 template <typename T> 322 void iter_swap(typename std::vector<DB_Row<T> >::iterator x, 323 typename std::vector<DB_Row<T> >::iterator y); 324 325 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 326 //! \name Classical comparison operators. 327 //@{ 328 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 329 /*! \relates DB_Row */ 330 template <typename T> 331 bool operator==(const DB_Row<T>& x, const DB_Row<T>& y); 332 333 /*! \relates DB_Row */ 334 template <typename T> 335 bool operator!=(const DB_Row<T>& x, const DB_Row<T>& y); 336 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 337 //@} 338 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 339 340 } // namespace Parma_Polyhedra_Library 341 342 343 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 344 //! The real implementation of a DB_Row object. 345 /*! \ingroup PPL_CXX_interface 346 The class DB_Row_Impl_Handler::Impl provides the implementation of 347 DB_Row objects and, in particular, of the corresponding memory 348 allocation functions. 349 */ 350 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 351 template <typename T> 352 class Parma_Polyhedra_Library::DB_Row_Impl_Handler<T>::Impl { 353 public: 354 //! \name Custom allocator and deallocator. 355 //@{ 356 357 /*! \brief 358 Allocates a chunk of memory able to contain \p capacity T objects 359 beyond the specified \p fixed_size and returns a pointer to the new 360 allocated memory. 361 */ 362 static void* operator new(size_t fixed_size, dimension_type capacity); 363 364 //! Uses the standard delete operator to free the memory \p p points to. 365 static void operator delete(void* p); 366 367 /*! \brief 368 Placement version: uses the standard operator delete to free 369 the memory \p p points to. 370 */ 371 static void operator delete(void* p, dimension_type capacity); 372 //@} 373 374 //! Default constructor. 375 Impl(); 376 377 //! Destructor. 378 /*! 379 Uses <CODE>shrink()</CODE> method with argument \f$0\f$ 380 to delete all the row elements. 381 */ 382 ~Impl(); 383 384 //! Expands the row to size \p new_size. 385 /*! 386 It is assumed that \p new_size is between the current size and capacity. 387 */ 388 void expand_within_capacity(dimension_type new_size); 389 390 //! Shrinks the row by erasing elements at the end. 391 /*! 392 It is assumed that \p new_size is not greater than the current size. 393 */ 394 void shrink(dimension_type new_size); 395 396 //! Exception-safe copy construction mechanism for coefficients. 397 void copy_construct_coefficients(const Impl& y); 398 399 /*! \brief 400 Exception-safe upward approximation construction mechanism 401 for coefficients. 402 */ 403 template <typename U> 404 void construct_upward_approximation(const U& y); 405 406 //! Returns the size() of the largest possible Impl. 407 static dimension_type max_size(); 408 409 //! \name Size accessors. 410 //@{ 411 //! Returns the actual size of \p this. 412 dimension_type size() const; 413 414 //! Sets to \p new_sz the actual size of \p *this. 415 void set_size(dimension_type new_sz); 416 417 //! Increments the size of \p *this by 1. 418 void bump_size(); 419 //@} 420 421 //! \name Subscript operators. 422 //@{ 423 //! Returns a reference to the element of \p *this indexed by \p k. 424 T& operator[](dimension_type k); 425 426 //! Returns a constant reference to the element of \p *this indexed by \p k. 427 const T& operator[](dimension_type k) const; 428 //@} 429 430 /*! \brief 431 Returns a lower bound to the total size in bytes of the memory 432 occupied by \p *this. 433 */ 434 memory_size_type total_memory_in_bytes() const; 435 436 //! Returns the total size in bytes of the memory occupied by \p *this. 437 memory_size_type total_memory_in_bytes(dimension_type capacity) const; 438 439 //! Returns the size in bytes of the memory managed by \p *this. 440 memory_size_type external_memory_in_bytes() const; 441 442 private: 443 friend class DB_Row<T>; 444 445 //! The number of coefficients in the row. 446 dimension_type size_; 447 448 //! The vector of coefficients. 449 T vec_[ 450 #if PPL_CXX_SUPPORTS_ZERO_LENGTH_ARRAYS 451 0 452 #else 453 1 454 #endif 455 ]; 456 457 //! Private and unimplemented: copy construction is not allowed. 458 Impl(const Impl& y); 459 460 //! Private and unimplemented: assignment is not allowed. 461 Impl& operator=(const Impl&); 462 463 //! Exception-safe copy construction mechanism. 464 void copy_construct(const Impl& y); 465 }; 466 467 #include "DB_Row_inlines.hh" 468 #include "DB_Row_templates.hh" 469 470 #endif // !defined(PPL_DB_Row_defs_hh) 471