1 /* $Id: CoinIndexedVector.hpp 2084 2019-01-09 14:17:08Z forrest $ */
2 // Copyright (C) 2000, International Business Machines
3 // Corporation and others.  All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5 
6 #ifndef CoinIndexedVector_H
7 #define CoinIndexedVector_H
8 
9 #if defined(_MSC_VER)
10 // Turn off compiler warning about long names
11 #pragma warning(disable : 4786)
12 #endif
13 
14 #include <map>
15 #include "CoinFinite.hpp"
16 #ifndef CLP_NO_VECTOR
17 #include "CoinPackedVectorBase.hpp"
18 #endif
19 #include "CoinSort.hpp"
20 #include "CoinHelperFunctions.hpp"
21 #include <cassert>
22 
23 #ifndef COIN_FLOAT
24 #define COIN_INDEXED_TINY_ELEMENT 1.0e-50
25 #define COIN_INDEXED_REALLY_TINY_ELEMENT 1.0e-100
26 #else
27 #define COIN_INDEXED_TINY_ELEMENT 1.0e-35
28 #define COIN_INDEXED_REALLY_TINY_ELEMENT 1.0e-39
29 #endif
30 
31 /** Indexed Vector
32 
33 This stores values unpacked but apart from that is a bit like CoinPackedVector.
34 It is designed to be lightweight in normal use.
35 
36 It now has a "packed" mode when it is even more like CoinPackedVector
37 
38 Indices array has capacity_ extra chars which are zeroed and can
39 be used for any purpose - but must be re-zeroed
40 
41 Stores vector of indices and associated element values.
42 Supports sorting of indices.
43 
44 Does not support negative indices.
45 
46 Does NOT support testing for duplicates
47 
48 *** getElements is no longer supported
49 
50 Here is a sample usage:
51 @verbatim
52     const int ne = 4;
53     int inx[ne] =   {  1,   4,  0,   2 }
54     double el[ne] = { 10., 40., 1., 50. }
55 
56     // Create vector and set its valuex1
57     CoinIndexedVector r(ne,inx,el);
58 
59     // access as a full storage vector
60     assert( r[ 0]==1. );
61     assert( r[ 1]==10.);
62     assert( r[ 2]==50.);
63     assert( r[ 3]==0. );
64     assert( r[ 4]==40.);
65 
66     // sort Elements in increasing order
67     r.sortIncrElement();
68 
69     // access each index and element
70     assert( r.getIndices ()[0]== 0  );
71     assert( r.getIndices ()[1]== 1  );
72     assert( r.getIndices ()[2]== 4  );
73     assert( r.getIndices ()[3]== 2  );
74 
75     // access as a full storage vector
76     assert( r[ 0]==1. );
77     assert( r[ 1]==10.);
78     assert( r[ 2]==50.);
79     assert( r[ 3]==0. );
80     assert( r[ 4]==40.);
81 
82     // Tests for equality and equivalence
83     CoinIndexedVector r1;
84     r1=r;
85     assert( r==r1 );
86     assert( r.equivalent(r1) );
87     r.sortIncrElement();
88     assert( r!=r1 );
89     assert( r.equivalent(r1) );
90 
91     // Add indexed vectors.
92     // Similarly for subtraction, multiplication,
93     // and division.
94     CoinIndexedVector add = r + r1;
95     assert( add[0] ==  1.+ 1. );
96     assert( add[1] == 10.+10. );
97     assert( add[2] == 50.+50. );
98     assert( add[3] ==  0.+ 0. );
99     assert( add[4] == 40.+40. );
100 
101     assert( r.sum() == 10.+40.+1.+50. );
102 @endverbatim
103 */
104 class CoinIndexedVector {
105   friend void CoinIndexedVectorUnitTest();
106 
107 public:
108   /**@name Get methods. */
109   //@{
110   /// Get the size
getNumElements() const111   inline int getNumElements() const { return nElements_; }
112   /// Get indices of elements
getIndices() const113   inline const int *getIndices() const { return indices_; }
114   /// Get element values
115   // ** No longer supported virtual const double * getElements() const ;
116   /// Get indices of elements
getIndices()117   inline int *getIndices() { return indices_; }
118   /** Get the vector as a dense vector. This is normal storage method.
119        The user should not not delete [] this.
120    */
denseVector() const121   inline double *denseVector() const { return elements_; }
122   /// For very temporary use when user needs to borrow a dense vector
setDenseVector(double * array)123   inline void setDenseVector(double *array)
124   {
125     elements_ = array;
126   }
127   /// For very temporary use when user needs to borrow an index vector
setIndexVector(int * array)128   inline void setIndexVector(int *array)
129   {
130     indices_ = array;
131   }
132   /** Access the i'th element of the full storage vector.
133    */
134   double &operator[](int i) const;
135 
136   //@}
137 
138   //-------------------------------------------------------------------
139   // Set indices and elements
140   //-------------------------------------------------------------------
141   /**@name Set methods */
142   //@{
143   /// Set the size
setNumElements(int value)144   inline void setNumElements(int value)
145   {
146     nElements_ = value;
147     if (!nElements_)
148       packedMode_ = false;
149   }
150   /// Reset the vector (as if were just created an empty vector).  This leaves arrays!
151   void clear();
152   /// Reset the vector (as if were just created an empty vector)
153   void empty();
154   /// Clear even if in a bad way
155   void reallyClear();
156   /** Assignment operator. */
157   CoinIndexedVector &operator=(const CoinIndexedVector &);
158 #ifndef CLP_NO_VECTOR
159   /** Assignment operator from a CoinPackedVectorBase. <br>
160    <strong>NOTE</strong>: This assumes no duplicates */
161   CoinIndexedVector &operator=(const CoinPackedVectorBase &rhs);
162 #endif
163   /** Copy the contents of one vector into another.  If multiplier is 1
164        It is the equivalent of = but if vectors are same size does
165        not re-allocate memory just clears and copies */
166   void copy(const CoinIndexedVector &rhs, double multiplier = 1.0);
167 
168   /** Borrow ownership of the arguments to this vector.
169        Size is the length of the unpacked elements vector. */
170   void borrowVector(int size, int numberIndices, int *inds, double *elems);
171 
172   /** Return ownership of the arguments to this vector.
173        State after is empty .
174    */
175   void returnVector();
176 
177   /** Set vector numberIndices, indices, and elements.
178        NumberIndices is the length of both the indices and elements vectors.
179        The indices and elements vectors are copied into this class instance's
180        member data. Assumed to have no duplicates */
181   void setVector(int numberIndices, const int *inds, const double *elems);
182 
183   /** Set vector size, indices, and elements.
184        Size is the length of the unpacked elements vector.
185        The indices and elements vectors are copied into this class instance's
186        member data. We do not check for duplicate indices */
187   void setVector(int size, int numberIndices, const int *inds, const double *elems);
188 
189   /** Elements set to have the same scalar value */
190   void setConstant(int size, const int *inds, double elems);
191 
192   /** Indices are not specified and are taken to be 0,1,...,size-1 */
193   void setFull(int size, const double *elems);
194 
195   /** Set an existing element in the indexed vector
196        The first argument is the "index" into the elements() array
197    */
198   void setElement(int index, double element);
199 
200   /// Insert an element into the vector
201   void insert(int index, double element);
202   /// Insert a nonzero element into the vector
quickInsert(int index,double element)203   inline void quickInsert(int index, double element)
204   {
205     assert(!elements_[index]);
206     indices_[nElements_++] = index;
207     assert(nElements_ <= capacity_);
208     elements_[index] = element;
209   }
210   /** Insert or if exists add an element into the vector
211        Any resulting zero elements will be made tiny */
212   void add(int index, double element);
213   /** Insert or if exists add an element into the vector
214        Any resulting zero elements will be made tiny.
215        This version does no checking */
quickAdd(int index,double element)216   inline void quickAdd(int index, double element)
217   {
218     if (elements_[index]) {
219       element += elements_[index];
220       if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) {
221         elements_[index] = element;
222       } else {
223         elements_[index] = 1.0e-100;
224       }
225     } else if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) {
226       indices_[nElements_++] = index;
227       assert(nElements_ <= capacity_);
228       elements_[index] = element;
229     }
230   }
231   /** Insert or if exists add an element into the vector
232        Any resulting zero elements will be made tiny.
233        This knows element is nonzero
234        This version does no checking */
quickAddNonZero(int index,double element)235   inline void quickAddNonZero(int index, double element)
236   {
237     assert(element);
238     if (elements_[index]) {
239       element += elements_[index];
240       if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) {
241         elements_[index] = element;
242       } else {
243         elements_[index] = COIN_DBL_MIN;
244       }
245     } else {
246       indices_[nElements_++] = index;
247       assert(nElements_ <= capacity_);
248       elements_[index] = element;
249     }
250   }
251   /** Makes nonzero tiny.
252        This version does no checking */
zero(int index)253   inline void zero(int index)
254   {
255     if (elements_[index])
256       elements_[index] = COIN_DBL_MIN;
257   }
258   /** set all small values to zero and return number remaining
259       - < tolerance => 0.0 */
260   int clean(double tolerance);
261   /// Same but packs down
262   int cleanAndPack(double tolerance);
263   /// Same but packs down and is safe (i.e. if order is odd)
264   int cleanAndPackSafe(double tolerance);
265   /// Mark as packed
setPacked()266   inline void setPacked()
267   {
268     packedMode_ = true;
269   }
270 #ifndef NDEBUG
271   /// For debug check vector is clear i.e. no elements
272   void checkClear();
273   /// For debug check vector is clean i.e. elements match indices
274   void checkClean();
275 #else
checkClear()276   inline void checkClear() {};
checkClean()277   inline void checkClean() {};
278 #endif
279   /// Scan dense region and set up indices (returns number found)
280   int scan();
281   /** Scan dense region from start to < end and set up indices
282        returns number found
283    */
284   int scan(int start, int end);
285   /** Scan dense region and set up indices (returns number found).
286       Only ones >= tolerance */
287   int scan(double tolerance);
288   /** Scan dense region from start to < end and set up indices
289        returns number found.  Only >= tolerance
290    */
291   int scan(int start, int end, double tolerance);
292   /// These are same but pack down
293   int scanAndPack();
294   int scanAndPack(int start, int end);
295   int scanAndPack(double tolerance);
296   int scanAndPack(int start, int end, double tolerance);
297   /// Create packed array
298   void createPacked(int number, const int *indices,
299     const double *elements);
300   /// Create unpacked array
301   void createUnpacked(int number, const int *indices,
302     const double *elements);
303   /// Create unpacked singleton
304   void createOneUnpackedElement(int index, double element);
305   /// This is mainly for testing - goes from packed to indexed
306   void expand();
307 #ifndef CLP_NO_VECTOR
308   /// Append a CoinPackedVector to the end
309   void append(const CoinPackedVectorBase &caboose);
310 #endif
311   /// Append a CoinIndexedVector to the end (with extra space)
312   void append(const CoinIndexedVector &caboose);
313   /// Append a CoinIndexedVector to the end and modify indices
314   void append(CoinIndexedVector &other, int adjustIndex, bool zapElements = false);
315 
316   /// Swap values in positions i and j of indices and elements
317   void swap(int i, int j);
318 
319   /// Throw away all entries in rows >= newSize
320   void truncate(int newSize);
321   ///  Print out
322   void print() const;
323   //@}
324   /**@name Arithmetic operators. */
325   //@{
326   /// add <code>value</code> to every entry
327   void operator+=(double value);
328   /// subtract <code>value</code> from every entry
329   void operator-=(double value);
330   /// multiply every entry by <code>value</code>
331   void operator*=(double value);
332   /// divide every entry by <code>value</code> (** 0 vanishes)
333   void operator/=(double value);
334   //@}
335 
336   /**@name Comparison operators on two indexed vectors */
337   //@{
338 #ifndef CLP_NO_VECTOR
339   /** Equal. Returns true if vectors have same length and corresponding
340        element of each vector is equal. */
341   bool operator==(const CoinPackedVectorBase &rhs) const;
342   /// Not equal
343   bool operator!=(const CoinPackedVectorBase &rhs) const;
344 #endif
345   /** Equal. Returns true if vectors have same length and corresponding
346        element of each vector is equal. */
347   bool operator==(const CoinIndexedVector &rhs) const;
348   /// Not equal
349   bool operator!=(const CoinIndexedVector &rhs) const;
350   /// Equal with a tolerance (returns -1 or position of inequality).
351   int isApproximatelyEqual(const CoinIndexedVector &rhs, double tolerance = 1.0e-8) const;
352   //@}
353 
354   /**@name Index methods */
355   //@{
356   /// Get value of maximum index
357   int getMaxIndex() const;
358   /// Get value of minimum index
359   int getMinIndex() const;
360   //@}
361 
362   /**@name Sorting */
363   //@{
364   /** Sort the indexed storage vector (increasing indices). */
sort()365   void sort()
366   {
367     std::sort(indices_, indices_ + nElements_);
368   }
369 
sortIncrIndex()370   void sortIncrIndex()
371   {
372     std::sort(indices_, indices_ + nElements_);
373   }
374 
375   void sortDecrIndex();
376 
377   void sortIncrElement();
378 
379   void sortDecrElement();
380   void sortPacked();
381 
382   //@}
383 
384   //#############################################################################
385 
386   /**@name Arithmetic operators on packed vectors.
387 
388    <strong>NOTE</strong>: These methods operate on those positions where at
389    least one of the arguments has a value listed. At those positions the
390    appropriate operation is executed, Otherwise the result of the operation is
391    considered 0.<br>
392    <strong>NOTE 2</strong>: Because these methods return an object (they can't
393    return a reference, though they could return a pointer...) they are
394    <em>very</em> inefficient...
395  */
396   //@{
397   /// Return the sum of two indexed vectors
398   CoinIndexedVector operator+(
399     const CoinIndexedVector &op2);
400 
401   /// Return the difference of two indexed vectors
402   CoinIndexedVector operator-(
403     const CoinIndexedVector &op2);
404 
405   /// Return the element-wise product of two indexed vectors
406   CoinIndexedVector operator*(
407     const CoinIndexedVector &op2);
408 
409   /// Return the element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes)
410   CoinIndexedVector operator/(
411     const CoinIndexedVector &op2);
412   /// The sum of two indexed vectors
413   void operator+=(const CoinIndexedVector &op2);
414 
415   /// The difference of two indexed vectors
416   void operator-=(const CoinIndexedVector &op2);
417 
418   /// The element-wise product of two indexed vectors
419   void operator*=(const CoinIndexedVector &op2);
420 
421   /// The element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes)
422   void operator/=(const CoinIndexedVector &op2);
423   //@}
424 
425   /**@name Memory usage */
426   //@{
427   /** Reserve space.
428        If one knows the eventual size of the indexed vector,
429        then it may be more efficient to reserve the space.
430    */
431   void reserve(int n);
432   /** capacity returns the size which could be accomodated without
433        having to reallocate storage.
434    */
capacity() const435   inline int capacity() const { return capacity_; }
setCapacity(int value)436   inline void setCapacity(int value)
437   {
438     capacity_ = value;
439   }
440   /// Sets packed mode
setPackedMode(bool yesNo)441   inline void setPackedMode(bool yesNo)
442   {
443     packedMode_ = yesNo;
444   }
445   /// Gets packed mode
packedMode() const446   inline bool packedMode() const
447   {
448     return packedMode_;
449   }
450   //@}
451 
452   /**@name Constructors and destructors */
453   //@{
454   /** Default constructor */
455   CoinIndexedVector();
456   /** Alternate Constructors - set elements to vector of doubles */
457   CoinIndexedVector(int size, const int *inds, const double *elems);
458   /** Alternate Constructors - set elements to same scalar value */
459   CoinIndexedVector(int size, const int *inds, double element);
460   /** Alternate Constructors - construct full storage with indices 0 through
461        size-1. */
462   CoinIndexedVector(int size, const double *elements);
463   /** Alternate Constructors - just size */
464   CoinIndexedVector(int size);
465   /** Copy constructor. */
466   CoinIndexedVector(const CoinIndexedVector &);
467   /** Copy constructor.2 */
468   CoinIndexedVector(const CoinIndexedVector *);
469 #ifndef CLP_NO_VECTOR
470   /** Copy constructor <em>from a PackedVectorBase</em>. */
471   CoinIndexedVector(const CoinPackedVectorBase &rhs);
472 #endif
473   /** Destructor */
474   ~CoinIndexedVector();
475   //@}
476 
477 private:
478   /**@name Private methods */
479   //@{
480   /// Copy internal data
481   void gutsOfSetVector(int size,
482     const int *inds, const double *elems);
483   void gutsOfSetVector(int size, int numberIndices,
484     const int *inds, const double *elems);
485   void gutsOfSetPackedVector(int size, int numberIndices,
486     const int *inds, const double *elems);
487   ///
488   void gutsOfSetConstant(int size,
489     const int *inds, double value);
490   //@}
491 
492 protected:
493   /**@name Private member data */
494   //@{
495   /// Vector indices
496   int *indices_;
497   ///Vector elements
498   double *elements_;
499   /// Size of indices and packed elements vectors
500   int nElements_;
501   /// Amount of memory allocated for indices_, and elements_.
502   int capacity_;
503   ///  Offset to get where new allocated array
504   int offset_;
505   /// If true then is operating in packed mode
506   bool packedMode_;
507   //@}
508 };
509 
510 //#############################################################################
511 /** A function that tests the methods in the CoinIndexedVector class. The
512     only reason for it not to be a member method is that this way it doesn't
513     have to be compiled into the library. And that's a gain, because the
514     library should be compiled with optimization on, but this method should be
515     compiled with debugging. */
516 void CoinIndexedVectorUnitTest();
517 /** Pointer with length in bytes
518 
519     This has a pointer to an array and the number of bytes in array.
520     If number of bytes==-1 then
521     CoinConditionalNew deletes existing pointer and returns new pointer
522     of correct size (and number bytes still -1).
523     CoinConditionalDelete deletes existing pointer and NULLs it.
524     So behavior is as normal (apart from New deleting pointer which will have
525     no effect with good coding practices.
526     If number of bytes >=0 then
527     CoinConditionalNew just returns existing pointer if array big enough
528     otherwise deletes existing pointer, allocates array with spare 1%+64 bytes
529     and updates number of bytes
530     CoinConditionalDelete sets number of bytes = -size-2 and then array
531     returns NULL
532 */
533 class CoinArrayWithLength {
534 
535 public:
536   /**@name Get methods. */
537   //@{
538   /// Get the size
getSize() const539   inline CoinBigIndex getSize() const
540   {
541     return static_cast< CoinBigIndex >(size_);
542   }
543   /// Get the size
rawSize() const544   inline CoinBigIndex rawSize() const
545   {
546     return static_cast< CoinBigIndex >(size_);
547   }
548   /// See if persistence already on
switchedOn() const549   inline bool switchedOn() const
550   {
551     return size_ != -1;
552   }
553   /// Get the capacity (just read it)
capacity() const554   inline CoinBigIndex capacity() const
555   {
556     return (size_ > -2) ? static_cast< CoinBigIndex >(size_) : static_cast< CoinBigIndex >((-size_) - 2);
557   }
558   /// Set the capacity to >=0 if <=-2
setCapacity()559   inline void setCapacity()
560   {
561     if (size_ <= -2)
562       size_ = (-size_) - 2;
563   }
564   /// Get Array
array() const565   inline const char *array() const
566   {
567     return (size_ > -2) ? array_ : NULL;
568   }
569   //@}
570 
571   /**@name Set methods */
572   //@{
573   /// Set the size
setSize(int value)574   inline void setSize(int value)
575   {
576     size_ = value;
577   }
578 #if COIN_BIG_INDEX
579   /// Set the size
setSize(long long value)580   inline void setSize(long long value)
581   {
582     size_ = value;
583   }
584 #endif
585   /// Set the size to -1
switchOff()586   inline void switchOff()
587   {
588     size_ = -1;
589   }
590   /// Set the size to -2 and alignment
switchOn(int alignment=3)591   inline void switchOn(int alignment = 3)
592   {
593     size_ = -2;
594     alignment_ = alignment;
595   }
596   /// Does what is needed to set persistence
597   void setPersistence(int flag, int currentLength);
598   /// Zero out array
599   void clear();
600   /// Swaps memory between two members
601   void swap(CoinArrayWithLength &other);
602   /// Extend a persistent array keeping data (size in bytes)
603   void extend(int newSize);
604 #if COIN_BIG_INDEX
605   /// Extend a persistent array keeping data (size in bytes)
606   void extend(long long newSize);
607 #endif
608   //@}
609 
610   /**@name Condition methods */
611   //@{
612   /// Conditionally gets new array
613   char *conditionalNew(CoinBigIndex sizeWanted);
614   /// Conditionally deletes
615   void conditionalDelete();
616   //@}
617 
618   /**@name Constructors and destructors */
619   //@{
620   /** Default constructor - NULL*/
CoinArrayWithLength()621   inline CoinArrayWithLength()
622     : array_(NULL)
623     , size_(-1)
624     , offset_(0)
625     , alignment_(0)
626   {
627   }
628   /** Alternate Constructor - length in bytes - size_ -1 */
CoinArrayWithLength(CoinBigIndex size)629   inline CoinArrayWithLength(CoinBigIndex size)
630     : size_(-1)
631     , offset_(0)
632     , alignment_(0)
633   {
634     array_ = new char[size];
635   }
636   /** Alternate Constructor - length in bytes
637       mode -  0 size_ set to size
638       mode>0 size_ set to size and zeroed
639       if size<=0 just does alignment
640       If abs(mode) >2 then align on that as power of 2
641   */
642   CoinArrayWithLength(CoinBigIndex size, int mode);
643   /** Copy constructor. */
644   CoinArrayWithLength(const CoinArrayWithLength &rhs);
645   /** Copy constructor.2 */
646   CoinArrayWithLength(const CoinArrayWithLength *rhs);
647   /** Assignment operator. */
648   CoinArrayWithLength &operator=(const CoinArrayWithLength &rhs);
649   /** Assignment with length (if -1 use internal length) */
650   void copy(const CoinArrayWithLength &rhs, int numberBytes = -1);
651   /** Assignment with length - does not copy */
652   void allocate(const CoinArrayWithLength &rhs, CoinBigIndex numberBytes);
653   /** Destructor */
654   ~CoinArrayWithLength();
655   /// Get array with alignment
656   void getArray(CoinBigIndex size);
657   /// Really get rid of array with alignment
658   void reallyFreeArray();
659   /// Get enough space (if more needed then do at least needed)
660   void getCapacity(CoinBigIndex numberBytes, CoinBigIndex numberIfNeeded = -1);
661   //@}
662 
663 protected:
664   /**@name Private member data */
665   //@{
666   /// Array
667   char *array_;
668   /// Size of array in bytes
669   CoinBigIndex size_;
670   /// Offset of array
671   int offset_;
672   /// Alignment wanted (power of 2)
673   int alignment_;
674   //@}
675 };
676 /// double * version
677 
678 class CoinDoubleArrayWithLength : public CoinArrayWithLength {
679 
680 public:
681   /**@name Get methods. */
682   //@{
683   /// Get the size
getSize() const684   inline CoinBigIndex getSize() const
685   {
686     return size_ / CoinSizeofAsInt(double);
687   }
688   /// Get Array
array() const689   inline double *array() const
690   {
691     return reinterpret_cast< double * >((size_ > -2) ? array_ : NULL);
692   }
693   //@}
694 
695   /**@name Set methods */
696   //@{
697   /// Set the size
setSize(int value)698   inline void setSize(int value)
699   {
700     size_ = value * CoinSizeofAsInt(double);
701   }
702   //@}
703 
704   /**@name Condition methods */
705   //@{
706   /// Conditionally gets new array
conditionalNew(CoinBigIndex sizeWanted)707   inline double *conditionalNew(CoinBigIndex sizeWanted)
708   {
709     return reinterpret_cast< double * >(CoinArrayWithLength::conditionalNew(sizeWanted >= 0 ? static_cast< long long >((sizeWanted)*CoinSizeofAsInt(double)) : -1));
710   }
711   //@}
712 
713   /**@name Constructors and destructors */
714   //@{
715   /** Default constructor - NULL*/
CoinDoubleArrayWithLength()716   inline CoinDoubleArrayWithLength()
717   {
718     array_ = NULL;
719     size_ = -1;
720   }
721   /** Alternate Constructor - length in bytes - size_ -1 */
CoinDoubleArrayWithLength(int size)722   inline CoinDoubleArrayWithLength(int size)
723   {
724     array_ = new char[size * CoinSizeofAsInt(double)];
725     size_ = -1;
726   }
727   /** Alternate Constructor - length in bytes
728       mode -  0 size_ set to size
729       1 size_ set to size and zeroed
730   */
CoinDoubleArrayWithLength(int size,int mode)731   inline CoinDoubleArrayWithLength(int size, int mode)
732     : CoinArrayWithLength(size * CoinSizeofAsInt(double), mode)
733   {
734   }
735   /** Copy constructor. */
CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength & rhs)736   inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength &rhs)
737     : CoinArrayWithLength(rhs)
738   {
739   }
740   /** Copy constructor.2 */
CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength * rhs)741   inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength *rhs)
742     : CoinArrayWithLength(rhs)
743   {
744   }
745   /** Assignment operator. */
operator =(const CoinDoubleArrayWithLength & rhs)746   inline CoinDoubleArrayWithLength &operator=(const CoinDoubleArrayWithLength &rhs)
747   {
748     CoinArrayWithLength::operator=(rhs);
749     return *this;
750   }
751   //@}
752 };
753 /// CoinFactorizationDouble * version
754 
755 class CoinFactorizationDoubleArrayWithLength : public CoinArrayWithLength {
756 
757 public:
758   /**@name Get methods. */
759   //@{
760   /// Get the size
getSize() const761   inline CoinBigIndex getSize() const
762   {
763     return size_ / CoinSizeofAsInt(CoinFactorizationDouble);
764   }
765   /// Get Array
array() const766   inline CoinFactorizationDouble *array() const
767   {
768     return reinterpret_cast< CoinFactorizationDouble * >((size_ > -2) ? array_ : NULL);
769   }
770   //@}
771 
772   /**@name Set methods */
773   //@{
774   /// Set the size
setSize(int value)775   inline void setSize(int value)
776   {
777     size_ = value * CoinSizeofAsInt(CoinFactorizationDouble);
778   }
779   //@}
780 
781   /**@name Condition methods */
782   //@{
783   /// Conditionally gets new array
conditionalNew(CoinBigIndex sizeWanted)784   inline CoinFactorizationDouble *conditionalNew(CoinBigIndex sizeWanted)
785   {
786     return reinterpret_cast< CoinFactorizationDouble * >(CoinArrayWithLength::conditionalNew(sizeWanted >= 0 ? static_cast< long long >((sizeWanted)*CoinSizeofAsInt(CoinFactorizationDouble)) : -1));
787   }
788   //@}
789 
790   /**@name Constructors and destructors */
791   //@{
792   /** Default constructor - NULL*/
CoinFactorizationDoubleArrayWithLength()793   inline CoinFactorizationDoubleArrayWithLength()
794   {
795     array_ = NULL;
796     size_ = -1;
797   }
798   /** Alternate Constructor - length in bytes - size_ -1 */
CoinFactorizationDoubleArrayWithLength(int size)799   inline CoinFactorizationDoubleArrayWithLength(int size)
800   {
801     array_ = new char[size * CoinSizeofAsInt(CoinFactorizationDouble)];
802     size_ = -1;
803   }
804   /** Alternate Constructor - length in bytes
805       mode -  0 size_ set to size
806       1 size_ set to size and zeroed
807   */
CoinFactorizationDoubleArrayWithLength(int size,int mode)808   inline CoinFactorizationDoubleArrayWithLength(int size, int mode)
809     : CoinArrayWithLength(size * CoinSizeofAsInt(CoinFactorizationDouble), mode)
810   {
811   }
812   /** Copy constructor. */
CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength & rhs)813   inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength &rhs)
814     : CoinArrayWithLength(rhs)
815   {
816   }
817   /** Copy constructor.2 */
CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength * rhs)818   inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength *rhs)
819     : CoinArrayWithLength(rhs)
820   {
821   }
822   /** Assignment operator. */
operator =(const CoinFactorizationDoubleArrayWithLength & rhs)823   inline CoinFactorizationDoubleArrayWithLength &operator=(const CoinFactorizationDoubleArrayWithLength &rhs)
824   {
825     CoinArrayWithLength::operator=(rhs);
826     return *this;
827   }
828   //@}
829 };
830 /// CoinFactorizationLongDouble * version
831 
832 class CoinFactorizationLongDoubleArrayWithLength : public CoinArrayWithLength {
833 
834 public:
835   /**@name Get methods. */
836   //@{
837   /// Get the size
getSize() const838   inline CoinBigIndex getSize() const
839   {
840     return size_ / CoinSizeofAsInt(long double);
841   }
842   /// Get Array
array() const843   inline long double *array() const
844   {
845     return reinterpret_cast< long double * >((size_ > -2) ? array_ : NULL);
846   }
847   //@}
848 
849   /**@name Set methods */
850   //@{
851   /// Set the size
setSize(int value)852   inline void setSize(int value)
853   {
854     size_ = value * CoinSizeofAsInt(long double);
855   }
856   //@}
857 
858   /**@name Condition methods */
859   //@{
860   /// Conditionally gets new array
conditionalNew(CoinBigIndex sizeWanted)861   inline long double *conditionalNew(CoinBigIndex sizeWanted)
862   {
863     return reinterpret_cast< long double * >(CoinArrayWithLength::conditionalNew(sizeWanted >= 0 ? static_cast< long long >((sizeWanted)*CoinSizeofAsInt(long double)) : -1));
864   }
865   //@}
866 
867   /**@name Constructors and destructors */
868   //@{
869   /** Default constructor - NULL*/
CoinFactorizationLongDoubleArrayWithLength()870   inline CoinFactorizationLongDoubleArrayWithLength()
871   {
872     array_ = NULL;
873     size_ = -1;
874   }
875   /** Alternate Constructor - length in bytes - size_ -1 */
CoinFactorizationLongDoubleArrayWithLength(int size)876   inline CoinFactorizationLongDoubleArrayWithLength(int size)
877   {
878     array_ = new char[size * CoinSizeofAsInt(long double)];
879     size_ = -1;
880   }
881   /** Alternate Constructor - length in bytes
882       mode -  0 size_ set to size
883       1 size_ set to size and zeroed
884   */
CoinFactorizationLongDoubleArrayWithLength(int size,int mode)885   inline CoinFactorizationLongDoubleArrayWithLength(int size, int mode)
886     : CoinArrayWithLength(size * CoinSizeofAsInt(long double), mode)
887   {
888   }
889   /** Copy constructor. */
CoinFactorizationLongDoubleArrayWithLength(const CoinFactorizationLongDoubleArrayWithLength & rhs)890   inline CoinFactorizationLongDoubleArrayWithLength(const CoinFactorizationLongDoubleArrayWithLength &rhs)
891     : CoinArrayWithLength(rhs)
892   {
893   }
894   /** Copy constructor.2 */
CoinFactorizationLongDoubleArrayWithLength(const CoinFactorizationLongDoubleArrayWithLength * rhs)895   inline CoinFactorizationLongDoubleArrayWithLength(const CoinFactorizationLongDoubleArrayWithLength *rhs)
896     : CoinArrayWithLength(rhs)
897   {
898   }
899   /** Assignment operator. */
operator =(const CoinFactorizationLongDoubleArrayWithLength & rhs)900   inline CoinFactorizationLongDoubleArrayWithLength &operator=(const CoinFactorizationLongDoubleArrayWithLength &rhs)
901   {
902     CoinArrayWithLength::operator=(rhs);
903     return *this;
904   }
905   //@}
906 };
907 /// int * version
908 
909 class CoinIntArrayWithLength : public CoinArrayWithLength {
910 
911 public:
912   /**@name Get methods. */
913   //@{
914   /// Get the size
getSize() const915   inline CoinBigIndex getSize() const
916   {
917     return size_ / CoinSizeofAsInt(int);
918   }
919   /// Get Array
array() const920   inline int *array() const
921   {
922     return reinterpret_cast< int * >((size_ > -2) ? array_ : NULL);
923   }
924   //@}
925 
926   /**@name Set methods */
927   //@{
928   /// Set the size
setSize(int value)929   inline void setSize(int value)
930   {
931     size_ = value * CoinSizeofAsInt(int);
932   }
933   //@}
934 
935   /**@name Condition methods */
936   //@{
937   /// Conditionally gets new array
conditionalNew(CoinBigIndex sizeWanted)938   inline int *conditionalNew(CoinBigIndex sizeWanted)
939   {
940     return reinterpret_cast< int * >(CoinArrayWithLength::conditionalNew(sizeWanted >= 0 ? static_cast< long long >((sizeWanted)*CoinSizeofAsInt(int)) : -1));
941   }
942   //@}
943 
944   /**@name Constructors and destructors */
945   //@{
946   /** Default constructor - NULL*/
CoinIntArrayWithLength()947   inline CoinIntArrayWithLength()
948   {
949     array_ = NULL;
950     size_ = -1;
951   }
952   /** Alternate Constructor - length in bytes - size_ -1 */
CoinIntArrayWithLength(int size)953   inline CoinIntArrayWithLength(int size)
954   {
955     array_ = new char[size * CoinSizeofAsInt(int)];
956     size_ = -1;
957   }
958   /** Alternate Constructor - length in bytes
959       mode -  0 size_ set to size
960       1 size_ set to size and zeroed
961   */
CoinIntArrayWithLength(int size,int mode)962   inline CoinIntArrayWithLength(int size, int mode)
963     : CoinArrayWithLength(size * CoinSizeofAsInt(int), mode)
964   {
965   }
966   /** Copy constructor. */
CoinIntArrayWithLength(const CoinIntArrayWithLength & rhs)967   inline CoinIntArrayWithLength(const CoinIntArrayWithLength &rhs)
968     : CoinArrayWithLength(rhs)
969   {
970   }
971   /** Copy constructor.2 */
CoinIntArrayWithLength(const CoinIntArrayWithLength * rhs)972   inline CoinIntArrayWithLength(const CoinIntArrayWithLength *rhs)
973     : CoinArrayWithLength(rhs)
974   {
975   }
976   /** Assignment operator. */
operator =(const CoinIntArrayWithLength & rhs)977   inline CoinIntArrayWithLength &operator=(const CoinIntArrayWithLength &rhs)
978   {
979     CoinArrayWithLength::operator=(rhs);
980     return *this;
981   }
982   //@}
983 };
984 /// CoinBigIndex * version
985 
986 class CoinBigIndexArrayWithLength : public CoinArrayWithLength {
987 
988 public:
989   /**@name Get methods. */
990   //@{
991   /// Get the size
getSize() const992   inline CoinBigIndex getSize() const
993   {
994     return size_ / CoinSizeofAsInt(CoinBigIndex);
995   }
996   /// Get Array
array() const997   inline CoinBigIndex *array() const
998   {
999     return reinterpret_cast< CoinBigIndex * >((size_ > -2) ? array_ : NULL);
1000   }
1001   //@}
1002 
1003   /**@name Set methods */
1004   //@{
1005   /// Set the size
setSize(CoinBigIndex value)1006   inline void setSize(CoinBigIndex value)
1007   {
1008     size_ = value * CoinSizeofAsInt(CoinBigIndex);
1009   }
1010   //@}
1011 
1012   /**@name Condition methods */
1013   //@{
1014   /// Conditionally gets new array
conditionalNew(CoinBigIndex sizeWanted)1015   inline CoinBigIndex *conditionalNew(CoinBigIndex sizeWanted)
1016   {
1017     return reinterpret_cast< CoinBigIndex * >(CoinArrayWithLength::conditionalNew(sizeWanted >= 0 ? static_cast< long long >((sizeWanted)*CoinSizeofAsInt(CoinBigIndex)) : -1));
1018   }
1019   //@}
1020 
1021   /**@name Constructors and destructors */
1022   //@{
1023   /** Default constructor - NULL*/
CoinBigIndexArrayWithLength()1024   inline CoinBigIndexArrayWithLength()
1025   {
1026     array_ = NULL;
1027     size_ = -1;
1028   }
1029   /** Alternate Constructor - length in bytes - size_ -1 */
CoinBigIndexArrayWithLength(CoinBigIndex size)1030   inline CoinBigIndexArrayWithLength(CoinBigIndex size)
1031   {
1032     array_ = new char[size * CoinSizeofAsInt(CoinBigIndex)];
1033     size_ = -1;
1034   }
1035   /** Alternate Constructor - length in bytes
1036       mode -  0 size_ set to size
1037       1 size_ set to size and zeroed
1038   */
CoinBigIndexArrayWithLength(CoinBigIndex size,int mode)1039   inline CoinBigIndexArrayWithLength(CoinBigIndex size, int mode)
1040     : CoinArrayWithLength(size * CoinSizeofAsInt(CoinBigIndex), mode)
1041   {
1042   }
1043   /** Copy constructor. */
CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength & rhs)1044   inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength &rhs)
1045     : CoinArrayWithLength(rhs)
1046   {
1047   }
1048   /** Copy constructor.2 */
CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength * rhs)1049   inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength *rhs)
1050     : CoinArrayWithLength(rhs)
1051   {
1052   }
1053   /** Assignment operator. */
operator =(const CoinBigIndexArrayWithLength & rhs)1054   inline CoinBigIndexArrayWithLength &operator=(const CoinBigIndexArrayWithLength &rhs)
1055   {
1056     CoinArrayWithLength::operator=(rhs);
1057     return *this;
1058   }
1059   //@}
1060 };
1061 /// unsigned int * version
1062 
1063 class CoinUnsignedIntArrayWithLength : public CoinArrayWithLength {
1064 
1065 public:
1066   /**@name Get methods. */
1067   //@{
1068   /// Get the size
getSize() const1069   inline CoinBigIndex getSize() const
1070   {
1071     return size_ / CoinSizeofAsInt(unsigned int);
1072   }
1073   /// Get Array
array() const1074   inline unsigned int *array() const
1075   {
1076     return reinterpret_cast< unsigned int * >((size_ > -2) ? array_ : NULL);
1077   }
1078   //@}
1079 
1080   /**@name Set methods */
1081   //@{
1082   /// Set the size
setSize(int value)1083   inline void setSize(int value)
1084   {
1085     size_ = value * CoinSizeofAsInt(unsigned int);
1086   }
1087   //@}
1088 
1089   /**@name Condition methods */
1090   //@{
1091   /// Conditionally gets new array
conditionalNew(CoinBigIndex sizeWanted)1092   inline unsigned int *conditionalNew(CoinBigIndex sizeWanted)
1093   {
1094     return reinterpret_cast< unsigned int * >(CoinArrayWithLength::conditionalNew(sizeWanted >= 0 ? static_cast< long long >((sizeWanted)*CoinSizeofAsInt(unsigned int)) : -1));
1095   }
1096   //@}
1097 
1098   /**@name Constructors and destructors */
1099   //@{
1100   /** Default constructor - NULL*/
CoinUnsignedIntArrayWithLength()1101   inline CoinUnsignedIntArrayWithLength()
1102   {
1103     array_ = NULL;
1104     size_ = -1;
1105   }
1106   /** Alternate Constructor - length in bytes - size_ -1 */
CoinUnsignedIntArrayWithLength(int size)1107   inline CoinUnsignedIntArrayWithLength(int size)
1108   {
1109     array_ = new char[size * CoinSizeofAsInt(unsigned int)];
1110     size_ = -1;
1111   }
1112   /** Alternate Constructor - length in bytes
1113       mode -  0 size_ set to size
1114       1 size_ set to size and zeroed
1115   */
CoinUnsignedIntArrayWithLength(int size,int mode)1116   inline CoinUnsignedIntArrayWithLength(int size, int mode)
1117     : CoinArrayWithLength(size * CoinSizeofAsInt(unsigned int), mode)
1118   {
1119   }
1120   /** Copy constructor. */
CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength & rhs)1121   inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength &rhs)
1122     : CoinArrayWithLength(rhs)
1123   {
1124   }
1125   /** Copy constructor.2 */
CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength * rhs)1126   inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength *rhs)
1127     : CoinArrayWithLength(rhs)
1128   {
1129   }
1130   /** Assignment operator. */
operator =(const CoinUnsignedIntArrayWithLength & rhs)1131   inline CoinUnsignedIntArrayWithLength &operator=(const CoinUnsignedIntArrayWithLength &rhs)
1132   {
1133     CoinArrayWithLength::operator=(rhs);
1134     return *this;
1135   }
1136   //@}
1137 };
1138 /// void * version
1139 
1140 class CoinVoidStarArrayWithLength : public CoinArrayWithLength {
1141 
1142 public:
1143   /**@name Get methods. */
1144   //@{
1145   /// Get the size
getSize() const1146   inline CoinBigIndex getSize() const
1147   {
1148     return size_ / CoinSizeofAsInt(void *);
1149   }
1150   /// Get Array
array() const1151   inline void **array() const
1152   {
1153     return reinterpret_cast< void ** >((size_ > -2) ? array_ : NULL);
1154   }
1155   //@}
1156 
1157   /**@name Set methods */
1158   //@{
1159   /// Set the size
setSize(int value)1160   inline void setSize(int value)
1161   {
1162     size_ = value * CoinSizeofAsInt(void *);
1163   }
1164   //@}
1165 
1166   /**@name Condition methods */
1167   //@{
1168   /// Conditionally gets new array
conditionalNew(CoinBigIndex sizeWanted)1169   inline void **conditionalNew(CoinBigIndex sizeWanted)
1170   {
1171     return reinterpret_cast< void ** >(CoinArrayWithLength::conditionalNew(sizeWanted >= 0 ? static_cast< long long >((sizeWanted)*CoinSizeofAsInt(void *)) : -1));
1172   }
1173   //@}
1174 
1175   /**@name Constructors and destructors */
1176   //@{
1177   /** Default constructor - NULL*/
CoinVoidStarArrayWithLength()1178   inline CoinVoidStarArrayWithLength()
1179   {
1180     array_ = NULL;
1181     size_ = -1;
1182   }
1183   /** Alternate Constructor - length in bytes - size_ -1 */
CoinVoidStarArrayWithLength(int size)1184   inline CoinVoidStarArrayWithLength(int size)
1185   {
1186     array_ = new char[size * CoinSizeofAsInt(void *)];
1187     size_ = -1;
1188   }
1189   /** Alternate Constructor - length in bytes
1190       mode -  0 size_ set to size
1191       1 size_ set to size and zeroed
1192   */
CoinVoidStarArrayWithLength(int size,int mode)1193   inline CoinVoidStarArrayWithLength(int size, int mode)
1194     : CoinArrayWithLength(size * CoinSizeofAsInt(void *), mode)
1195   {
1196   }
1197   /** Copy constructor. */
CoinVoidStarArrayWithLength(const CoinVoidStarArrayWithLength & rhs)1198   inline CoinVoidStarArrayWithLength(const CoinVoidStarArrayWithLength &rhs)
1199     : CoinArrayWithLength(rhs)
1200   {
1201   }
1202   /** Copy constructor.2 */
CoinVoidStarArrayWithLength(const CoinVoidStarArrayWithLength * rhs)1203   inline CoinVoidStarArrayWithLength(const CoinVoidStarArrayWithLength *rhs)
1204     : CoinArrayWithLength(rhs)
1205   {
1206   }
1207   /** Assignment operator. */
operator =(const CoinVoidStarArrayWithLength & rhs)1208   inline CoinVoidStarArrayWithLength &operator=(const CoinVoidStarArrayWithLength &rhs)
1209   {
1210     CoinArrayWithLength::operator=(rhs);
1211     return *this;
1212   }
1213   //@}
1214 };
1215 /// arbitrary version
1216 
1217 class CoinArbitraryArrayWithLength : public CoinArrayWithLength {
1218 
1219 public:
1220   /**@name Get methods. */
1221   //@{
1222   /// Get the size
getSize() const1223   inline CoinBigIndex getSize() const
1224   {
1225     return size_ / lengthInBytes_;
1226   }
1227   /// Get Array
array() const1228   inline void **array() const
1229   {
1230     return reinterpret_cast< void ** >((size_ > -2) ? array_ : NULL);
1231   }
1232   //@}
1233 
1234   /**@name Set methods */
1235   //@{
1236   /// Set the size
setSize(int value)1237   inline void setSize(int value)
1238   {
1239     size_ = value * lengthInBytes_;
1240   }
1241   //@}
1242 
1243   /**@name Condition methods */
1244   //@{
1245   /// Conditionally gets new array
conditionalNew(CoinBigIndex length,CoinBigIndex sizeWanted)1246   inline char *conditionalNew(CoinBigIndex length, CoinBigIndex sizeWanted)
1247   {
1248     lengthInBytes_ = length;
1249     return reinterpret_cast< char * >(CoinArrayWithLength::conditionalNew(sizeWanted >= 0 ? static_cast< long long >((sizeWanted)*lengthInBytes_) : -1));
1250   }
1251   //@}
1252 
1253   /**@name Constructors and destructors */
1254   //@{
1255   /** Default constructor - NULL*/
CoinArbitraryArrayWithLength(int length=1)1256   inline CoinArbitraryArrayWithLength(int length = 1)
1257   {
1258     array_ = NULL;
1259     size_ = -1;
1260     lengthInBytes_ = length;
1261   }
1262   /** Alternate Constructor - length in bytes - size_ -1 */
CoinArbitraryArrayWithLength(int length,int size)1263   inline CoinArbitraryArrayWithLength(int length, int size)
1264   {
1265     array_ = new char[size * length];
1266     size_ = -1;
1267     lengthInBytes_ = length;
1268   }
1269   /** Alternate Constructor - length in bytes
1270       mode -  0 size_ set to size
1271       1 size_ set to size and zeroed
1272   */
CoinArbitraryArrayWithLength(int length,int size,int mode)1273   inline CoinArbitraryArrayWithLength(int length, int size, int mode)
1274     : CoinArrayWithLength(size * length, mode)
1275   {
1276     lengthInBytes_ = length;
1277   }
1278   /** Copy constructor. */
CoinArbitraryArrayWithLength(const CoinArbitraryArrayWithLength & rhs)1279   inline CoinArbitraryArrayWithLength(const CoinArbitraryArrayWithLength &rhs)
1280     : CoinArrayWithLength(rhs)
1281   {
1282   }
1283   /** Copy constructor.2 */
CoinArbitraryArrayWithLength(const CoinArbitraryArrayWithLength * rhs)1284   inline CoinArbitraryArrayWithLength(const CoinArbitraryArrayWithLength *rhs)
1285     : CoinArrayWithLength(rhs)
1286   {
1287   }
1288   /** Assignment operator. */
operator =(const CoinArbitraryArrayWithLength & rhs)1289   inline CoinArbitraryArrayWithLength &operator=(const CoinArbitraryArrayWithLength &rhs)
1290   {
1291     CoinArrayWithLength::operator=(rhs);
1292     return *this;
1293   }
1294   //@}
1295 
1296 protected:
1297   /**@name Private member data */
1298   //@{
1299   /// Length in bytes
1300   CoinBigIndex lengthInBytes_;
1301   //@}
1302 };
1303 class CoinPartitionedVector : public CoinIndexedVector {
1304 
1305 public:
1306 #ifndef COIN_PARTITIONS
1307 #define COIN_PARTITIONS 8
1308 #endif
1309   /**@name Get methods. */
1310   //@{
1311   /// Get the size of a partition
getNumElements(int partition) const1312   inline int getNumElements(int partition) const
1313   {
1314     assert(partition < COIN_PARTITIONS);
1315     return numberElementsPartition_[partition];
1316   }
1317   /// Get number of partitions
getNumPartitions() const1318   inline int getNumPartitions() const
1319   {
1320     return numberPartitions_;
1321   }
1322   /// Get the size
getNumElements() const1323   inline int getNumElements() const { return nElements_; }
1324   /// Get starts
startPartition(int partition) const1325   inline int startPartition(int partition) const
1326   {
1327     assert(partition <= COIN_PARTITIONS);
1328     return startPartition_[partition];
1329   }
1330   /// Get starts
startPartitions() const1331   inline const int *startPartitions() const
1332   {
1333     return startPartition_;
1334   }
1335   //@}
1336 
1337   //-------------------------------------------------------------------
1338   // Set indices and elements
1339   //-------------------------------------------------------------------
1340   /**@name Set methods */
1341   //@{
1342   /// Set the size of a partition
setNumElementsPartition(int partition,int value)1343   inline void setNumElementsPartition(int partition, int value)
1344   {
1345     assert(partition < COIN_PARTITIONS);
1346     if (numberPartitions_)
1347       numberElementsPartition_[partition] = value;
1348   }
1349   /// Set the size of a partition (just for a tiny while)
setTempNumElementsPartition(int partition,int value)1350   inline void setTempNumElementsPartition(int partition, int value)
1351   {
1352     assert(partition < COIN_PARTITIONS);
1353     numberElementsPartition_[partition] = value;
1354   }
1355   /// Add up number of elements in partitions
1356   void computeNumberElements();
1357   /// Add up number of elements in partitions and pack and get rid of partitions
1358   void compact();
1359   /** Reserve space.
1360    */
1361   void reserve(int n);
1362   /// Setup partitions (needs end as well)
1363   void setPartitions(int number, const int *starts);
1364   /// Reset the vector (as if were just created an empty vector). Gets rid of partitions
1365   void clearAndReset();
1366   /// Reset the vector (as if were just created an empty vector). Keeps partitions
1367   void clearAndKeep();
1368   /// Clear a partition.
1369   void clearPartition(int partition);
1370 #ifndef NDEBUG
1371   /// For debug check vector is clear i.e. no elements
1372   void checkClear();
1373   /// For debug check vector is clean i.e. elements match indices
1374   void checkClean();
1375 #else
checkClear()1376   inline void checkClear() {};
checkClean()1377   inline void checkClean() {};
1378 #endif
1379   /// Scan dense region and set up indices (returns number found)
1380   int scan(int partition, double tolerance = 0.0);
1381   /** Scan dense region from start to < end and set up indices
1382        returns number found
1383    */
1384   ///  Print out
1385   void print() const;
1386   //@}
1387 
1388   /**@name Sorting */
1389   //@{
1390   /** Sort the indexed storage vector (increasing indices). */
1391   void sort();
1392   //@}
1393 
1394   /**@name Constructors and destructors (not all wriiten) */
1395   //@{
1396   /** Default constructor */
1397   CoinPartitionedVector();
1398   /** Alternate Constructors - set elements to vector of doubles */
1399   CoinPartitionedVector(int size, const int *inds, const double *elems);
1400   /** Alternate Constructors - set elements to same scalar value */
1401   CoinPartitionedVector(int size, const int *inds, double element);
1402   /** Alternate Constructors - construct full storage with indices 0 through
1403        size-1. */
1404   CoinPartitionedVector(int size, const double *elements);
1405   /** Alternate Constructors - just size */
1406   CoinPartitionedVector(int size);
1407   /** Copy constructor. */
1408   CoinPartitionedVector(const CoinPartitionedVector &);
1409   /** Copy constructor.2 */
1410   CoinPartitionedVector(const CoinPartitionedVector *);
1411   /** Assignment operator. */
1412   CoinPartitionedVector &operator=(const CoinPartitionedVector &);
1413   /** Destructor */
1414   ~CoinPartitionedVector();
1415   //@}
1416 protected:
1417   /**@name Private member data */
1418   //@{
1419   /// Starts
1420   int startPartition_[COIN_PARTITIONS + 1];
1421   /// Size of indices in a partition
1422   int numberElementsPartition_[COIN_PARTITIONS];
1423   /// Number of partitions (0 means off)
1424   int numberPartitions_;
1425   //@}
1426 };
roundUpDouble(double * address)1427 inline double *roundUpDouble(double *address)
1428 {
1429   // align on 64 byte boundary
1430   CoinInt64 xx = reinterpret_cast< CoinInt64 >(address);
1431   int iBottom = static_cast< int >(xx & 63);
1432   if (iBottom)
1433     return address + ((64 - iBottom) >> 3);
1434   else
1435     return address;
1436 }
1437 #endif
1438