00001
00002
00003
00004
00005 #ifndef CoinHelperFunctions_H
00006 #define CoinHelperFunctions_H
00007 #if defined(_MSC_VER)
00008 # include <direct.h>
00009 # define getcwd _getcwd
00010 #else
00011 # include <unistd.h>
00012 #endif
00013
00014
00015 #include <cstdlib>
00016 #include <cstdio>
00017 #include "CoinError.hpp"
00018 #include "CoinFinite.hpp"
00019
00020
00026 template <class T> inline void
00027 CoinCopyN(register const T* from, const int size, register T* to)
00028 {
00029 if (size == 0 || from == to)
00030 return;
00031
00032 #ifndef NDEBUG
00033 if (size < 0)
00034 throw CoinError("trying to copy negative number of entries",
00035 "CoinCopyN", "");
00036 #endif
00037
00038 register int n = (size + 7) / 8;
00039 if (to > from) {
00040 register const T* downfrom = from + size;
00041 register T* downto = to + size;
00042
00043 switch (size % 8) {
00044 case 0: do{ *--downto = *--downfrom;
00045 case 7: *--downto = *--downfrom;
00046 case 6: *--downto = *--downfrom;
00047 case 5: *--downto = *--downfrom;
00048 case 4: *--downto = *--downfrom;
00049 case 3: *--downto = *--downfrom;
00050 case 2: *--downto = *--downfrom;
00051 case 1: *--downto = *--downfrom;
00052 }while(--n>0);
00053 }
00054 } else {
00055
00056 --from;
00057 --to;
00058 switch (size % 8) {
00059 case 0: do{ *++to = *++from;
00060 case 7: *++to = *++from;
00061 case 6: *++to = *++from;
00062 case 5: *++to = *++from;
00063 case 4: *++to = *++from;
00064 case 3: *++to = *++from;
00065 case 2: *++to = *++from;
00066 case 1: *++to = *++from;
00067 }while(--n>0);
00068 }
00069 }
00070 }
00071
00072
00073
00078 template <class T> inline void
00079 CoinCopy(register const T* first, register const T* last, register T* to)
00080 {
00081 CoinCopyN(first, last - first, to);
00082 }
00083
00084
00085
00093 template <class T> inline void
00094 CoinDisjointCopyN(register const T* from, const int size, register T* to)
00095 {
00096 #ifndef _MSC_VER
00097 if (size == 0 || from == to)
00098 return;
00099
00100 #ifndef NDEBUG
00101 if (size < 0)
00102 throw CoinError("trying to copy negative number of entries",
00103 "CoinDisjointCopyN", "");
00104 #endif
00105
00106 #if 0
00107
00108
00109
00110 const long dist = to - from;
00111 if (-size < dist && dist < size)
00112 throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
00113 #endif
00114
00115 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00116 to[0] = from[0];
00117 to[1] = from[1];
00118 to[2] = from[2];
00119 to[3] = from[3];
00120 to[4] = from[4];
00121 to[5] = from[5];
00122 to[6] = from[6];
00123 to[7] = from[7];
00124 }
00125 switch (size % 8) {
00126 case 7: to[6] = from[6];
00127 case 6: to[5] = from[5];
00128 case 5: to[4] = from[4];
00129 case 4: to[3] = from[3];
00130 case 3: to[2] = from[2];
00131 case 2: to[1] = from[1];
00132 case 1: to[0] = from[0];
00133 case 0: break;
00134 }
00135 #else
00136 CoinCopyN(from, size, to);
00137 #endif
00138 }
00139
00140
00141
00146 template <class T> inline void
00147 CoinDisjointCopy(register const T* first, register const T* last,
00148 register T* to)
00149 {
00150 CoinDisjointCopyN(first, static_cast<int>(last - first), to);
00151 }
00152
00153
00154
00159 template <class T> inline T*
00160 CoinCopyOfArray( const T * array, const int size)
00161 {
00162 if (array) {
00163 T * arrayNew = new T[size];
00164 std::memcpy(arrayNew,array,size*sizeof(T));
00165 return arrayNew;
00166 } else {
00167 return NULL;
00168 }
00169 }
00170
00171
00176 template <class T> inline T*
00177 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
00178 {
00179 if (array||size) {
00180 T * arrayNew = new T[size];
00181 assert (copySize<=size);
00182 std::memcpy(arrayNew,array,copySize*sizeof(T));
00183 return arrayNew;
00184 } else {
00185 return NULL;
00186 }
00187 }
00188
00193 template <class T> inline T*
00194 CoinCopyOfArray( const T * array, const int size, T value)
00195 {
00196 T * arrayNew = new T[size];
00197 if (array) {
00198 std::memcpy(arrayNew,array,size*sizeof(T));
00199 } else {
00200 int i;
00201 for (i=0;i<size;i++)
00202 arrayNew[i] = value;
00203 }
00204 return arrayNew;
00205 }
00206
00207
00212 template <class T> inline T*
00213 CoinCopyOfArrayOrZero( const T * array , const int size)
00214 {
00215 T * arrayNew = new T[size];
00216 if (array) {
00217 std::memcpy(arrayNew,array,size*sizeof(T));
00218 } else {
00219 std::memset(arrayNew,0,size*sizeof(T));
00220 }
00221 return arrayNew;
00222 }
00223
00224
00225
00226
00234 #ifndef COIN_USE_RESTRICT
00235 template <class T> inline void
00236 CoinMemcpyN(register const T* from, const int size, register T* to)
00237 {
00238 #ifndef _MSC_VER
00239 #ifdef USE_MEMCPY
00240
00241 #ifndef NDEBUG
00242
00243 if (size < 0)
00244 throw CoinError("trying to copy negative number of entries",
00245 "CoinMemcpyN", "");
00246
00247 #if 0
00248
00249
00250
00251 const long dist = to - from;
00252 if (-size < dist && dist < size)
00253 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00254 #endif
00255 #endif
00256 std::memcpy(to,from,size*sizeof(T));
00257 #else
00258 if (size == 0 || from == to)
00259 return;
00260
00261 #ifndef NDEBUG
00262 if (size < 0)
00263 throw CoinError("trying to copy negative number of entries",
00264 "CoinMemcpyN", "");
00265 #endif
00266
00267 #if 0
00268
00269
00270
00271 const long dist = to - from;
00272 if (-size < dist && dist < size)
00273 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00274 #endif
00275
00276 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00277 to[0] = from[0];
00278 to[1] = from[1];
00279 to[2] = from[2];
00280 to[3] = from[3];
00281 to[4] = from[4];
00282 to[5] = from[5];
00283 to[6] = from[6];
00284 to[7] = from[7];
00285 }
00286 switch (size % 8) {
00287 case 7: to[6] = from[6];
00288 case 6: to[5] = from[5];
00289 case 5: to[4] = from[4];
00290 case 4: to[3] = from[3];
00291 case 3: to[2] = from[2];
00292 case 2: to[1] = from[1];
00293 case 1: to[0] = from[0];
00294 case 0: break;
00295 }
00296 #endif
00297 #else
00298 CoinCopyN(from, size, to);
00299 #endif
00300 }
00301 #else
00302 template <class T> inline void
00303 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
00304 {
00305 #ifdef USE_MEMCPY
00306 std::memcpy(to,from,size*sizeof(T));
00307 #else
00308 T * COIN_RESTRICT put = to;
00309 const T * COIN_RESTRICT get = from;
00310 for ( ; 0<size ; --size)
00311 *put++ = *get++;
00312 #endif
00313 }
00314 #endif
00315
00316
00317
00322 template <class T> inline void
00323 CoinMemcpy(register const T* first, register const T* last,
00324 register T* to)
00325 {
00326 CoinMemcpyN(first, static_cast<int>(last - first), to);
00327 }
00328
00329
00330
00337 template <class T> inline void
00338 CoinFillN(register T* to, const int size, register const T value)
00339 {
00340 if (size == 0)
00341 return;
00342
00343 #ifndef NDEBUG
00344 if (size < 0)
00345 throw CoinError("trying to fill negative number of entries",
00346 "CoinFillN", "");
00347 #endif
00348 #if 1
00349 for (register int n = size / 8; n > 0; --n, to += 8) {
00350 to[0] = value;
00351 to[1] = value;
00352 to[2] = value;
00353 to[3] = value;
00354 to[4] = value;
00355 to[5] = value;
00356 to[6] = value;
00357 to[7] = value;
00358 }
00359 switch (size % 8) {
00360 case 7: to[6] = value;
00361 case 6: to[5] = value;
00362 case 5: to[4] = value;
00363 case 4: to[3] = value;
00364 case 3: to[2] = value;
00365 case 2: to[1] = value;
00366 case 1: to[0] = value;
00367 case 0: break;
00368 }
00369 #else
00370
00371 register int n = (size + 7) / 8;
00372 --to;
00373 switch (size % 8) {
00374 case 0: do{ *++to = value;
00375 case 7: *++to = value;
00376 case 6: *++to = value;
00377 case 5: *++to = value;
00378 case 4: *++to = value;
00379 case 3: *++to = value;
00380 case 2: *++to = value;
00381 case 1: *++to = value;
00382 }while(--n>0);
00383 }
00384 #endif
00385 }
00386
00387
00388
00392 template <class T> inline void
00393 CoinFill(register T* first, register T* last, const T value)
00394 {
00395 CoinFillN(first, last - first, value);
00396 }
00397
00398
00399
00406 template <class T> inline void
00407 CoinZeroN(register T* to, const int size)
00408 {
00409 #ifdef USE_MEMCPY
00410
00411 #ifndef NDEBUG
00412
00413 if (size < 0)
00414 throw CoinError("trying to fill negative number of entries",
00415 "CoinZeroN", "");
00416 #endif
00417 memset(to,0,size*sizeof(T));
00418 #else
00419 if (size == 0)
00420 return;
00421
00422 #ifndef NDEBUG
00423 if (size < 0)
00424 throw CoinError("trying to fill negative number of entries",
00425 "CoinZeroN", "");
00426 #endif
00427 #if 1
00428 for (register int n = size / 8; n > 0; --n, to += 8) {
00429 to[0] = 0;
00430 to[1] = 0;
00431 to[2] = 0;
00432 to[3] = 0;
00433 to[4] = 0;
00434 to[5] = 0;
00435 to[6] = 0;
00436 to[7] = 0;
00437 }
00438 switch (size % 8) {
00439 case 7: to[6] = 0;
00440 case 6: to[5] = 0;
00441 case 5: to[4] = 0;
00442 case 4: to[3] = 0;
00443 case 3: to[2] = 0;
00444 case 2: to[1] = 0;
00445 case 1: to[0] = 0;
00446 case 0: break;
00447 }
00448 #else
00449
00450 register int n = (size + 7) / 8;
00451 --to;
00452 switch (size % 8) {
00453 case 0: do{ *++to = 0;
00454 case 7: *++to = 0;
00455 case 6: *++to = 0;
00456 case 5: *++to = 0;
00457 case 4: *++to = 0;
00458 case 3: *++to = 0;
00459 case 2: *++to = 0;
00460 case 1: *++to = 0;
00461 }while(--n>0);
00462 }
00463 #endif
00464 #endif
00465 }
00467 inline void
00468 CoinCheckDoubleZero(double * to, const int size)
00469 {
00470 int n=0;
00471 for (int j=0;j<size;j++) {
00472 if (to[j])
00473 n++;
00474 }
00475 if (n) {
00476 printf("array of length %d should be zero has %d nonzero\n",size,n);
00477 }
00478 }
00480 inline void
00481 CoinCheckIntZero(int * to, const int size)
00482 {
00483 int n=0;
00484 for (int j=0;j<size;j++) {
00485 if (to[j])
00486 n++;
00487 }
00488 if (n) {
00489 printf("array of length %d should be zero has %d nonzero\n",size,n);
00490 }
00491 }
00492
00493
00494
00498 template <class T> inline void
00499 CoinZero(register T* first, register T* last)
00500 {
00501 CoinZeroN(first, last - first);
00502 }
00503
00504
00505
00507 inline char * CoinStrdup(const char * name)
00508 {
00509 char* dup = NULL;
00510 if (name) {
00511 const int len = static_cast<int>(strlen(name));
00512 dup = static_cast<char*>(malloc(len+1));
00513 CoinMemcpyN(name, len, dup);
00514 dup[len] = 0;
00515 }
00516 return dup;
00517 }
00518
00519
00520
00524 template <class T> inline T
00525 CoinMax(register const T x1, register const T x2)
00526 {
00527 return (x1 > x2) ? x1 : x2;
00528 }
00529
00530
00531
00535 template <class T> inline T
00536 CoinMin(register const T x1, register const T x2)
00537 {
00538 return (x1 < x2) ? x1 : x2;
00539 }
00540
00541
00542
00546 template <class T> inline T
00547 CoinAbs(const T value)
00548 {
00549 return value<0 ? -value : value;
00550 }
00551
00552
00553
00557 template <class T> inline bool
00558 CoinIsSorted(register const T* first, const int size)
00559 {
00560 if (size == 0)
00561 return true;
00562
00563 #ifndef NDEBUG
00564 if (size < 0)
00565 throw CoinError("negative number of entries", "CoinIsSorted", "");
00566 #endif
00567 #if 1
00568
00569 const int size1 = size - 1;
00570 for (register int n = size1 / 8; n > 0; --n, first += 8) {
00571 if (first[8] < first[7]) return false;
00572 if (first[7] < first[6]) return false;
00573 if (first[6] < first[5]) return false;
00574 if (first[5] < first[4]) return false;
00575 if (first[4] < first[3]) return false;
00576 if (first[3] < first[2]) return false;
00577 if (first[2] < first[1]) return false;
00578 if (first[1] < first[0]) return false;
00579 }
00580
00581 switch (size1 % 8) {
00582 case 7: if (first[7] < first[6]) return false;
00583 case 6: if (first[6] < first[5]) return false;
00584 case 5: if (first[5] < first[4]) return false;
00585 case 4: if (first[4] < first[3]) return false;
00586 case 3: if (first[3] < first[2]) return false;
00587 case 2: if (first[2] < first[1]) return false;
00588 case 1: if (first[1] < first[0]) return false;
00589 case 0: break;
00590 }
00591 #else
00592 register const T* next = first;
00593 register const T* last = first + size;
00594 for (++next; next != last; first = next, ++next)
00595 if (*next < *first)
00596 return false;
00597 #endif
00598 return true;
00599 }
00600
00601
00602
00606 template <class T> inline bool
00607 CoinIsSorted(register const T* first, register const T* last)
00608 {
00609 return CoinIsSorted(first, static_cast<int>(last - first));
00610 }
00611
00612
00613
00617 template <class T> inline void
00618 CoinIotaN(register T* first, const int size, register T init)
00619 {
00620 if (size == 0)
00621 return;
00622
00623 #ifndef NDEBUG
00624 if (size < 0)
00625 throw CoinError("negative number of entries", "CoinIotaN", "");
00626 #endif
00627 #if 1
00628 for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00629 first[0] = init;
00630 first[1] = init + 1;
00631 first[2] = init + 2;
00632 first[3] = init + 3;
00633 first[4] = init + 4;
00634 first[5] = init + 5;
00635 first[6] = init + 6;
00636 first[7] = init + 7;
00637 }
00638 switch (size % 8) {
00639 case 7: first[6] = init + 6;
00640 case 6: first[5] = init + 5;
00641 case 5: first[4] = init + 4;
00642 case 4: first[3] = init + 3;
00643 case 3: first[2] = init + 2;
00644 case 2: first[1] = init + 1;
00645 case 1: first[0] = init;
00646 case 0: break;
00647 }
00648 #else
00649
00650 register int n = (size + 7) / 8;
00651 --first;
00652 --init;
00653 switch (size % 8) {
00654 case 0: do{ *++first = ++init;
00655 case 7: *++first = ++init;
00656 case 6: *++first = ++init;
00657 case 5: *++first = ++init;
00658 case 4: *++first = ++init;
00659 case 3: *++first = ++init;
00660 case 2: *++first = ++init;
00661 case 1: *++first = ++init;
00662 }while(--n>0);
00663 }
00664 #endif
00665 }
00666
00667
00668
00672 template <class T> inline void
00673 CoinIota(T* first, const T* last, T init)
00674 {
00675 CoinIotaN(first, last-first, init);
00676 }
00677
00678
00679
00685 template <class T> inline T *
00686 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00687 const int * firstDelPos, const int * lastDelPos)
00688 {
00689 int delNum = lastDelPos - firstDelPos;
00690 if (delNum == 0)
00691 return arrayLast;
00692
00693 if (delNum < 0)
00694 throw CoinError("trying to delete negative number of entries",
00695 "CoinDeleteEntriesFromArray", "");
00696
00697 int * delSortedPos = NULL;
00698 if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00699 std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00700
00701 delSortedPos = new int[delNum];
00702 CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00703 std::sort(delSortedPos, delSortedPos + delNum);
00704 delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00705 }
00706 const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00707
00708 const int last = delNum - 1;
00709 int size = delSorted[0];
00710 for (int i = 0; i < last; ++i) {
00711 const int copyFirst = delSorted[i] + 1;
00712 const int copyLast = delSorted[i+1];
00713 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00714 arrayFirst + size);
00715 size += copyLast - copyFirst;
00716 }
00717 const int copyFirst = delSorted[last] + 1;
00718 const int copyLast = arrayLast - arrayFirst;
00719 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00720 arrayFirst + size);
00721 size += copyLast - copyFirst;
00722
00723 if (delSortedPos)
00724 delete[] delSortedPos;
00725
00726 return arrayFirst + size;
00727 }
00728
00729
00730
00731 #define COIN_OWN_RANDOM_32
00732
00733 #if defined COIN_OWN_RANDOM_32
00734
00735
00736
00737
00738
00739
00740
00742 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00743 {
00744 static unsigned int last = 123456;
00745 if (isSeed) {
00746 last = seed;
00747 } else {
00748 last = 1664525*last+1013904223;
00749 return ((static_cast<double> (last))/4294967296.0);
00750 }
00751 return(0.0);
00752 }
00754 inline void CoinSeedRandom(int iseed)
00755 {
00756 CoinDrand48(true, iseed);
00757 }
00758
00759 #else // COIN_OWN_RANDOM_32
00760
00761 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00762
00763 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00764 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00765
00766 #else
00767
00768 inline double CoinDrand48() { return drand48(); }
00769 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00770
00771 #endif
00772
00773 #endif // COIN_OWN_RANDOM_32
00774
00775
00776
00779 inline char CoinFindDirSeparator()
00780 {
00781 int size = 1000;
00782 char* buf = 0;
00783 while (true) {
00784 buf = new char[size];
00785 if (getcwd(buf, size))
00786 break;
00787 delete[] buf;
00788 buf = 0;
00789 size = 2*size;
00790 }
00791
00792
00793 char dirsep = buf[0] == '/' ? '/' : '\\';
00794 delete[] buf;
00795 return dirsep;
00796 }
00797
00798
00799 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00800 const size_t len)
00801 {
00802 for (size_t i = 0; i < len; ++i) {
00803 if (s0[i] == 0) {
00804 return s1[i] == 0 ? 0 : -1;
00805 }
00806 if (s1[i] == 0) {
00807 return 1;
00808 }
00809 const int c0 = tolower(s0[i]);
00810 const int c1 = tolower(s1[i]);
00811 if (c0 < c1)
00812 return -1;
00813 if (c0 > c1)
00814 return 1;
00815 }
00816 return 0;
00817 }
00818
00819
00820
00822 template <class T> inline void CoinSwap (T &x, T &y)
00823 {
00824 T t = x;
00825 x = y;
00826 y = t;
00827 }
00828
00829
00830
00835
00836
00837 template <class T> inline int
00838 CoinToFile( const T* array, int size, FILE * fp)
00839 {
00840 size_t numberWritten;
00841 if (array&&size) {
00842 numberWritten = fwrite(&size,sizeof(int),1,fp);
00843 if (numberWritten!=1)
00844 return 1;
00845 numberWritten = fwrite(array,sizeof(T),size_t(size),fp);
00846 if (numberWritten!=size)
00847 return 1;
00848 } else {
00849 size = 0;
00850 numberWritten = fwrite(&size,sizeof(int),1,fp);
00851 if (numberWritten!=1)
00852 return 1;
00853 }
00854 return 0;
00855 }
00856
00857
00858
00865
00866
00867 template <class T> inline int
00868 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00869 {
00870 size_t numberRead;
00871 numberRead = fread(&newSize,sizeof(int),1,fp);
00872 if (numberRead!=1)
00873 return 1;
00874 int returnCode=0;
00875 if (size!=newSize&&(newSize||array))
00876 returnCode=2;
00877 if (newSize) {
00878 array = new T [newSize];
00879 numberRead = fread(array,sizeof(T),size_t(newSize),fp);
00880 if (numberRead!=newSize)
00881 returnCode=1;
00882 } else {
00883 array = NULL;
00884 }
00885 return returnCode;
00886 }
00887
00888
00889
00891 inline double CoinCbrt(double x)
00892 {
00893 #if defined(_MSC_VER)
00894 return pow(x,(1./3.));
00895 #else
00896 return cbrt(x);
00897 #endif
00898 }
00899
00900
00902 #define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type)))
00903
00904 inline int
00905 CoinStrlenAsInt(const char * string)
00906 {
00907 return static_cast<int>(strlen(string));
00908 }
00909
00912 #if defined COIN_OWN_RANDOM_32
00913 class CoinThreadRandom {
00914 public:
00919 CoinThreadRandom()
00920 { seed_=12345678;}
00922 CoinThreadRandom(int seed)
00923 {
00924 seed_ = seed;
00925 }
00927 ~CoinThreadRandom() {}
00928
00929 CoinThreadRandom(const CoinThreadRandom & rhs)
00930 { seed_ = rhs.seed_;}
00931
00932 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00933 {
00934 if (this != &rhs) {
00935 seed_ = rhs.seed_;
00936 }
00937 return *this;
00938 }
00939
00941
00946 inline void setSeed(int seed)
00947 {
00948 seed_ = seed;
00949 }
00951 inline unsigned int getSeed() const
00952 {
00953 return seed_;
00954 }
00956 inline double randomDouble() const
00957 {
00958 double retVal;
00959 seed_ = 1664525*(seed_)+1013904223;
00960 retVal = ((static_cast<double> (seed_))/4294967296.0);
00961 return retVal;
00962 }
00964
00965
00966 protected:
00970
00971 mutable unsigned int seed_;
00973 };
00974 #else
00975 class CoinThreadRandom {
00976 public:
00981 CoinThreadRandom()
00982 { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00984 CoinThreadRandom(const unsigned short seed[3])
00985 { memcpy(seed_,seed,3*sizeof(unsigned short));}
00987 CoinThreadRandom(int seed)
00988 {
00989 union { int i[2]; unsigned short int s[4];} put;
00990 put.i[0]=seed;
00991 put.i[1]=seed;
00992 memcpy(seed_,put.s,3*sizeof(unsigned short));
00993 }
00995 ~CoinThreadRandom() {}
00996
00997 CoinThreadRandom(const CoinThreadRandom & rhs)
00998 { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00999
01000 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
01001 {
01002 if (this != &rhs) {
01003 memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
01004 }
01005 return *this;
01006 }
01007
01009
01014 inline void setSeed(const unsigned short seed[3])
01015 { memcpy(seed_,seed,3*sizeof(unsigned short));}
01017 inline void setSeed(int seed)
01018 {
01019 union { int i[2]; unsigned short int s[4];} put;
01020 put.i[0]=seed;
01021 put.i[1]=seed;
01022 memcpy(seed_,put.s,3*sizeof(unsigned short));
01023 }
01025 inline double randomDouble() const
01026 {
01027 double retVal;
01028 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
01029 retVal=rand();
01030 retVal=retVal/(double) RAND_MAX;
01031 #else
01032 retVal = erand48(seed_);
01033 #endif
01034 return retVal;
01035 }
01037
01038
01039 protected:
01043
01044 mutable unsigned short seed_[3];
01046 };
01047 #endif
01048 #endif