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