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