00001
00002
00003
00004
00005
00006 #ifndef CoinHelperFunctions_H
00007 #define CoinHelperFunctions_H
00008
00009 #include "CoinUtilsConfig.h"
00010
00011 #if defined(_MSC_VER)
00012 # include <direct.h>
00013 # include <cctype>
00014 # define getcwd _getcwd
00015 # include <cctype>
00016 #else
00017 # include <unistd.h>
00018 #endif
00019
00020
00021 #include <cstdlib>
00022 #include <cstdio>
00023 #include <algorithm>
00024 #include "CoinTypes.hpp"
00025 #include "CoinError.hpp"
00026
00027
00028 #ifndef COIN_RESTRICT
00029 #ifdef COIN_USE_RESTRICT
00030 #define COIN_RESTRICT __restrict
00031 #else
00032 #define COIN_RESTRICT
00033 #endif
00034 #endif
00035
00036
00037
00043 template <class T> inline void
00044 CoinCopyN(register const T* from, const int size, register T* to)
00045 {
00046 if (size == 0 || from == to)
00047 return;
00048
00049 #ifndef NDEBUG
00050 if (size < 0)
00051 throw CoinError("trying to copy negative number of entries",
00052 "CoinCopyN", "");
00053 #endif
00054
00055 register int n = (size + 7) / 8;
00056 if (to > from) {
00057 register const T* downfrom = from + size;
00058 register T* downto = to + size;
00059
00060 switch (size % 8) {
00061 case 0: do{ *--downto = *--downfrom;
00062 case 7: *--downto = *--downfrom;
00063 case 6: *--downto = *--downfrom;
00064 case 5: *--downto = *--downfrom;
00065 case 4: *--downto = *--downfrom;
00066 case 3: *--downto = *--downfrom;
00067 case 2: *--downto = *--downfrom;
00068 case 1: *--downto = *--downfrom;
00069 }while(--n>0);
00070 }
00071 } else {
00072
00073 --from;
00074 --to;
00075 switch (size % 8) {
00076 case 0: do{ *++to = *++from;
00077 case 7: *++to = *++from;
00078 case 6: *++to = *++from;
00079 case 5: *++to = *++from;
00080 case 4: *++to = *++from;
00081 case 3: *++to = *++from;
00082 case 2: *++to = *++from;
00083 case 1: *++to = *++from;
00084 }while(--n>0);
00085 }
00086 }
00087 }
00088
00089
00090
00101 template <class T> inline void
00102 CoinCopy(register const T* first, register const T* last, register T* to)
00103 {
00104 CoinCopyN(first, static_cast<int>(last-first), to);
00105 }
00106
00107
00108
00116 template <class T> inline void
00117 CoinDisjointCopyN(register const T* from, const int size, register T* to)
00118 {
00119 #ifndef _MSC_VER
00120 if (size == 0 || from == to)
00121 return;
00122
00123 #ifndef NDEBUG
00124 if (size < 0)
00125 throw CoinError("trying to copy negative number of entries",
00126 "CoinDisjointCopyN", "");
00127 #endif
00128
00129 #if 0
00130
00131
00132
00133 const long dist = to - from;
00134 if (-size < dist && dist < size)
00135 throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
00136 #endif
00137
00138 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00139 to[0] = from[0];
00140 to[1] = from[1];
00141 to[2] = from[2];
00142 to[3] = from[3];
00143 to[4] = from[4];
00144 to[5] = from[5];
00145 to[6] = from[6];
00146 to[7] = from[7];
00147 }
00148 switch (size % 8) {
00149 case 7: to[6] = from[6];
00150 case 6: to[5] = from[5];
00151 case 5: to[4] = from[4];
00152 case 4: to[3] = from[3];
00153 case 3: to[2] = from[2];
00154 case 2: to[1] = from[1];
00155 case 1: to[0] = from[0];
00156 case 0: break;
00157 }
00158 #else
00159 CoinCopyN(from, size, to);
00160 #endif
00161 }
00162
00163
00164
00169 template <class T> inline void
00170 CoinDisjointCopy(register const T* first, register const T* last,
00171 register T* to)
00172 {
00173 CoinDisjointCopyN(first, static_cast<int>(last - first), to);
00174 }
00175
00176
00177
00182 template <class T> inline T*
00183 CoinCopyOfArray( const T * array, const int size)
00184 {
00185 if (array) {
00186 T * arrayNew = new T[size];
00187 std::memcpy(arrayNew,array,size*sizeof(T));
00188 return arrayNew;
00189 } else {
00190 return NULL;
00191 }
00192 }
00193
00194
00199 template <class T> inline T*
00200 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
00201 {
00202 if (array||size) {
00203 T * arrayNew = new T[size];
00204 assert (copySize<=size);
00205 std::memcpy(arrayNew,array,copySize*sizeof(T));
00206 return arrayNew;
00207 } else {
00208 return NULL;
00209 }
00210 }
00211
00216 template <class T> inline T*
00217 CoinCopyOfArray( const T * array, const int size, T value)
00218 {
00219 T * arrayNew = new T[size];
00220 if (array) {
00221 std::memcpy(arrayNew,array,size*sizeof(T));
00222 } else {
00223 int i;
00224 for (i=0;i<size;i++)
00225 arrayNew[i] = value;
00226 }
00227 return arrayNew;
00228 }
00229
00230
00235 template <class T> inline T*
00236 CoinCopyOfArrayOrZero( const T * array , const int size)
00237 {
00238 T * arrayNew = new T[size];
00239 if (array) {
00240 std::memcpy(arrayNew,array,size*sizeof(T));
00241 } else {
00242 std::memset(arrayNew,0,size*sizeof(T));
00243 }
00244 return arrayNew;
00245 }
00246
00247
00248
00249
00257 #ifndef COIN_USE_RESTRICT
00258 template <class T> inline void
00259 CoinMemcpyN(register const T* from, const int size, register T* to)
00260 {
00261 #ifndef _MSC_VER
00262 #ifdef USE_MEMCPY
00263
00264 #ifndef NDEBUG
00265
00266 if (size < 0)
00267 throw CoinError("trying to copy negative number of entries",
00268 "CoinMemcpyN", "");
00269
00270 #if 0
00271
00272
00273
00274 const long dist = to - from;
00275 if (-size < dist && dist < size)
00276 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00277 #endif
00278 #endif
00279 std::memcpy(to,from,size*sizeof(T));
00280 #else
00281 if (size == 0 || from == to)
00282 return;
00283
00284 #ifndef NDEBUG
00285 if (size < 0)
00286 throw CoinError("trying to copy negative number of entries",
00287 "CoinMemcpyN", "");
00288 #endif
00289
00290 #if 0
00291
00292
00293
00294 const long dist = to - from;
00295 if (-size < dist && dist < size)
00296 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00297 #endif
00298
00299 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00300 to[0] = from[0];
00301 to[1] = from[1];
00302 to[2] = from[2];
00303 to[3] = from[3];
00304 to[4] = from[4];
00305 to[5] = from[5];
00306 to[6] = from[6];
00307 to[7] = from[7];
00308 }
00309 switch (size % 8) {
00310 case 7: to[6] = from[6];
00311 case 6: to[5] = from[5];
00312 case 5: to[4] = from[4];
00313 case 4: to[3] = from[3];
00314 case 3: to[2] = from[2];
00315 case 2: to[1] = from[1];
00316 case 1: to[0] = from[0];
00317 case 0: break;
00318 }
00319 #endif
00320 #else
00321 CoinCopyN(from, size, to);
00322 #endif
00323 }
00324 #else
00325 template <class T> inline void
00326 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
00327 {
00328 #ifdef USE_MEMCPY
00329 std::memcpy(to,from,size*sizeof(T));
00330 #else
00331 T * COIN_RESTRICT put = to;
00332 const T * COIN_RESTRICT get = from;
00333 for ( ; 0<size ; --size)
00334 *put++ = *get++;
00335 #endif
00336 }
00337 #endif
00338
00339
00340
00345 template <class T> inline void
00346 CoinMemcpy(register const T* first, register const T* last,
00347 register T* to)
00348 {
00349 CoinMemcpyN(first, static_cast<int>(last - first), to);
00350 }
00351
00352
00353
00360 template <class T> inline void
00361 CoinFillN(register T* to, const int size, register const T value)
00362 {
00363 if (size == 0)
00364 return;
00365
00366 #ifndef NDEBUG
00367 if (size < 0)
00368 throw CoinError("trying to fill negative number of entries",
00369 "CoinFillN", "");
00370 #endif
00371 #if 1
00372 for (register int n = size / 8; n > 0; --n, to += 8) {
00373 to[0] = value;
00374 to[1] = value;
00375 to[2] = value;
00376 to[3] = value;
00377 to[4] = value;
00378 to[5] = value;
00379 to[6] = value;
00380 to[7] = value;
00381 }
00382 switch (size % 8) {
00383 case 7: to[6] = value;
00384 case 6: to[5] = value;
00385 case 5: to[4] = value;
00386 case 4: to[3] = value;
00387 case 3: to[2] = value;
00388 case 2: to[1] = value;
00389 case 1: to[0] = value;
00390 case 0: break;
00391 }
00392 #else
00393
00394 register int n = (size + 7) / 8;
00395 --to;
00396 switch (size % 8) {
00397 case 0: do{ *++to = value;
00398 case 7: *++to = value;
00399 case 6: *++to = value;
00400 case 5: *++to = value;
00401 case 4: *++to = value;
00402 case 3: *++to = value;
00403 case 2: *++to = value;
00404 case 1: *++to = value;
00405 }while(--n>0);
00406 }
00407 #endif
00408 }
00409
00410
00411
00415 template <class T> inline void
00416 CoinFill(register T* first, register T* last, const T value)
00417 {
00418 CoinFillN(first, last - first, value);
00419 }
00420
00421
00422
00429 template <class T> inline void
00430 CoinZeroN(register T* to, const int size)
00431 {
00432 #ifdef USE_MEMCPY
00433
00434 #ifndef NDEBUG
00435
00436 if (size < 0)
00437 throw CoinError("trying to fill negative number of entries",
00438 "CoinZeroN", "");
00439 #endif
00440 memset(to,0,size*sizeof(T));
00441 #else
00442 if (size == 0)
00443 return;
00444
00445 #ifndef NDEBUG
00446 if (size < 0)
00447 throw CoinError("trying to fill negative number of entries",
00448 "CoinZeroN", "");
00449 #endif
00450 #if 1
00451 for (register int n = size / 8; n > 0; --n, to += 8) {
00452 to[0] = 0;
00453 to[1] = 0;
00454 to[2] = 0;
00455 to[3] = 0;
00456 to[4] = 0;
00457 to[5] = 0;
00458 to[6] = 0;
00459 to[7] = 0;
00460 }
00461 switch (size % 8) {
00462 case 7: to[6] = 0;
00463 case 6: to[5] = 0;
00464 case 5: to[4] = 0;
00465 case 4: to[3] = 0;
00466 case 3: to[2] = 0;
00467 case 2: to[1] = 0;
00468 case 1: to[0] = 0;
00469 case 0: break;
00470 }
00471 #else
00472
00473 register int n = (size + 7) / 8;
00474 --to;
00475 switch (size % 8) {
00476 case 0: do{ *++to = 0;
00477 case 7: *++to = 0;
00478 case 6: *++to = 0;
00479 case 5: *++to = 0;
00480 case 4: *++to = 0;
00481 case 3: *++to = 0;
00482 case 2: *++to = 0;
00483 case 1: *++to = 0;
00484 }while(--n>0);
00485 }
00486 #endif
00487 #endif
00488 }
00490 inline void
00491 CoinCheckDoubleZero(double * to, const int size)
00492 {
00493 int n=0;
00494 for (int j=0;j<size;j++) {
00495 if (to[j])
00496 n++;
00497 }
00498 if (n) {
00499 printf("array of length %d should be zero has %d nonzero\n",size,n);
00500 }
00501 }
00503 inline void
00504 CoinCheckIntZero(int * to, const int size)
00505 {
00506 int n=0;
00507 for (int j=0;j<size;j++) {
00508 if (to[j])
00509 n++;
00510 }
00511 if (n) {
00512 printf("array of length %d should be zero has %d nonzero\n",size,n);
00513 }
00514 }
00515
00516
00517
00521 template <class T> inline void
00522 CoinZero(register T* first, register T* last)
00523 {
00524 CoinZeroN(first, last - first);
00525 }
00526
00527
00528
00530 inline char * CoinStrdup(const char * name)
00531 {
00532 char* dup = NULL;
00533 if (name) {
00534 const int len = static_cast<int>(strlen(name));
00535 dup = static_cast<char*>(malloc(len+1));
00536 CoinMemcpyN(name, len, dup);
00537 dup[len] = 0;
00538 }
00539 return dup;
00540 }
00541
00542
00543
00547 template <class T> inline T
00548 CoinMax(register const T x1, register const T x2)
00549 {
00550 return (x1 > x2) ? x1 : x2;
00551 }
00552
00553
00554
00558 template <class T> inline T
00559 CoinMin(register const T x1, register const T x2)
00560 {
00561 return (x1 < x2) ? x1 : x2;
00562 }
00563
00564
00565
00569 template <class T> inline T
00570 CoinAbs(const T value)
00571 {
00572 return value<0 ? -value : value;
00573 }
00574
00575
00576
00580 template <class T> inline bool
00581 CoinIsSorted(register const T* first, const int size)
00582 {
00583 if (size == 0)
00584 return true;
00585
00586 #ifndef NDEBUG
00587 if (size < 0)
00588 throw CoinError("negative number of entries", "CoinIsSorted", "");
00589 #endif
00590 #if 1
00591
00592 const int size1 = size - 1;
00593 for (register int n = size1 / 8; n > 0; --n, first += 8) {
00594 if (first[8] < first[7]) return false;
00595 if (first[7] < first[6]) return false;
00596 if (first[6] < first[5]) return false;
00597 if (first[5] < first[4]) return false;
00598 if (first[4] < first[3]) return false;
00599 if (first[3] < first[2]) return false;
00600 if (first[2] < first[1]) return false;
00601 if (first[1] < first[0]) return false;
00602 }
00603
00604 switch (size1 % 8) {
00605 case 7: if (first[7] < first[6]) return false;
00606 case 6: if (first[6] < first[5]) return false;
00607 case 5: if (first[5] < first[4]) return false;
00608 case 4: if (first[4] < first[3]) return false;
00609 case 3: if (first[3] < first[2]) return false;
00610 case 2: if (first[2] < first[1]) return false;
00611 case 1: if (first[1] < first[0]) return false;
00612 case 0: break;
00613 }
00614 #else
00615 register const T* next = first;
00616 register const T* last = first + size;
00617 for (++next; next != last; first = next, ++next)
00618 if (*next < *first)
00619 return false;
00620 #endif
00621 return true;
00622 }
00623
00624
00625
00629 template <class T> inline bool
00630 CoinIsSorted(register const T* first, register const T* last)
00631 {
00632 return CoinIsSorted(first, static_cast<int>(last - first));
00633 }
00634
00635
00636
00640 template <class T> inline void
00641 CoinIotaN(register T* first, const int size, register T init)
00642 {
00643 if (size == 0)
00644 return;
00645
00646 #ifndef NDEBUG
00647 if (size < 0)
00648 throw CoinError("negative number of entries", "CoinIotaN", "");
00649 #endif
00650 #if 1
00651 for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00652 first[0] = init;
00653 first[1] = init + 1;
00654 first[2] = init + 2;
00655 first[3] = init + 3;
00656 first[4] = init + 4;
00657 first[5] = init + 5;
00658 first[6] = init + 6;
00659 first[7] = init + 7;
00660 }
00661 switch (size % 8) {
00662 case 7: first[6] = init + 6;
00663 case 6: first[5] = init + 5;
00664 case 5: first[4] = init + 4;
00665 case 4: first[3] = init + 3;
00666 case 3: first[2] = init + 2;
00667 case 2: first[1] = init + 1;
00668 case 1: first[0] = init;
00669 case 0: break;
00670 }
00671 #else
00672
00673 register int n = (size + 7) / 8;
00674 --first;
00675 --init;
00676 switch (size % 8) {
00677 case 0: do{ *++first = ++init;
00678 case 7: *++first = ++init;
00679 case 6: *++first = ++init;
00680 case 5: *++first = ++init;
00681 case 4: *++first = ++init;
00682 case 3: *++first = ++init;
00683 case 2: *++first = ++init;
00684 case 1: *++first = ++init;
00685 }while(--n>0);
00686 }
00687 #endif
00688 }
00689
00690
00691
00695 template <class T> inline void
00696 CoinIota(T* first, const T* last, T init)
00697 {
00698 CoinIotaN(first, last-first, init);
00699 }
00700
00701
00702
00708 template <class T> inline T *
00709 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00710 const int * firstDelPos, const int * lastDelPos)
00711 {
00712 int delNum = static_cast<int>(lastDelPos - firstDelPos);
00713 if (delNum == 0)
00714 return arrayLast;
00715
00716 if (delNum < 0)
00717 throw CoinError("trying to delete negative number of entries",
00718 "CoinDeleteEntriesFromArray", "");
00719
00720 int * delSortedPos = NULL;
00721 if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00722 std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00723
00724 delSortedPos = new int[delNum];
00725 CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00726 std::sort(delSortedPos, delSortedPos + delNum);
00727 delNum = static_cast<int>(std::unique(delSortedPos,
00728 delSortedPos+delNum) - delSortedPos);
00729 }
00730 const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00731
00732 const int last = delNum - 1;
00733 int size = delSorted[0];
00734 for (int i = 0; i < last; ++i) {
00735 const int copyFirst = delSorted[i] + 1;
00736 const int copyLast = delSorted[i+1];
00737 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00738 arrayFirst + size);
00739 size += copyLast - copyFirst;
00740 }
00741 const int copyFirst = delSorted[last] + 1;
00742 const int copyLast = static_cast<int>(arrayLast - arrayFirst);
00743 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00744 arrayFirst + size);
00745 size += copyLast - copyFirst;
00746
00747 if (delSortedPos)
00748 delete[] delSortedPos;
00749
00750 return arrayFirst + size;
00751 }
00752
00753
00754
00755 #define COIN_OWN_RANDOM_32
00756
00757 #if defined COIN_OWN_RANDOM_32
00758
00759
00760
00773 inline double CoinDrand48 (bool isSeed = false, unsigned int seed = 1)
00774 {
00775 static unsigned int last = 123456;
00776 if (isSeed) {
00777 last = seed;
00778 } else {
00779 last = 1664525*last+1013904223;
00780 return ((static_cast<double> (last))/4294967296.0);
00781 }
00782 return (0.0);
00783 }
00784
00786 inline void CoinSeedRandom(int iseed)
00787 {
00788 CoinDrand48(true, iseed);
00789 }
00790
00791 #else // COIN_OWN_RANDOM_32
00792
00793 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00794
00796 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00798 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00799
00800 #else
00801
00803 inline double CoinDrand48() { return drand48(); }
00805 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00806
00807 #endif
00808
00809 #endif // COIN_OWN_RANDOM_32
00810
00811
00812
00815 inline char CoinFindDirSeparator()
00816 {
00817 int size = 1000;
00818 char* buf = 0;
00819 while (true) {
00820 buf = new char[size];
00821 if (getcwd(buf, size))
00822 break;
00823 delete[] buf;
00824 buf = 0;
00825 size = 2*size;
00826 }
00827
00828
00829 char dirsep = buf[0] == '/' ? '/' : '\\';
00830 delete[] buf;
00831 return dirsep;
00832 }
00833
00834
00835 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00836 const size_t len)
00837 {
00838 for (size_t i = 0; i < len; ++i) {
00839 if (s0[i] == 0) {
00840 return s1[i] == 0 ? 0 : -1;
00841 }
00842 if (s1[i] == 0) {
00843 return 1;
00844 }
00845 const int c0 = std::tolower(s0[i]);
00846 const int c1 = std::tolower(s1[i]);
00847 if (c0 < c1)
00848 return -1;
00849 if (c0 > c1)
00850 return 1;
00851 }
00852 return 0;
00853 }
00854
00855
00856
00858 template <class T> inline void CoinSwap (T &x, T &y)
00859 {
00860 T t = x;
00861 x = y;
00862 y = t;
00863 }
00864
00865
00866
00871 template <class T> inline int
00872 CoinToFile( const T* array, CoinBigIndex size, FILE * fp)
00873 {
00874 CoinBigIndex numberWritten;
00875 if (array&&size) {
00876 numberWritten =
00877 static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp));
00878 if (numberWritten!=1)
00879 return 1;
00880 numberWritten =
00881 static_cast<CoinBigIndex>(fwrite(array,sizeof(T),size_t(size),fp));
00882 if (numberWritten!=size)
00883 return 1;
00884 } else {
00885 size = 0;
00886 numberWritten =
00887 static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp));
00888 if (numberWritten!=1)
00889 return 1;
00890 }
00891 return 0;
00892 }
00893
00894
00895
00902 template <class T> inline int
00903 CoinFromFile( T* &array, CoinBigIndex size, FILE * fp, CoinBigIndex & newSize)
00904 {
00905 CoinBigIndex numberRead;
00906 numberRead =
00907 static_cast<CoinBigIndex>(fread(&newSize,sizeof(int),1,fp));
00908 if (numberRead!=1)
00909 return 1;
00910 int returnCode=0;
00911 if (size!=newSize&&(newSize||array))
00912 returnCode=2;
00913 if (newSize) {
00914 array = new T [newSize];
00915 numberRead =
00916 static_cast<CoinBigIndex>(fread(array,sizeof(T),newSize,fp));
00917 if (numberRead!=newSize)
00918 returnCode=1;
00919 } else {
00920 array = NULL;
00921 }
00922 return returnCode;
00923 }
00924
00925
00926
00928 #if 0
00929 inline double CoinCbrt(double x)
00930 {
00931 #if defined(_MSC_VER)
00932 return pow(x,(1./3.));
00933 #else
00934 return cbrt(x);
00935 #endif
00936 }
00937 #endif
00938
00939
00940
00942 #define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type)))
00944 inline int
00945 CoinStrlenAsInt(const char * string)
00946 {
00947 return static_cast<int>(strlen(string));
00948 }
00949
00952 #if defined COIN_OWN_RANDOM_32
00953 class CoinThreadRandom {
00954 public:
00959 CoinThreadRandom()
00960 { seed_=12345678;}
00962 CoinThreadRandom(int seed)
00963 {
00964 seed_ = seed;
00965 }
00967 ~CoinThreadRandom() {}
00968
00969 CoinThreadRandom(const CoinThreadRandom & rhs)
00970 { seed_ = rhs.seed_;}
00971
00972 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00973 {
00974 if (this != &rhs) {
00975 seed_ = rhs.seed_;
00976 }
00977 return *this;
00978 }
00979
00981
00986 inline void setSeed(int seed)
00987 {
00988 seed_ = seed;
00989 }
00991 inline unsigned int getSeed() const
00992 {
00993 return seed_;
00994 }
00996 inline double randomDouble() const
00997 {
00998 double retVal;
00999 seed_ = 1664525*(seed_)+1013904223;
01000 retVal = ((static_cast<double> (seed_))/4294967296.0);
01001 return retVal;
01002 }
01004 inline void randomize(int n=0)
01005 {
01006 if (!n)
01007 n=seed_ & 255;
01008 for (int i=0;i<n;i++)
01009 randomDouble();
01010 }
01012
01013
01014 protected:
01018
01019 mutable unsigned int seed_;
01021 };
01022 #else
01023 class CoinThreadRandom {
01024 public:
01029 CoinThreadRandom()
01030 { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
01032 CoinThreadRandom(const unsigned short seed[3])
01033 { memcpy(seed_,seed,3*sizeof(unsigned short));}
01035 CoinThreadRandom(int seed)
01036 {
01037 union { int i[2]; unsigned short int s[4];} put;
01038 put.i[0]=seed;
01039 put.i[1]=seed;
01040 memcpy(seed_,put.s,3*sizeof(unsigned short));
01041 }
01043 ~CoinThreadRandom() {}
01044
01045 CoinThreadRandom(const CoinThreadRandom & rhs)
01046 { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
01047
01048 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
01049 {
01050 if (this != &rhs) {
01051 memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
01052 }
01053 return *this;
01054 }
01055
01057
01062 inline void setSeed(const unsigned short seed[3])
01063 { memcpy(seed_,seed,3*sizeof(unsigned short));}
01065 inline void setSeed(int seed)
01066 {
01067 union { int i[2]; unsigned short int s[4];} put;
01068 put.i[0]=seed;
01069 put.i[1]=seed;
01070 memcpy(seed_,put.s,3*sizeof(unsigned short));
01071 }
01073 inline double randomDouble() const
01074 {
01075 double retVal;
01076 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
01077 retVal=rand();
01078 retVal=retVal/(double) RAND_MAX;
01079 #else
01080 retVal = erand48(seed_);
01081 #endif
01082 return retVal;
01083 }
01085 inline void randomize(int n=0)
01086 {
01087 if (!n) {
01088 n=seed_[0]+seed_[1]+seed_[2];
01089 n &= 255;
01090 }
01091 for (int i=0;i<n;i++)
01092 randomDouble();
01093 }
01095
01096
01097 protected:
01101
01102 mutable unsigned short seed_[3];
01104 };
01105 #endif
01106 #ifndef COIN_DETAIL
01107 #define COIN_DETAIL_PRINT(s) {}
01108 #else
01109 #define COIN_DETAIL_PRINT(s) s
01110 #endif
01111 #endif