1/* $Id: CoinIndexedVector.hpp 1464 2011-08-08 16:20:42Z 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
33This stores values unpacked but apart from that is a bit like CoinPackedVector.
34It is designed to be lightweight in normal use.
35
36It now has a "packed" mode when it is even more like CoinPackedVector
37
38Indices array has capacity_ extra chars which are zeroed and can
39be used for any purpose - but must be re-zeroed
40
41Stores vector of indices and associated element values.
42Supports sorting of indices.
43
44Does not support negative indices.
45
46Does NOT support testing for duplicates
47
48*** getElements is no longer supported
49
50Here 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*/
104class CoinIndexedVector {
105 friend void CoinIndexedVectorUnitTest();
106
107public:
108 /**@name Get methods. */
109 //@{
110 /// Get the size
111 inline int getNumElements() const { return nElements_; }
112 /// Get indices of elements
113 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
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 */
121 inline double * denseVector() const { return elements_; }
122 /// For very temporary use when user needs to borrow a dense vector
123 inline void setDenseVector(double * array)
124 { elements_ = array;}
125 /// For very temporary use when user needs to borrow an index vector
126 inline void setIndexVector(int * array)
127 { indices_ = array;}
128 /** Access the i'th element of the full storage vector.
129 */
130 double & operator[](int i) const;
131
132 //@}
133
134 //-------------------------------------------------------------------
135 // Set indices and elements
136 //-------------------------------------------------------------------
137 /**@name Set methods */
138 //@{
139 /// Set the size
140 inline void setNumElements(int value) { nElements_ = value;
141 if (!nElements_) packedMode_=false;}
142 /// Reset the vector (as if were just created an empty vector). This leaves arrays!
143 void clear();
144 /// Reset the vector (as if were just created an empty vector)
145 void empty();
146 /** Assignment operator. */
147 CoinIndexedVector & operator=(const CoinIndexedVector &);
148#ifndef CLP_NO_VECTOR
149 /** Assignment operator from a CoinPackedVectorBase. <br>
150 <strong>NOTE</strong>: This assumes no duplicates */
151 CoinIndexedVector & operator=(const CoinPackedVectorBase & rhs);
152#endif
153 /** Copy the contents of one vector into another. If multiplier is 1
154 It is the equivalent of = but if vectors are same size does
155 not re-allocate memory just clears and copies */
156 void copy(const CoinIndexedVector & rhs, double multiplier=1.0);
157
158 /** Borrow ownership of the arguments to this vector.
159 Size is the length of the unpacked elements vector. */
160 void borrowVector(int size, int numberIndices, int* inds, double* elems);
161
162 /** Return ownership of the arguments to this vector.
163 State after is empty .
164 */
165 void returnVector();
166
167 /** Set vector numberIndices, indices, and elements.
168 NumberIndices is the length of both the indices and elements vectors.
169 The indices and elements vectors are copied into this class instance's
170 member data. Assumed to have no duplicates */
171 void setVector(int numberIndices, const int * inds, const double * elems);
172
173 /** Set vector size, indices, and elements.
174 Size is the length of the unpacked elements vector.
175 The indices and elements vectors are copied into this class instance's
176 member data. We do not check for duplicate indices */
177 void setVector(int size, int numberIndices, const int * inds, const double * elems);
178
179 /** Elements set to have the same scalar value */
180 void setConstant(int size, const int * inds, double elems);
181
182 /** Indices are not specified and are taken to be 0,1,...,size-1 */
183 void setFull(int size, const double * elems);
184
185 /** Set an existing element in the indexed vector
186 The first argument is the "index" into the elements() array
187 */
188 void setElement(int index, double element);
189
190 /// Insert an element into the vector
191 void insert(int index, double element);
192 /// Insert a nonzero element into the vector
193 inline void quickInsert(int index, double element)
194 {
195 assert (!elements_[index]);
196 indices_[nElements_++] = index;
197 assert (nElements_<=capacity_);
198 elements_[index] = element;
199 }
200 /** Insert or if exists add an element into the vector
201 Any resulting zero elements will be made tiny */
202 void add(int index, double element);
203 /** Insert or if exists add an element into the vector
204 Any resulting zero elements will be made tiny.
205 This version does no checking */
206 inline void quickAdd(int index, double element)
207 {
208 if (elements_[index]) {
209 element += elements_[index];
210 if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) {
211 elements_[index] = element;
212 } else {
213 elements_[index] = 1.0e-100;
214 }
215 } else if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) {
216 indices_[nElements_++] = index;
217 assert (nElements_<=capacity_);
218 elements_[index] = element;
219 }
220 }
221 /** Insert or if exists add an element into the vector
222 Any resulting zero elements will be made tiny.
223 This knows element is nonzero
224 This version does no checking */
225 inline void quickAddNonZero(int index, double element)
226 {
227 assert (element);
228 if (elements_[index]) {
229 element += elements_[index];
230 if (element) {
231 elements_[index] = element;
232 } else {
233 elements_[index] = COIN_DBL_MIN;
234 }
235 } else {
236 indices_[nElements_++] = index;
237 assert (nElements_<=capacity_);
238 elements_[index] = element;
239 }
240 }
241 /** Makes nonzero tiny.
242 This version does no checking */
243 inline void zero(int index)
244 {
245 if (elements_[index])
246 elements_[index] = COIN_DBL_MIN;
247 }
248 /** set all small values to zero and return number remaining
249 - < tolerance => 0.0 */
250 int clean(double tolerance);
251 /// Same but packs down
252 int cleanAndPack(double tolerance);
253 /// Same but packs down and is safe (i.e. if order is odd)
254 int cleanAndPackSafe(double tolerance);
255 /// Mark as packed
256 inline void setPacked()
257 { packedMode_ = true;}
258 /// For debug check vector is clear i.e. no elements
259 void checkClear();
260 /// For debug check vector is clean i.e. elements match indices
261 void checkClean();
262 /// Scan dense region and set up indices (returns number found)
263 int scan();
264 /** Scan dense region from start to < end and set up indices
265 returns number found
266 */
267 int scan(int start, int end);
268 /** Scan dense region and set up indices (returns number found).
269 Only ones >= tolerance */
270 int scan(double tolerance);
271 /** Scan dense region from start to < end and set up indices
272 returns number found. Only >= tolerance
273 */
274 int scan(int start, int end, double tolerance);
275 /// These are same but pack down
276 int scanAndPack();
277 int scanAndPack(int start, int end);
278 int scanAndPack(double tolerance);
279 int scanAndPack(int start, int end, double tolerance);
280 /// Create packed array
281 void createPacked(int number, const int * indices,
282 const double * elements);
283 /// This is mainly for testing - goes from packed to indexed
284 void expand();
285#ifndef CLP_NO_VECTOR
286 /// Append a CoinPackedVector to the end
287 void append(const CoinPackedVectorBase & caboose);
288#endif
289 /// Append a CoinIndexedVector to the end
290 void append(const CoinIndexedVector & caboose);
291
292 /// Swap values in positions i and j of indices and elements
293 void swap(int i, int j);
294
295 /// Throw away all entries in rows >= newSize
296 void truncate(int newSize);
297 /// Print out
298 void print() const;
299 //@}
300 /**@name Arithmetic operators. */
301 //@{
302 /// add <code>value</code> to every entry
303 void operator+=(double value);
304 /// subtract <code>value</code> from every entry
305 void operator-=(double value);
306 /// multiply every entry by <code>value</code>
307 void operator*=(double value);
308 /// divide every entry by <code>value</code> (** 0 vanishes)
309 void operator/=(double value);
310 //@}
311
312 /**@name Comparison operators on two indexed vectors */
313 //@{
314#ifndef CLP_NO_VECTOR
315 /** Equal. Returns true if vectors have same length and corresponding
316 element of each vector is equal. */
317 bool operator==(const CoinPackedVectorBase & rhs) const;
318 /// Not equal
319 bool operator!=(const CoinPackedVectorBase & rhs) const;
320#endif
321 /** Equal. Returns true if vectors have same length and corresponding
322 element of each vector is equal. */
323 bool operator==(const CoinIndexedVector & rhs) const;
324 /// Not equal
325 bool operator!=(const CoinIndexedVector & rhs) const;
326 //@}
327
328 /**@name Index methods */
329 //@{
330 /// Get value of maximum index
331 int getMaxIndex() const;
332 /// Get value of minimum index
333 int getMinIndex() const;
334 //@}
335
336
337 /**@name Sorting */
338 //@{
339 /** Sort the indexed storage vector (increasing indices). */
340 void sort()
341 { std::sort(indices_,indices_+nElements_); }
342
343 void sortIncrIndex()
344 { std::sort(indices_,indices_+nElements_); }
345
346 void sortDecrIndex();
347
348 void sortIncrElement();
349
350 void sortDecrElement();
351
352 //@}
353
354 //#############################################################################
355
356 /**@name Arithmetic operators on packed vectors.
357
358 <strong>NOTE</strong>: These methods operate on those positions where at
359 least one of the arguments has a value listed. At those positions the
360 appropriate operation is executed, Otherwise the result of the operation is
361 considered 0.<br>
362 <strong>NOTE 2</strong>: Because these methods return an object (they can't
363 return a reference, though they could return a pointer...) they are
364 <em>very</em> inefficient...
365 */
366//@{
367/// Return the sum of two indexed vectors
368CoinIndexedVector operator+(
369 const CoinIndexedVector& op2);
370
371/// Return the difference of two indexed vectors
372CoinIndexedVector operator-(
373 const CoinIndexedVector& op2);
374
375/// Return the element-wise product of two indexed vectors
376CoinIndexedVector operator*(
377 const CoinIndexedVector& op2);
378
379/// Return the element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes)
380CoinIndexedVector operator/(
381 const CoinIndexedVector& op2);
382/// The sum of two indexed vectors
383void operator+=(const CoinIndexedVector& op2);
384
385/// The difference of two indexed vectors
386void operator-=( const CoinIndexedVector& op2);
387
388/// The element-wise product of two indexed vectors
389void operator*=(const CoinIndexedVector& op2);
390
391/// The element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes)
392void operator/=(const CoinIndexedVector& op2);
393//@}
394
395 /**@name Memory usage */
396 //@{
397 /** Reserve space.
398 If one knows the eventual size of the indexed vector,
399 then it may be more efficient to reserve the space.
400 */
401 void reserve(int n);
402 /** capacity returns the size which could be accomodated without
403 having to reallocate storage.
404 */
405 int capacity() const { return capacity_; }
406 /// Sets packed mode
407 inline void setPackedMode(bool yesNo)
408 { packedMode_=yesNo;}
409 /// Gets packed mode
410 inline bool packedMode() const
411 { return packedMode_;}
412 //@}
413
414 /**@name Constructors and destructors */
415 //@{
416 /** Default constructor */
417 CoinIndexedVector();
418 /** Alternate Constructors - set elements to vector of doubles */
419 CoinIndexedVector(int size, const int * inds, const double * elems);
420 /** Alternate Constructors - set elements to same scalar value */
421 CoinIndexedVector(int size, const int * inds, double element);
422 /** Alternate Constructors - construct full storage with indices 0 through
423 size-1. */
424 CoinIndexedVector(int size, const double * elements);
425 /** Alternate Constructors - just size */
426 CoinIndexedVector(int size);
427 /** Copy constructor. */
428 CoinIndexedVector(const CoinIndexedVector &);
429 /** Copy constructor.2 */
430 CoinIndexedVector(const CoinIndexedVector *);
431#ifndef CLP_NO_VECTOR
432 /** Copy constructor <em>from a PackedVectorBase</em>. */
433 CoinIndexedVector(const CoinPackedVectorBase & rhs);
434#endif
435 /** Destructor */
436 ~CoinIndexedVector ();
437 //@}
438
439private:
440 /**@name Private methods */
441 //@{
442 /// Copy internal data
443 void gutsOfSetVector(int size,
444 const int * inds, const double * elems);
445 void gutsOfSetVector(int size, int numberIndices,
446 const int * inds, const double * elems);
447 void gutsOfSetPackedVector(int size, int numberIndices,
448 const int * inds, const double * elems);
449 ///
450 void gutsOfSetConstant(int size,
451 const int * inds, double value);
452 //@}
453
454private:
455 /**@name Private member data */
456 //@{
457 /// Vector indices
458 int * indices_;
459 ///Vector elements
460 double * elements_;
461 /// Size of indices and packed elements vectors
462 int nElements_;
463 /// Amount of memory allocated for indices_, and elements_.
464 int capacity_;
465 /// Offset to get where new allocated array
466 int offset_;
467 /// If true then is operating in packed mode
468 bool packedMode_;
469 //@}
470};
471
472//#############################################################################
473/** A function that tests the methods in the CoinIndexedVector class. The
474 only reason for it not to be a member method is that this way it doesn't
475 have to be compiled into the library. And that's a gain, because the
476 library should be compiled with optimization on, but this method should be
477 compiled with debugging. */
478void
479CoinIndexedVectorUnitTest();
480/** Pointer with length in bytes
481
482 This has a pointer to an array and the number of bytes in array.
483 If number of bytes==-1 then
484 CoinConditionalNew deletes existing pointer and returns new pointer
485 of correct size (and number bytes still -1).
486 CoinConditionalDelete deletes existing pointer and NULLs it.
487 So behavior is as normal (apart from New deleting pointer which will have
488 no effect with good coding practices.
489 If number of bytes >=0 then
490 CoinConditionalNew just returns existing pointer if array big enough
491 otherwise deletes existing pointer, allocates array with spare 1%+64 bytes
492 and updates number of bytes
493 CoinConditionalDelete sets number of bytes = -size-2 and then array
494 returns NULL
495*/
496class CoinArrayWithLength {
497
498public:
499 /**@name Get methods. */
500 //@{
501 /// Get the size
502 inline int getSize() const
503 { return size_; }
504 /// Get the size
505 inline int rawSize() const
506 { return size_; }
507 /// See if persistence already on
508 inline bool switchedOn() const
509 { return size_!=-1; }
510 /// Get the capacity
511 inline int getCapacity() const
512 { return (size_>-2) ? size_ : (-size_)-2; }
513 /// Set the capacity to >=0 if <=-2
514 inline void setCapacity()
515 { if (size_<=-2) size_ = (-size_)-2; }
516 /// Get Array
517 inline const char * array() const
518 { return (size_>-2) ? array_ : nullptr; }
519 //@}
520
521 /**@name Set methods */
522 //@{
523 /// Set the size
524 inline void setSize(int value)
525 { size_ = value; }
526 /// Set the size to -1
527 inline void switchOff()
528 { size_ = -1; }
529 /// Does what is needed to set persistence
530 void setPersistence(int flag,int currentLength);
531 /// Zero out array
532 void clear();
533 /// Swaps memory between two members
534 void swap(CoinArrayWithLength & other);
535 /// Extend a persistent array keeping data (size in bytes)
536 void extend(int newSize);
537 //@}
538
539 /**@name Condition methods */
540 //@{
541 /// Conditionally gets new array
542 char * conditionalNew(long sizeWanted);
543 /// Conditionally deletes
544 void conditionalDelete();
545 //@}
546
547 /**@name Constructors and destructors */
548 //@{
549 /** Default constructor - NULL*/
550 inline CoinArrayWithLength()
551 { array_=nullptr; size_=-1;}
552 /** Alternate Constructor - length in bytes - size_ -1 */
553 inline CoinArrayWithLength(int size)
554 { array_=new char [size]; size_=-1;}
555 /** Alternate Constructor - length in bytes
556 mode - 0 size_ set to size
557 1 size_ set to size and zeroed
558 */
559 inline CoinArrayWithLength(int size, int mode)
560 { array_ = new char [size]; if (mode) memset(array_,0,size);size_=size;}
561 /** Copy constructor. */
562 CoinArrayWithLength(const CoinArrayWithLength & rhs);
563 /** Copy constructor.2 */
564 CoinArrayWithLength(const CoinArrayWithLength * rhs);
565 /** Assignment operator. */
566 CoinArrayWithLength& operator=(const CoinArrayWithLength & rhs);
567 /** Assignment with length (if -1 use internal length) */
568 void copy(const CoinArrayWithLength & rhs, int numberBytes=-1);
569 /** Assignment with length - does not copy */
570 void allocate(const CoinArrayWithLength & rhs, int numberBytes);
571 /** Destructor */
572 inline ~CoinArrayWithLength ()
573 { delete [] array_; }
574 // was { free(array_); }
575 //@}
576
577protected:
578 /**@name Private member data */
579 //@{
580 /// Array
581 char * array_;
582 /// Size of array in bytes
583 int size_;
584 //@}
585};
586/// double * version
587
588class CoinDoubleArrayWithLength : public CoinArrayWithLength {
589
590public:
591 /**@name Get methods. */
592 //@{
593 /// Get the size
594 inline int getSize() const
595 { return size_/CoinSizeofAsInt(double); }
596 /// Get Array
597 inline double * array() const
598 { return reinterpret_cast<double *> ((size_>-2) ? array_ : nullptr); }
599 //@}
600
601 /**@name Set methods */
602 //@{
603 /// Set the size
604 inline void setSize(int value)
605 { size_ = value*CoinSizeofAsInt(double); }
606 //@}
607
608 /**@name Condition methods */
609 //@{
610 /// Conditionally gets new array
611 inline double * conditionalNew(int sizeWanted)
612 { return reinterpret_cast<double *> ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> ((sizeWanted)*CoinSizeofAsInt(double)) : -1)); }
613 //@}
614
615 /**@name Constructors and destructors */
616 //@{
617 /** Default constructor - NULL*/
618 inline CoinDoubleArrayWithLength()
619 { array_=nullptr; size_=-1;}
620 /** Alternate Constructor - length in bytes - size_ -1 */
621 inline CoinDoubleArrayWithLength(int size)
622 { array_=new char [size*CoinSizeofAsInt(double)]; size_=-1;}
623 /** Alternate Constructor - length in bytes
624 mode - 0 size_ set to size
625 1 size_ set to size and zeroed
626 */
627 inline CoinDoubleArrayWithLength(int size, int mode)
628 : CoinArrayWithLength(size*CoinSizeofAsInt(double),mode) {}
629 /** Copy constructor. */
630 inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength & rhs)
631 : CoinArrayWithLength(rhs) {}
632 /** Copy constructor.2 */
633 inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength * rhs)
634 : CoinArrayWithLength(rhs) {}
635 /** Assignment operator. */
636 inline CoinDoubleArrayWithLength& operator=(const CoinDoubleArrayWithLength & rhs)
637 { CoinArrayWithLength::operator=(rhs); return *this;}
638 //@}
639};
640/// CoinFactorizationDouble * version
641
642class CoinFactorizationDoubleArrayWithLength : public CoinArrayWithLength {
643
644public:
645 /**@name Get methods. */
646 //@{
647 /// Get the size
648 inline int getSize() const
649 { return size_/CoinSizeofAsInt(CoinFactorizationDouble); }
650 /// Get Array
651 inline CoinFactorizationDouble * array() const
652 { return reinterpret_cast<CoinFactorizationDouble *> ((size_>-2) ? array_ : nullptr); }
653 //@}
654
655 /**@name Set methods */
656 //@{
657 /// Set the size
658 inline void setSize(int value)
659 { size_ = value*CoinSizeofAsInt(CoinFactorizationDouble); }
660 //@}
661
662 /**@name Condition methods */
663 //@{
664 /// Conditionally gets new array
665 inline CoinFactorizationDouble * conditionalNew(int sizeWanted)
666 { return reinterpret_cast<CoinFactorizationDouble *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(CoinFactorizationDouble)) : -1)); }
667 //@}
668
669 /**@name Constructors and destructors */
670 //@{
671 /** Default constructor - NULL*/
672 inline CoinFactorizationDoubleArrayWithLength()
673 { array_=nullptr; size_=-1;}
674 /** Alternate Constructor - length in bytes - size_ -1 */
675 inline CoinFactorizationDoubleArrayWithLength(int size)
676 { array_=new char [size*CoinSizeofAsInt(CoinFactorizationDouble)]; size_=-1;}
677 /** Alternate Constructor - length in bytes
678 mode - 0 size_ set to size
679 1 size_ set to size and zeroed
680 */
681 inline CoinFactorizationDoubleArrayWithLength(int size, int mode)
682 : CoinArrayWithLength(size*CoinSizeofAsInt(CoinFactorizationDouble),mode) {}
683 /** Copy constructor. */
684 inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength & rhs)
685 : CoinArrayWithLength(rhs) {}
686 /** Copy constructor.2 */
687 inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength * rhs)
688 : CoinArrayWithLength(rhs) {}
689 /** Assignment operator. */
690 inline CoinFactorizationDoubleArrayWithLength& operator=(const CoinFactorizationDoubleArrayWithLength & rhs)
691 { CoinArrayWithLength::operator=(rhs); return *this;}
692 //@}
693};
694/// int * version
695
696class CoinIntArrayWithLength : public CoinArrayWithLength {
697
698public:
699 /**@name Get methods. */
700 //@{
701 /// Get the size
702 inline int getSize() const
703 { return size_/CoinSizeofAsInt(int); }
704 /// Get Array
705 inline int * array() const
706 { return reinterpret_cast<int *> ((size_>-2) ? array_ : nullptr); }
707 //@}
708
709 /**@name Set methods */
710 //@{
711 /// Set the size
712 inline void setSize(int value)
713 { size_ = value*CoinSizeofAsInt(int); }
714 //@}
715
716 /**@name Condition methods */
717 //@{
718 /// Conditionally gets new array
719 inline int * conditionalNew(int sizeWanted)
720 { return reinterpret_cast<int *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(int)) : -1)); }
721 //@}
722
723 /**@name Constructors and destructors */
724 //@{
725 /** Default constructor - NULL*/
726 inline CoinIntArrayWithLength()
727 { array_=nullptr; size_=-1;}
728 /** Alternate Constructor - length in bytes - size_ -1 */
729 inline CoinIntArrayWithLength(int size)
730 { array_=new char [size*CoinSizeofAsInt(int)]; size_=-1;}
731 /** Alternate Constructor - length in bytes
732 mode - 0 size_ set to size
733 1 size_ set to size and zeroed
734 */
735 inline CoinIntArrayWithLength(int size, int mode)
736 : CoinArrayWithLength(size*CoinSizeofAsInt(int),mode) {}
737 /** Copy constructor. */
738 inline CoinIntArrayWithLength(const CoinIntArrayWithLength & rhs)
739 : CoinArrayWithLength(rhs) {}
740 /** Copy constructor.2 */
741 inline CoinIntArrayWithLength(const CoinIntArrayWithLength * rhs)
742 : CoinArrayWithLength(rhs) {}
743 /** Assignment operator. */
744 inline CoinIntArrayWithLength& operator=(const CoinIntArrayWithLength & rhs)
745 { CoinArrayWithLength::operator=(rhs); return *this;}
746 //@}
747};
748/// CoinBigIndex * version
749
750class CoinBigIndexArrayWithLength : public CoinArrayWithLength {
751
752public:
753 /**@name Get methods. */
754 //@{
755 /// Get the size
756 inline int getSize() const
757 { return size_/CoinSizeofAsInt(CoinBigIndex); }
758 /// Get Array
759 inline CoinBigIndex * array() const
760 { return reinterpret_cast<CoinBigIndex *> ((size_>-2) ? array_ : nullptr); }
761 //@}
762
763 /**@name Set methods */
764 //@{
765 /// Set the size
766 inline void setSize(int value)
767 { size_ = value*CoinSizeofAsInt(CoinBigIndex); }
768 //@}
769
770 /**@name Condition methods */
771 //@{
772 /// Conditionally gets new array
773 inline CoinBigIndex * conditionalNew(int sizeWanted)
774 { return reinterpret_cast<CoinBigIndex *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(CoinBigIndex)) : -1)); }
775 //@}
776
777 /**@name Constructors and destructors */
778 //@{
779 /** Default constructor - NULL*/
780 inline CoinBigIndexArrayWithLength()
781 { array_=nullptr; size_=-1;}
782 /** Alternate Constructor - length in bytes - size_ -1 */
783 inline CoinBigIndexArrayWithLength(int size)
784 { array_=new char [size*CoinSizeofAsInt(CoinBigIndex)]; size_=-1;}
785 /** Alternate Constructor - length in bytes
786 mode - 0 size_ set to size
787 1 size_ set to size and zeroed
788 */
789 inline CoinBigIndexArrayWithLength(int size, int mode)
790 : CoinArrayWithLength(size*CoinSizeofAsInt(CoinBigIndex),mode) {}
791 /** Copy constructor. */
792 inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength & rhs)
793 : CoinArrayWithLength(rhs) {}
794 /** Copy constructor.2 */
795 inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength * rhs)
796 : CoinArrayWithLength(rhs) {}
797 /** Assignment operator. */
798 inline CoinBigIndexArrayWithLength& operator=(const CoinBigIndexArrayWithLength & rhs)
799 { CoinArrayWithLength::operator=(rhs); return *this;}
800 //@}
801};
802/// unsigned int * version
803
804class CoinUnsignedIntArrayWithLength : public CoinArrayWithLength {
805
806public:
807 /**@name Get methods. */
808 //@{
809 /// Get the size
810 inline int getSize() const
811 { return size_/CoinSizeofAsInt(unsigned int); }
812 /// Get Array
813 inline unsigned int * array() const
814 { return reinterpret_cast<unsigned int *> ((size_>-2) ? array_ : nullptr); }
815 //@}
816
817 /**@name Set methods */
818 //@{
819 /// Set the size
820 inline void setSize(int value)
821 { size_ = value*CoinSizeofAsInt(unsigned int); }
822 //@}
823
824 /**@name Condition methods */
825 //@{
826 /// Conditionally gets new array
827 inline unsigned int * conditionalNew(int sizeWanted)
828 { return reinterpret_cast<unsigned int *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(unsigned int)) : -1)); }
829 //@}
830
831 /**@name Constructors and destructors */
832 //@{
833 /** Default constructor - NULL*/
834 inline CoinUnsignedIntArrayWithLength()
835 { array_=nullptr; size_=-1;}
836 /** Alternate Constructor - length in bytes - size_ -1 */
837 inline CoinUnsignedIntArrayWithLength(int size)
838 { array_=new char [size*CoinSizeofAsInt(unsigned int)]; size_=-1;}
839 /** Alternate Constructor - length in bytes
840 mode - 0 size_ set to size
841 1 size_ set to size and zeroed
842 */
843 inline CoinUnsignedIntArrayWithLength(int size, int mode)
844 : CoinArrayWithLength(size*CoinSizeofAsInt(unsigned int),mode) {}
845 /** Copy constructor. */
846 inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength & rhs)
847 : CoinArrayWithLength(rhs) {}
848 /** Copy constructor.2 */
849 inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength * rhs)
850 : CoinArrayWithLength(rhs) {}
851 /** Assignment operator. */
852 inline CoinUnsignedIntArrayWithLength& operator=(const CoinUnsignedIntArrayWithLength & rhs)
853 { CoinArrayWithLength::operator=(rhs); return *this;}
854 //@}
855};
856#endif
857