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 | |
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 |
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 |
368 | CoinIndexedVector operator+( |
369 | const CoinIndexedVector& op2); |
370 | |
371 | /// Return the difference of two indexed vectors |
372 | CoinIndexedVector operator-( |
373 | const CoinIndexedVector& op2); |
374 | |
375 | /// Return the element-wise product of two indexed vectors |
376 | CoinIndexedVector operator*( |
377 | const CoinIndexedVector& op2); |
378 | |
379 | /// Return the element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes) |
380 | CoinIndexedVector operator/( |
381 | const CoinIndexedVector& op2); |
382 | /// The sum of two indexed vectors |
383 | void operator+=(const CoinIndexedVector& op2); |
384 | |
385 | /// The difference of two indexed vectors |
386 | void operator-=( const CoinIndexedVector& op2); |
387 | |
388 | /// The element-wise product of two indexed vectors |
389 | void operator*=(const CoinIndexedVector& op2); |
390 | |
391 | /// The element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes) |
392 | void 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 | |
439 | private: |
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 | |
454 | private: |
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. */ |
478 | void |
479 | CoinIndexedVectorUnitTest(); |
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 | */ |
496 | class CoinArrayWithLength { |
497 | |
498 | public: |
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 | |
577 | protected: |
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 | |
588 | class CoinDoubleArrayWithLength : public CoinArrayWithLength { |
589 | |
590 | public: |
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 | |
642 | class CoinFactorizationDoubleArrayWithLength : public CoinArrayWithLength { |
643 | |
644 | public: |
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 | |
696 | class CoinIntArrayWithLength : public CoinArrayWithLength { |
697 | |
698 | public: |
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 | |
750 | class CoinBigIndexArrayWithLength : public CoinArrayWithLength { |
751 | |
752 | public: |
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 | |
804 | class CoinUnsignedIntArrayWithLength : public CoinArrayWithLength { |
805 | |
806 | public: |
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 | |