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
00084 template <class T> inline void
00085 CoinCopy(register const T* first, register const T* last, register T* to)
00086 {
00087 CoinCopyN(first, static_cast<int>(last-first), to);
00088 }
00089
00090
00091
00099 template <class T> inline void
00100 CoinDisjointCopyN(register const T* from, const int size, register T* to)
00101 {
00102 #ifndef _MSC_VER
00103 if (size == 0 || from == to)
00104 return;
00105
00106 #ifndef NDEBUG
00107 if (size < 0)
00108 throw CoinError("trying to copy negative number of entries",
00109 "CoinDisjointCopyN", "");
00110 #endif
00111
00112 #if 0
00113
00114
00115
00116 const long dist = to - from;
00117 if (-size < dist && dist < size)
00118 throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
00119 #endif
00120
00121 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00122 to[0] = from[0];
00123 to[1] = from[1];
00124 to[2] = from[2];
00125 to[3] = from[3];
00126 to[4] = from[4];
00127 to[5] = from[5];
00128 to[6] = from[6];
00129 to[7] = from[7];
00130 }
00131 switch (size % 8) {
00132 case 7: to[6] = from[6];
00133 case 6: to[5] = from[5];
00134 case 5: to[4] = from[4];
00135 case 4: to[3] = from[3];
00136 case 3: to[2] = from[2];
00137 case 2: to[1] = from[1];
00138 case 1: to[0] = from[0];
00139 case 0: break;
00140 }
00141 #else
00142 CoinCopyN(from, size, to);
00143 #endif
00144 }
00145
00146
00147
00152 template <class T> inline void
00153 CoinDisjointCopy(register const T* first, register const T* last,
00154 register T* to)
00155 {
00156 CoinDisjointCopyN(first, static_cast<int>(last - first), to);
00157 }
00158
00159
00160
00165 template <class T> inline T*
00166 CoinCopyOfArray( const T * array, const int size)
00167 {
00168 if (array) {
00169 T * arrayNew = new T[size];
00170 std::memcpy(arrayNew,array,size*sizeof(T));
00171 return arrayNew;
00172 } else {
00173 return NULL;
00174 }
00175 }
00176
00177
00182 template <class T> inline T*
00183 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
00184 {
00185 if (array||size) {
00186 T * arrayNew = new T[size];
00187 assert (copySize<=size);
00188 std::memcpy(arrayNew,array,copySize*sizeof(T));
00189 return arrayNew;
00190 } else {
00191 return NULL;
00192 }
00193 }
00194
00199 template <class T> inline T*
00200 CoinCopyOfArray( const T * array, const int size, T value)
00201 {
00202 T * arrayNew = new T[size];
00203 if (array) {
00204 std::memcpy(arrayNew,array,size*sizeof(T));
00205 } else {
00206 int i;
00207 for (i=0;i<size;i++)
00208 arrayNew[i] = value;
00209 }
00210 return arrayNew;
00211 }
00212
00213
00218 template <class T> inline T*
00219 CoinCopyOfArrayOrZero( const T * array , const int size)
00220 {
00221 T * arrayNew = new T[size];
00222 if (array) {
00223 std::memcpy(arrayNew,array,size*sizeof(T));
00224 } else {
00225 std::memset(arrayNew,0,size*sizeof(T));
00226 }
00227 return arrayNew;
00228 }
00229
00230
00231
00232
00240 #ifndef COIN_USE_RESTRICT
00241 template <class T> inline void
00242 CoinMemcpyN(register const T* from, const int size, register T* to)
00243 {
00244 #ifndef _MSC_VER
00245 #ifdef USE_MEMCPY
00246
00247 #ifndef NDEBUG
00248
00249 if (size < 0)
00250 throw CoinError("trying to copy negative number of entries",
00251 "CoinMemcpyN", "");
00252
00253 #if 0
00254
00255
00256
00257 const long dist = to - from;
00258 if (-size < dist && dist < size)
00259 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00260 #endif
00261 #endif
00262 std::memcpy(to,from,size*sizeof(T));
00263 #else
00264 if (size == 0 || from == to)
00265 return;
00266
00267 #ifndef NDEBUG
00268 if (size < 0)
00269 throw CoinError("trying to copy negative number of entries",
00270 "CoinMemcpyN", "");
00271 #endif
00272
00273 #if 0
00274
00275
00276
00277 const long dist = to - from;
00278 if (-size < dist && dist < size)
00279 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00280 #endif
00281
00282 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00283 to[0] = from[0];
00284 to[1] = from[1];
00285 to[2] = from[2];
00286 to[3] = from[3];
00287 to[4] = from[4];
00288 to[5] = from[5];
00289 to[6] = from[6];
00290 to[7] = from[7];
00291 }
00292 switch (size % 8) {
00293 case 7: to[6] = from[6];
00294 case 6: to[5] = from[5];
00295 case 5: to[4] = from[4];
00296 case 4: to[3] = from[3];
00297 case 3: to[2] = from[2];
00298 case 2: to[1] = from[1];
00299 case 1: to[0] = from[0];
00300 case 0: break;
00301 }
00302 #endif
00303 #else
00304 CoinCopyN(from, size, to);
00305 #endif
00306 }
00307 #else
00308 template <class T> inline void
00309 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
00310 {
00311 #ifdef USE_MEMCPY
00312 std::memcpy(to,from,size*sizeof(T));
00313 #else
00314 T * COIN_RESTRICT put = to;
00315 const T * COIN_RESTRICT get = from;
00316 for ( ; 0<size ; --size)
00317 *put++ = *get++;
00318 #endif
00319 }
00320 #endif
00321
00322
00323
00328 template <class T> inline void
00329 CoinMemcpy(register const T* first, register const T* last,
00330 register T* to)
00331 {
00332 CoinMemcpyN(first, static_cast<int>(last - first), to);
00333 }
00334
00335
00336
00343 template <class T> inline void
00344 CoinFillN(register T* to, const int size, register const T value)
00345 {
00346 if (size == 0)
00347 return;
00348
00349 #ifndef NDEBUG
00350 if (size < 0)
00351 throw CoinError("trying to fill negative number of entries",
00352 "CoinFillN", "");
00353 #endif
00354 #if 1
00355 for (register int n = size / 8; n > 0; --n, to += 8) {
00356 to[0] = value;
00357 to[1] = value;
00358 to[2] = value;
00359 to[3] = value;
00360 to[4] = value;
00361 to[5] = value;
00362 to[6] = value;
00363 to[7] = value;
00364 }
00365 switch (size % 8) {
00366 case 7: to[6] = value;
00367 case 6: to[5] = value;
00368 case 5: to[4] = value;
00369 case 4: to[3] = value;
00370 case 3: to[2] = value;
00371 case 2: to[1] = value;
00372 case 1: to[0] = value;
00373 case 0: break;
00374 }
00375 #else
00376
00377 register int n = (size + 7) / 8;
00378 --to;
00379 switch (size % 8) {
00380 case 0: do{ *++to = value;
00381 case 7: *++to = value;
00382 case 6: *++to = value;
00383 case 5: *++to = value;
00384 case 4: *++to = value;
00385 case 3: *++to = value;
00386 case 2: *++to = value;
00387 case 1: *++to = value;
00388 }while(--n>0);
00389 }
00390 #endif
00391 }
00392
00393
00394
00398 template <class T> inline void
00399 CoinFill(register T* first, register T* last, const T value)
00400 {
00401 CoinFillN(first, last - first, value);
00402 }
00403
00404
00405
00412 template <class T> inline void
00413 CoinZeroN(register T* to, const int size)
00414 {
00415 #ifdef USE_MEMCPY
00416
00417 #ifndef NDEBUG
00418
00419 if (size < 0)
00420 throw CoinError("trying to fill negative number of entries",
00421 "CoinZeroN", "");
00422 #endif
00423 memset(to,0,size*sizeof(T));
00424 #else
00425 if (size == 0)
00426 return;
00427
00428 #ifndef NDEBUG
00429 if (size < 0)
00430 throw CoinError("trying to fill negative number of entries",
00431 "CoinZeroN", "");
00432 #endif
00433 #if 1
00434 for (register int n = size / 8; n > 0; --n, to += 8) {
00435 to[0] = 0;
00436 to[1] = 0;
00437 to[2] = 0;
00438 to[3] = 0;
00439 to[4] = 0;
00440 to[5] = 0;
00441 to[6] = 0;
00442 to[7] = 0;
00443 }
00444 switch (size % 8) {
00445 case 7: to[6] = 0;
00446 case 6: to[5] = 0;
00447 case 5: to[4] = 0;
00448 case 4: to[3] = 0;
00449 case 3: to[2] = 0;
00450 case 2: to[1] = 0;
00451 case 1: to[0] = 0;
00452 case 0: break;
00453 }
00454 #else
00455
00456 register int n = (size + 7) / 8;
00457 --to;
00458 switch (size % 8) {
00459 case 0: do{ *++to = 0;
00460 case 7: *++to = 0;
00461 case 6: *++to = 0;
00462 case 5: *++to = 0;
00463 case 4: *++to = 0;
00464 case 3: *++to = 0;
00465 case 2: *++to = 0;
00466 case 1: *++to = 0;
00467 }while(--n>0);
00468 }
00469 #endif
00470 #endif
00471 }
00473 inline void
00474 CoinCheckDoubleZero(double * to, const int size)
00475 {
00476 int n=0;
00477 for (int j=0;j<size;j++) {
00478 if (to[j])
00479 n++;
00480 }
00481 if (n) {
00482 printf("array of length %d should be zero has %d nonzero\n",size,n);
00483 }
00484 }
00486 inline void
00487 CoinCheckIntZero(int * to, const int size)
00488 {
00489 int n=0;
00490 for (int j=0;j<size;j++) {
00491 if (to[j])
00492 n++;
00493 }
00494 if (n) {
00495 printf("array of length %d should be zero has %d nonzero\n",size,n);
00496 }
00497 }
00498
00499
00500
00504 template <class T> inline void
00505 CoinZero(register T* first, register T* last)
00506 {
00507 CoinZeroN(first, last - first);
00508 }
00509
00510
00511
00513 inline char * CoinStrdup(const char * name)
00514 {
00515 char* dup = NULL;
00516 if (name) {
00517 const int len = static_cast<int>(strlen(name));
00518 dup = static_cast<char*>(malloc(len+1));
00519 CoinMemcpyN(name, len, dup);
00520 dup[len] = 0;
00521 }
00522 return dup;
00523 }
00524
00525
00526
00530 template <class T> inline T
00531 CoinMax(register const T x1, register const T x2)
00532 {
00533 return (x1 > x2) ? x1 : x2;
00534 }
00535
00536
00537
00541 template <class T> inline T
00542 CoinMin(register const T x1, register const T x2)
00543 {
00544 return (x1 < x2) ? x1 : x2;
00545 }
00546
00547
00548
00552 template <class T> inline T
00553 CoinAbs(const T value)
00554 {
00555 return value<0 ? -value : value;
00556 }
00557
00558
00559
00563 template <class T> inline bool
00564 CoinIsSorted(register const T* first, const int size)
00565 {
00566 if (size == 0)
00567 return true;
00568
00569 #ifndef NDEBUG
00570 if (size < 0)
00571 throw CoinError("negative number of entries", "CoinIsSorted", "");
00572 #endif
00573 #if 1
00574
00575 const int size1 = size - 1;
00576 for (register int n = size1 / 8; n > 0; --n, first += 8) {
00577 if (first[8] < first[7]) return false;
00578 if (first[7] < first[6]) return false;
00579 if (first[6] < first[5]) return false;
00580 if (first[5] < first[4]) return false;
00581 if (first[4] < first[3]) return false;
00582 if (first[3] < first[2]) return false;
00583 if (first[2] < first[1]) return false;
00584 if (first[1] < first[0]) return false;
00585 }
00586
00587 switch (size1 % 8) {
00588 case 7: if (first[7] < first[6]) return false;
00589 case 6: if (first[6] < first[5]) return false;
00590 case 5: if (first[5] < first[4]) return false;
00591 case 4: if (first[4] < first[3]) return false;
00592 case 3: if (first[3] < first[2]) return false;
00593 case 2: if (first[2] < first[1]) return false;
00594 case 1: if (first[1] < first[0]) return false;
00595 case 0: break;
00596 }
00597 #else
00598 register const T* next = first;
00599 register const T* last = first + size;
00600 for (++next; next != last; first = next, ++next)
00601 if (*next < *first)
00602 return false;
00603 #endif
00604 return true;
00605 }
00606
00607
00608
00612 template <class T> inline bool
00613 CoinIsSorted(register const T* first, register const T* last)
00614 {
00615 return CoinIsSorted(first, static_cast<int>(last - first));
00616 }
00617
00618
00619
00623 template <class T> inline void
00624 CoinIotaN(register T* first, const int size, register T init)
00625 {
00626 if (size == 0)
00627 return;
00628
00629 #ifndef NDEBUG
00630 if (size < 0)
00631 throw CoinError("negative number of entries", "CoinIotaN", "");
00632 #endif
00633 #if 1
00634 for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00635 first[0] = init;
00636 first[1] = init + 1;
00637 first[2] = init + 2;
00638 first[3] = init + 3;
00639 first[4] = init + 4;
00640 first[5] = init + 5;
00641 first[6] = init + 6;
00642 first[7] = init + 7;
00643 }
00644 switch (size % 8) {
00645 case 7: first[6] = init + 6;
00646 case 6: first[5] = init + 5;
00647 case 5: first[4] = init + 4;
00648 case 4: first[3] = init + 3;
00649 case 3: first[2] = init + 2;
00650 case 2: first[1] = init + 1;
00651 case 1: first[0] = init;
00652 case 0: break;
00653 }
00654 #else
00655
00656 register int n = (size + 7) / 8;
00657 --first;
00658 --init;
00659 switch (size % 8) {
00660 case 0: do{ *++first = ++init;
00661 case 7: *++first = ++init;
00662 case 6: *++first = ++init;
00663 case 5: *++first = ++init;
00664 case 4: *++first = ++init;
00665 case 3: *++first = ++init;
00666 case 2: *++first = ++init;
00667 case 1: *++first = ++init;
00668 }while(--n>0);
00669 }
00670 #endif
00671 }
00672
00673
00674
00678 template <class T> inline void
00679 CoinIota(T* first, const T* last, T init)
00680 {
00681 CoinIotaN(first, last-first, init);
00682 }
00683
00684
00685
00691 template <class T> inline T *
00692 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00693 const int * firstDelPos, const int * lastDelPos)
00694 {
00695 int delNum = static_cast<int>(lastDelPos - firstDelPos);
00696 if (delNum == 0)
00697 return arrayLast;
00698
00699 if (delNum < 0)
00700 throw CoinError("trying to delete negative number of entries",
00701 "CoinDeleteEntriesFromArray", "");
00702
00703 int * delSortedPos = NULL;
00704 if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00705 std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00706
00707 delSortedPos = new int[delNum];
00708 CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00709 std::sort(delSortedPos, delSortedPos + delNum);
00710 delNum = static_cast<int>(std::unique(delSortedPos,
00711 delSortedPos+delNum) - delSortedPos);
00712 }
00713 const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00714
00715 const int last = delNum - 1;
00716 int size = delSorted[0];
00717 for (int i = 0; i < last; ++i) {
00718 const int copyFirst = delSorted[i] + 1;
00719 const int copyLast = delSorted[i+1];
00720 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00721 arrayFirst + size);
00722 size += copyLast - copyFirst;
00723 }
00724 const int copyFirst = delSorted[last] + 1;
00725 const int copyLast = static_cast<int>(arrayLast - arrayFirst);
00726 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00727 arrayFirst + size);
00728 size += copyLast - copyFirst;
00729
00730 if (delSortedPos)
00731 delete[] delSortedPos;
00732
00733 return arrayFirst + size;
00734 }
00735
00736
00737
00738 #define COIN_OWN_RANDOM_32
00739
00740 #if defined COIN_OWN_RANDOM_32
00741
00742
00743
00744
00745
00746
00747
00749 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00750 {
00751 static unsigned int last = 123456;
00752 if (isSeed) {
00753 last = seed;
00754 } else {
00755 last = 1664525*last+1013904223;
00756 return ((static_cast<double> (last))/4294967296.0);
00757 }
00758 return(0.0);
00759 }
00761 inline void CoinSeedRandom(int iseed)
00762 {
00763 CoinDrand48(true, iseed);
00764 }
00765
00766 #else // COIN_OWN_RANDOM_32
00767
00768 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00769
00770 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00771 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00772
00773 #else
00774
00775 inline double CoinDrand48() { return drand48(); }
00776 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00777
00778 #endif
00779
00780 #endif // COIN_OWN_RANDOM_32
00781
00782
00783
00786 inline char CoinFindDirSeparator()
00787 {
00788 int size = 1000;
00789 char* buf = 0;
00790 while (true) {
00791 buf = new char[size];
00792 if (getcwd(buf, size))
00793 break;
00794 delete[] buf;
00795 buf = 0;
00796 size = 2*size;
00797 }
00798
00799
00800 char dirsep = buf[0] == '/' ? '/' : '\\';
00801 delete[] buf;
00802 return dirsep;
00803 }
00804
00805
00806 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00807 const size_t len)
00808 {
00809 for (size_t i = 0; i < len; ++i) {
00810 if (s0[i] == 0) {
00811 return s1[i] == 0 ? 0 : -1;
00812 }
00813 if (s1[i] == 0) {
00814 return 1;
00815 }
00816 const int c0 = tolower(s0[i]);
00817 const int c1 = tolower(s1[i]);
00818 if (c0 < c1)
00819 return -1;
00820 if (c0 > c1)
00821 return 1;
00822 }
00823 return 0;
00824 }
00825
00826
00827
00829 template <class T> inline void CoinSwap (T &x, T &y)
00830 {
00831 T t = x;
00832 x = y;
00833 y = t;
00834 }
00835
00836
00837
00842 template <class T> inline int
00843 CoinToFile( const T* array, CoinBigIndex size, FILE * fp)
00844 {
00845 CoinBigIndex numberWritten;
00846 if (array&&size) {
00847 numberWritten =
00848 static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp));
00849 if (numberWritten!=1)
00850 return 1;
00851 numberWritten =
00852 static_cast<CoinBigIndex>(fwrite(array,sizeof(T),size_t(size),fp));
00853 if (numberWritten!=size)
00854 return 1;
00855 } else {
00856 size = 0;
00857 numberWritten =
00858 static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp));
00859 if (numberWritten!=1)
00860 return 1;
00861 }
00862 return 0;
00863 }
00864
00865
00866
00873 template <class T> inline int
00874 CoinFromFile( T* &array, CoinBigIndex size, FILE * fp, CoinBigIndex & newSize)
00875 {
00876 CoinBigIndex numberRead;
00877 numberRead =
00878 static_cast<CoinBigIndex>(fread(&newSize,sizeof(int),1,fp));
00879 if (numberRead!=1)
00880 return 1;
00881 int returnCode=0;
00882 if (size!=newSize&&(newSize||array))
00883 returnCode=2;
00884 if (newSize) {
00885 array = new T [newSize];
00886 numberRead =
00887 static_cast<CoinBigIndex>(fread(array,sizeof(T),newSize,fp));
00888 if (numberRead!=newSize)
00889 returnCode=1;
00890 } else {
00891 array = NULL;
00892 }
00893 return returnCode;
00894 }
00895
00896
00897
00899 inline double CoinCbrt(double x)
00900 {
00901 #if defined(_MSC_VER)
00902 return pow(x,(1./3.));
00903 #else
00904 return cbrt(x);
00905 #endif
00906 }
00907
00908
00910 #define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type)))
00912 inline int
00913 CoinStrlenAsInt(const char * string)
00914 {
00915 return static_cast<int>(strlen(string));
00916 }
00917
00920 #if defined COIN_OWN_RANDOM_32
00921 class CoinThreadRandom {
00922 public:
00927 CoinThreadRandom()
00928 { seed_=12345678;}
00930 CoinThreadRandom(int seed)
00931 {
00932 seed_ = seed;
00933 }
00935 ~CoinThreadRandom() {}
00936
00937 CoinThreadRandom(const CoinThreadRandom & rhs)
00938 { seed_ = rhs.seed_;}
00939
00940 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00941 {
00942 if (this != &rhs) {
00943 seed_ = rhs.seed_;
00944 }
00945 return *this;
00946 }
00947
00949
00954 inline void setSeed(int seed)
00955 {
00956 seed_ = seed;
00957 }
00959 inline unsigned int getSeed() const
00960 {
00961 return seed_;
00962 }
00964 inline double randomDouble() const
00965 {
00966 double retVal;
00967 seed_ = 1664525*(seed_)+1013904223;
00968 retVal = ((static_cast<double> (seed_))/4294967296.0);
00969 return retVal;
00970 }
00972
00973
00974 protected:
00978
00979 mutable unsigned int seed_;
00981 };
00982 #else
00983 class CoinThreadRandom {
00984 public:
00989 CoinThreadRandom()
00990 { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00992 CoinThreadRandom(const unsigned short seed[3])
00993 { memcpy(seed_,seed,3*sizeof(unsigned short));}
00995 CoinThreadRandom(int seed)
00996 {
00997 union { int i[2]; unsigned short int s[4];} put;
00998 put.i[0]=seed;
00999 put.i[1]=seed;
01000 memcpy(seed_,put.s,3*sizeof(unsigned short));
01001 }
01003 ~CoinThreadRandom() {}
01004
01005 CoinThreadRandom(const CoinThreadRandom & rhs)
01006 { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
01007
01008 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
01009 {
01010 if (this != &rhs) {
01011 memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
01012 }
01013 return *this;
01014 }
01015
01017
01022 inline void setSeed(const unsigned short seed[3])
01023 { memcpy(seed_,seed,3*sizeof(unsigned short));}
01025 inline void setSeed(int seed)
01026 {
01027 union { int i[2]; unsigned short int s[4];} put;
01028 put.i[0]=seed;
01029 put.i[1]=seed;
01030 memcpy(seed_,put.s,3*sizeof(unsigned short));
01031 }
01033 inline double randomDouble() const
01034 {
01035 double retVal;
01036 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
01037 retVal=rand();
01038 retVal=retVal/(double) RAND_MAX;
01039 #else
01040 retVal = erand48(seed_);
01041 #endif
01042 return retVal;
01043 }
01045
01046
01047 protected:
01051
01052 mutable unsigned short seed_[3];
01054 };
01055 #endif
01056 #endif