00001
00002
00003
00004 #ifndef CoinHelperFunctions_H
00005 #define CoinHelperFunctions_H
00006 #if defined(_MSC_VER)
00007 # include <direct.h>
00008 # define getcwd _getcwd
00009 #else
00010 # include <unistd.h>
00011 #endif
00012
00013 #include <cstdio>
00014 #include "CoinError.hpp"
00015 #include "CoinFinite.hpp"
00016
00017
00023 template <class T> inline void
00024 CoinCopyN(register const T* from, const int size, register T* to)
00025 {
00026 if (size == 0 || from == to)
00027 return;
00028
00029 if (size < 0)
00030 throw CoinError("trying to copy negative number of entries",
00031 "CoinCopyN", "");
00032
00033 register int n = (size + 7) / 8;
00034 if (to > from) {
00035 register const T* downfrom = from + size;
00036 register T* downto = to + size;
00037
00038 switch (size % 8) {
00039 case 0: do{ *--downto = *--downfrom;
00040 case 7: *--downto = *--downfrom;
00041 case 6: *--downto = *--downfrom;
00042 case 5: *--downto = *--downfrom;
00043 case 4: *--downto = *--downfrom;
00044 case 3: *--downto = *--downfrom;
00045 case 2: *--downto = *--downfrom;
00046 case 1: *--downto = *--downfrom;
00047 }while(--n>0);
00048 }
00049 } else {
00050
00051 --from;
00052 --to;
00053 switch (size % 8) {
00054 case 0: do{ *++to = *++from;
00055 case 7: *++to = *++from;
00056 case 6: *++to = *++from;
00057 case 5: *++to = *++from;
00058 case 4: *++to = *++from;
00059 case 3: *++to = *++from;
00060 case 2: *++to = *++from;
00061 case 1: *++to = *++from;
00062 }while(--n>0);
00063 }
00064 }
00065 }
00066
00067
00068
00073 template <class T> inline void
00074 CoinCopy(register const T* first, register const T* last, register T* to)
00075 {
00076 CoinCopyN(first, last - first, to);
00077 }
00078
00079
00080
00088 template <class T> inline void
00089 CoinDisjointCopyN(register const T* from, const int size, register T* to)
00090 {
00091 #ifndef _MSC_VER
00092 if (size == 0 || from == to)
00093 return;
00094
00095 if (size < 0)
00096 throw CoinError("trying to copy negative number of entries",
00097 "CoinDisjointCopyN", "");
00098
00099 #if 0
00100
00101
00102
00103 const long dist = to - from;
00104 if (-size < dist && dist < size)
00105 throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
00106 #endif
00107
00108 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00109 to[0] = from[0];
00110 to[1] = from[1];
00111 to[2] = from[2];
00112 to[3] = from[3];
00113 to[4] = from[4];
00114 to[5] = from[5];
00115 to[6] = from[6];
00116 to[7] = from[7];
00117 }
00118 switch (size % 8) {
00119 case 7: to[6] = from[6];
00120 case 6: to[5] = from[5];
00121 case 5: to[4] = from[4];
00122 case 4: to[3] = from[3];
00123 case 3: to[2] = from[2];
00124 case 2: to[1] = from[1];
00125 case 1: to[0] = from[0];
00126 case 0: break;
00127 }
00128 #else
00129 CoinCopyN(from, size, to);
00130 #endif
00131 }
00132
00133
00134
00139 template <class T> inline void
00140 CoinDisjointCopy(register const T* first, register const T* last,
00141 register T* to)
00142 {
00143 CoinDisjointCopyN(first, static_cast<int>(last - first), to);
00144 }
00145
00146
00147
00152 template <class T> inline T*
00153 CoinCopyOfArray( const T * array, const int size)
00154 {
00155 if (array) {
00156 T * arrayNew = new T[size];
00157 memcpy(arrayNew,array,size*sizeof(T));
00158 return arrayNew;
00159 } else {
00160 return NULL;
00161 }
00162 }
00163
00164
00169 template <class T> inline T*
00170 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
00171 {
00172 if (array) {
00173 T * arrayNew = new T[size];
00174 assert (copySize<=size);
00175 memcpy(arrayNew,array,copySize*sizeof(T));
00176 return arrayNew;
00177 } else {
00178 return NULL;
00179 }
00180 }
00181
00186 template <class T> inline T*
00187 CoinCopyOfArray( const T * array, const int size, T value)
00188 {
00189 T * arrayNew = new T[size];
00190 if (array) {
00191 memcpy(arrayNew,array,size*sizeof(T));
00192 } else {
00193 int i;
00194 for (i=0;i<size;i++)
00195 arrayNew[i] = value;
00196 }
00197 return arrayNew;
00198 }
00199
00200
00205 template <class T> inline T*
00206 CoinCopyOfArrayOrZero( const T * array , const int size)
00207 {
00208 T * arrayNew = new T[size];
00209 if (array) {
00210 memcpy(arrayNew,array,size*sizeof(T));
00211 } else {
00212 memset(arrayNew,0,size*sizeof(T));
00213 }
00214 return arrayNew;
00215 }
00216
00217
00218
00219
00227 template <class T> inline void
00228 CoinMemcpyN(register const T* from, const int size, register T* to)
00229 {
00230 #ifndef _MSC_VER
00231 #ifdef USE_MEMCPY
00232
00233 #ifndef NDEBUG
00234
00235 if (size < 0)
00236 throw CoinError("trying to copy negative number of entries",
00237 "CoinMemcpyN", "");
00238
00239 #if 0
00240
00241
00242
00243 const long dist = to - from;
00244 if (-size < dist && dist < size)
00245 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00246 #endif
00247 #endif
00248 memcpy(to,from,size*sizeof(T));
00249 #else
00250 if (size == 0 || from == to)
00251 return;
00252
00253 if (size < 0)
00254 throw CoinError("trying to copy negative number of entries",
00255 "CoinMemcpyN", "");
00256
00257 #if 0
00258
00259
00260
00261 const long dist = to - from;
00262 if (-size < dist && dist < size)
00263 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00264 #endif
00265
00266 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00267 to[0] = from[0];
00268 to[1] = from[1];
00269 to[2] = from[2];
00270 to[3] = from[3];
00271 to[4] = from[4];
00272 to[5] = from[5];
00273 to[6] = from[6];
00274 to[7] = from[7];
00275 }
00276 switch (size % 8) {
00277 case 7: to[6] = from[6];
00278 case 6: to[5] = from[5];
00279 case 5: to[4] = from[4];
00280 case 4: to[3] = from[3];
00281 case 3: to[2] = from[2];
00282 case 2: to[1] = from[1];
00283 case 1: to[0] = from[0];
00284 case 0: break;
00285 }
00286 #endif
00287 #else
00288 CoinCopyN(from, size, to);
00289 #endif
00290 }
00291
00292
00293
00298 template <class T> inline void
00299 CoinMemcpy(register const T* first, register const T* last,
00300 register T* to)
00301 {
00302 CoinMemcpyN(first, static_cast<int>(last - first), to);
00303 }
00304
00305
00306
00313 template <class T> inline void
00314 CoinFillN(register T* to, const int size, register const T value)
00315 {
00316 if (size == 0)
00317 return;
00318
00319 if (size < 0)
00320 throw CoinError("trying to fill negative number of entries",
00321 "CoinFillN", "");
00322
00323 #if 1
00324 for (register int n = size / 8; n > 0; --n, to += 8) {
00325 to[0] = value;
00326 to[1] = value;
00327 to[2] = value;
00328 to[3] = value;
00329 to[4] = value;
00330 to[5] = value;
00331 to[6] = value;
00332 to[7] = value;
00333 }
00334 switch (size % 8) {
00335 case 7: to[6] = value;
00336 case 6: to[5] = value;
00337 case 5: to[4] = value;
00338 case 4: to[3] = value;
00339 case 3: to[2] = value;
00340 case 2: to[1] = value;
00341 case 1: to[0] = value;
00342 case 0: break;
00343 }
00344 #else
00345
00346 register int n = (size + 7) / 8;
00347 --to;
00348 switch (size % 8) {
00349 case 0: do{ *++to = value;
00350 case 7: *++to = value;
00351 case 6: *++to = value;
00352 case 5: *++to = value;
00353 case 4: *++to = value;
00354 case 3: *++to = value;
00355 case 2: *++to = value;
00356 case 1: *++to = value;
00357 }while(--n>0);
00358 }
00359 #endif
00360 }
00361
00362
00363
00367 template <class T> inline void
00368 CoinFill(register T* first, register T* last, const T value)
00369 {
00370 CoinFillN(first, last - first, value);
00371 }
00372
00373
00374
00381 template <class T> inline void
00382 CoinZeroN(register T* to, const int size)
00383 {
00384 #ifdef USE_MEMCPY
00385
00386 #ifndef NDEBUG
00387
00388 if (size < 0)
00389 throw CoinError("trying to fill negative number of entries",
00390 "CoinZeroN", "");
00391 #endif
00392 memset(to,0,size*sizeof(T));
00393 #else
00394 if (size == 0)
00395 return;
00396
00397 if (size < 0)
00398 throw CoinError("trying to fill negative number of entries",
00399 "CoinZeroN", "");
00400 #if 1
00401 for (register int n = size / 8; n > 0; --n, to += 8) {
00402 to[0] = 0;
00403 to[1] = 0;
00404 to[2] = 0;
00405 to[3] = 0;
00406 to[4] = 0;
00407 to[5] = 0;
00408 to[6] = 0;
00409 to[7] = 0;
00410 }
00411 switch (size % 8) {
00412 case 7: to[6] = 0;
00413 case 6: to[5] = 0;
00414 case 5: to[4] = 0;
00415 case 4: to[3] = 0;
00416 case 3: to[2] = 0;
00417 case 2: to[1] = 0;
00418 case 1: to[0] = 0;
00419 case 0: break;
00420 }
00421 #else
00422
00423 register int n = (size + 7) / 8;
00424 --to;
00425 switch (size % 8) {
00426 case 0: do{ *++to = 0;
00427 case 7: *++to = 0;
00428 case 6: *++to = 0;
00429 case 5: *++to = 0;
00430 case 4: *++to = 0;
00431 case 3: *++to = 0;
00432 case 2: *++to = 0;
00433 case 1: *++to = 0;
00434 }while(--n>0);
00435 }
00436 #endif
00437 #endif
00438 }
00440 inline void
00441 CoinCheckDoubleZero(double * to, const int size)
00442 {
00443 int n=0;
00444 for (int j=0;j<size;j++) {
00445 if (to[j])
00446 n++;
00447 }
00448 if (n) {
00449 printf("array of length %d should be zero has %d nonzero\n",size,n);
00450 }
00451 }
00453 inline void
00454 CoinCheckIntZero(int * to, const int size)
00455 {
00456 int n=0;
00457 for (int j=0;j<size;j++) {
00458 if (to[j])
00459 n++;
00460 }
00461 if (n) {
00462 printf("array of length %d should be zero has %d nonzero\n",size,n);
00463 }
00464 }
00465
00466
00467
00471 template <class T> inline void
00472 CoinZero(register T* first, register T* last)
00473 {
00474 CoinZeroN(first, last - first);
00475 }
00476
00477
00478
00482 template <class T> inline T
00483 CoinMax(register const T x1, register const T x2)
00484 {
00485 return (x1 > x2) ? x1 : x2;
00486 }
00487
00488
00489
00493 template <class T> inline T
00494 CoinMin(register const T x1, register const T x2)
00495 {
00496 return (x1 < x2) ? x1 : x2;
00497 }
00498
00499
00500
00504 template <class T> inline T
00505 CoinAbs(const T value)
00506 {
00507 return value<0 ? -value : value;
00508 }
00509
00510
00511
00515 template <class T> inline bool
00516 CoinIsSorted(register const T* first, const int size)
00517 {
00518 if (size == 0)
00519 return true;
00520
00521 if (size < 0)
00522 throw CoinError("negative number of entries", "CoinIsSorted", "");
00523
00524 #if 1
00525
00526 const int size1 = size - 1;
00527 for (register int n = size1 / 8; n > 0; --n, first += 8) {
00528 if (first[8] < first[7]) return false;
00529 if (first[7] < first[6]) return false;
00530 if (first[6] < first[5]) return false;
00531 if (first[5] < first[4]) return false;
00532 if (first[4] < first[3]) return false;
00533 if (first[3] < first[2]) return false;
00534 if (first[2] < first[1]) return false;
00535 if (first[1] < first[0]) return false;
00536 }
00537
00538 switch (size1 % 8) {
00539 case 7: if (first[7] < first[6]) return false;
00540 case 6: if (first[6] < first[5]) return false;
00541 case 5: if (first[5] < first[4]) return false;
00542 case 4: if (first[4] < first[3]) return false;
00543 case 3: if (first[3] < first[2]) return false;
00544 case 2: if (first[2] < first[1]) return false;
00545 case 1: if (first[1] < first[0]) return false;
00546 case 0: break;
00547 }
00548 #else
00549 register const T* next = first;
00550 register const T* last = first + size;
00551 for (++next; next != last; first = next, ++next)
00552 if (*next < *first)
00553 return false;
00554 #endif
00555 return true;
00556 }
00557
00558
00559
00563 template <class T> inline bool
00564 CoinIsSorted(register const T* first, register const T* last)
00565 {
00566 return CoinIsSorted(first, static_cast<int>(last - first));
00567 }
00568
00569
00570
00574 template <class T> inline void
00575 CoinIotaN(register T* first, const int size, register T init)
00576 {
00577 if (size == 0)
00578 return;
00579
00580 if (size < 0)
00581 throw CoinError("negative number of entries", "CoinIotaN", "");
00582
00583 #if 1
00584 for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00585 first[0] = init;
00586 first[1] = init + 1;
00587 first[2] = init + 2;
00588 first[3] = init + 3;
00589 first[4] = init + 4;
00590 first[5] = init + 5;
00591 first[6] = init + 6;
00592 first[7] = init + 7;
00593 }
00594 switch (size % 8) {
00595 case 7: first[6] = init + 6;
00596 case 6: first[5] = init + 5;
00597 case 5: first[4] = init + 4;
00598 case 4: first[3] = init + 3;
00599 case 3: first[2] = init + 2;
00600 case 2: first[1] = init + 1;
00601 case 1: first[0] = init;
00602 case 0: break;
00603 }
00604 #else
00605
00606 register int n = (size + 7) / 8;
00607 --first;
00608 --init;
00609 switch (size % 8) {
00610 case 0: do{ *++first = ++init;
00611 case 7: *++first = ++init;
00612 case 6: *++first = ++init;
00613 case 5: *++first = ++init;
00614 case 4: *++first = ++init;
00615 case 3: *++first = ++init;
00616 case 2: *++first = ++init;
00617 case 1: *++first = ++init;
00618 }while(--n>0);
00619 }
00620 #endif
00621 }
00622
00623
00624
00628 template <class T> inline void
00629 CoinIota(T* first, const T* last, T init)
00630 {
00631 CoinIotaN(first, last-first, init);
00632 }
00633
00634
00635
00641 template <class T> inline T *
00642 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00643 const int * firstDelPos, const int * lastDelPos)
00644 {
00645 int delNum = lastDelPos - firstDelPos;
00646 if (delNum == 0)
00647 return arrayLast;
00648
00649 if (delNum < 0)
00650 throw CoinError("trying to delete negative number of entries",
00651 "CoinDeleteEntriesFromArray", "");
00652
00653 int * delSortedPos = NULL;
00654 if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00655 std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00656
00657 delSortedPos = new int[delNum];
00658 CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00659 std::sort(delSortedPos, delSortedPos + delNum);
00660 delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00661 }
00662 const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00663
00664 const int last = delNum - 1;
00665 int size = delSorted[0];
00666 for (int i = 0; i < last; ++i) {
00667 const int copyFirst = delSorted[i] + 1;
00668 const int copyLast = delSorted[i+1];
00669 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00670 arrayFirst + size);
00671 size += copyLast - copyFirst;
00672 }
00673 const int copyFirst = delSorted[last] + 1;
00674 const int copyLast = arrayLast - arrayFirst;
00675 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00676 arrayFirst + size);
00677 size += copyLast - copyFirst;
00678
00679 if (delSortedPos)
00680 delete[] delSortedPos;
00681
00682 return arrayFirst + size;
00683 }
00684 #define COIN_OWN_RANDOM_32
00685
00686
00687
00688
00690 inline void CoinSeedRandom(int iseed)
00691 {
00692 #if defined COIN_OWN_RANDOM_32
00693 double CoinDrand48(bool isSeed = false, unsigned long seed=1);
00694 CoinDrand48(true, iseed);
00695 #else
00696 int jseed;
00697 jseed = iseed + 69822;
00698 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00699 srand(jseed);
00700 #else
00701 srand48(jseed);
00702 #endif
00703 #endif // end else COIN_OWN_RANDOM
00704 }
00705
00707 #if defined COIN_OWN_RANDOM_32
00708
00709
00710
00711
00712 inline double CoinDrand48(bool isSeed = false, unsigned long seed=1)
00713 {
00714 static unsigned last;
00715 if (isSeed) {
00716 last = seed;
00717 } else {
00718 last = 1664525*last+1013904223;
00719 return (((double) last)/4294967296.0);
00720 }
00721 return(0.0);
00722 }
00723 #else
00724 inline double CoinDrand48()
00725 {
00726 double retVal;
00727 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00728 retVal=rand();
00729 retVal=retVal/(double) RAND_MAX;
00730 #else
00731 retVal = drand48();
00732 #endif
00733 return retVal;
00734 }
00735 #endif
00736
00737
00738
00741 inline char CoinFindDirSeparator()
00742 {
00743 int size = 1000;
00744 char* buf = 0;
00745 while (true) {
00746 buf = new char[size];
00747 if (getcwd(buf, size))
00748 break;
00749 delete[] buf;
00750 buf = 0;
00751 size = 2*size;
00752 }
00753
00754
00755 char dirsep = buf[0] == '/' ? '/' : '\\';
00756 delete[] buf;
00757 return dirsep;
00758 }
00759
00760
00761 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00762 const size_t len)
00763 {
00764 for (size_t i = 0; i < len; ++i) {
00765 if (s0[i] == 0) {
00766 return s1[i] == 0 ? 0 : -1;
00767 }
00768 if (s1[i] == 0) {
00769 return 1;
00770 }
00771 const int c0 = tolower(s0[i]);
00772 const int c1 = tolower(s1[i]);
00773 if (c0 < c1)
00774 return -1;
00775 if (c0 > c1)
00776 return 1;
00777 }
00778 return 0;
00779 }
00780
00781
00782
00784 template <class T> inline void CoinSwap (T &x, T &y)
00785 {
00786 T t = x;
00787 x = y;
00788 y = t;
00789 }
00790
00791
00792
00797 template <class T> inline int
00798 CoinToFile( const T* array, int size, FILE * fp)
00799 {
00800 int numberWritten;
00801 if (array&&size) {
00802 numberWritten = fwrite(&size,sizeof(int),1,fp);
00803 if (numberWritten!=1)
00804 return 1;
00805 numberWritten = fwrite(array,sizeof(T),size,fp);
00806 if (numberWritten!=size)
00807 return 1;
00808 } else {
00809 size = 0;
00810 numberWritten = fwrite(&size,sizeof(int),1,fp);
00811 if (numberWritten!=1)
00812 return 1;
00813 }
00814 return 0;
00815 }
00816
00817
00818
00825 template <class T> inline int
00826 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00827 {
00828 int numberRead;
00829 numberRead = fread(&newSize,sizeof(int),1,fp);
00830 if (numberRead!=1)
00831 return 1;
00832 int returnCode=0;
00833 if (size!=newSize&&(newSize||array))
00834 returnCode=2;
00835 if (newSize) {
00836 array = new T [newSize];
00837 numberRead = fread(array,sizeof(T),newSize,fp);
00838 if (numberRead!=newSize)
00839 returnCode=1;
00840 } else {
00841 array = NULL;
00842 }
00843 return returnCode;
00844 }
00845
00846
00847
00849 inline double CoinCbrt(double x)
00850 {
00851 #if defined(_MSC_VER)
00852 return pow(x,(1./3.));
00853 #else
00854 return cbrt(x);
00855 #endif
00856 }
00859 #if defined COIN_OWN_RANDOM_32
00860 class CoinThreadRandom {
00861 public:
00866 CoinThreadRandom()
00867 { seed_=12345678;}
00869 CoinThreadRandom(int seed)
00870 {
00871 seed_ = seed;
00872 }
00874 ~CoinThreadRandom() {}
00875
00876 CoinThreadRandom(const CoinThreadRandom & rhs)
00877 { seed_ = rhs.seed_;}
00878
00879 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00880 {
00881 if (this != &rhs) {
00882 seed_ = rhs.seed_;
00883 }
00884 return *this;
00885 }
00886
00888
00893 inline void setSeed(int seed)
00894 {
00895 seed_ = seed;
00896 }
00898 inline double randomDouble() const
00899 {
00900 double retVal;
00901 seed_ = 1664525*(seed_)+1013904223;
00902 retVal = (((double) seed_)/4294967296.0);
00903 return retVal;
00904 }
00906
00907
00908 protected:
00912
00913 mutable unsigned int seed_;
00915 };
00916 #else
00917 class CoinThreadRandom {
00918 public:
00923 CoinThreadRandom()
00924 { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00926 CoinThreadRandom(const unsigned short seed[3])
00927 { memcpy(seed_,seed,3*sizeof(unsigned short));}
00929 CoinThreadRandom(int seed)
00930 {
00931 union { int i[2]; unsigned short int s[4];} put;
00932 put.i[0]=seed;
00933 put.i[1]=seed;
00934 memcpy(seed_,put.s,3*sizeof(unsigned short));
00935 }
00937 ~CoinThreadRandom() {}
00938
00939 CoinThreadRandom(const CoinThreadRandom & rhs)
00940 { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00941
00942 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00943 {
00944 if (this != &rhs) {
00945 memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
00946 }
00947 return *this;
00948 }
00949
00951
00956 inline void setSeed(const unsigned short seed[3])
00957 { memcpy(seed_,seed,3*sizeof(unsigned short));}
00959 inline void setSeed(int seed)
00960 {
00961 union { int i[2]; unsigned short int s[4];} put;
00962 put.i[0]=seed;
00963 put.i[1]=seed;
00964 memcpy(seed_,put.s,3*sizeof(unsigned short));
00965 }
00967 inline double randomDouble() const
00968 {
00969 double retVal;
00970 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00971 retVal=rand();
00972 retVal=retVal/(double) RAND_MAX;
00973 #else
00974 retVal = erand48(seed_);
00975 #endif
00976 return retVal;
00977 }
00979
00980
00981 protected:
00985
00986 mutable unsigned short seed_[3];
00988 };
00989 #endif
00990 #endif