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