/home/coin/SVN-release/CoinUtils-2.2.6/CoinUtils/src/CoinHelperFunctions.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
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         // Use Duff's device to copy
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         // Use Duff's device to copy
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     /* There is no point to do this test. If to and from are from different
00102        blocks then dist is undefined, so this can crash correct code. It's
00103        better to trust the user that the arrays are really disjoint. */
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         std::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         std::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         std::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       std::memcpy(arrayNew,array,size*sizeof(T));
00212     } else {
00213       std::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     // Use memcpy - seems a lot faster on Intel with gcc
00234 #ifndef NDEBUG
00235     // Some debug so check
00236     if (size < 0)
00237         throw CoinError("trying to copy negative number of entries",
00238                         "CoinMemcpyN", "");
00239   
00240 #if 0
00241     /* There is no point to do this test. If to and from are from different
00242        blocks then dist is undefined, so this can crash correct code. It's
00243        better to trust the user that the arrays are really disjoint. */
00244     const long dist = to - from;
00245     if (-size < dist && dist < size)
00246         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00247 #endif
00248 #endif
00249     std::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     /* There is no point to do this test. If to and from are from different
00260        blocks then dist is undefined, so this can crash correct code. It's
00261        better to trust the user that the arrays are really disjoint. */
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     // Use Duff's device to fill
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     // Use memset - seems faster on Intel with gcc
00387 #ifndef NDEBUG
00388     // Some debug so check
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     // Use Duff's device to fill
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 
00481 inline char * CoinStrdup(const char * name)
00482 {
00483   char* dup = NULL;
00484   if (name) {
00485     const int len = strlen(name);
00486     dup = (char*)malloc(len+1);
00487     CoinMemcpyN(name, len, dup);
00488     dup[len] = 0;
00489   }
00490   return dup;
00491 }
00492 
00493 //#############################################################################
00494 
00498 template <class T> inline T
00499 CoinMax(register const T x1, register const T x2)
00500 {
00501     return (x1 > x2) ? x1 : x2;
00502 }
00503 
00504 //-----------------------------------------------------------------------------
00505 
00509 template <class T> inline T
00510 CoinMin(register const T x1, register const T x2)
00511 {
00512     return (x1 < x2) ? x1 : x2;
00513 }
00514 
00515 //-----------------------------------------------------------------------------
00516 
00520 template <class T> inline T
00521 CoinAbs(const T value)
00522 {
00523     return value<0 ? -value : value;
00524 }
00525 
00526 //#############################################################################
00527 
00531 template <class T> inline bool
00532 CoinIsSorted(register const T* first, const int size)
00533 {
00534     if (size == 0)
00535         return true;
00536 
00537     if (size < 0)
00538         throw CoinError("negative number of entries", "CoinIsSorted", "");
00539 
00540 #if 1
00541     // size1 is the number of comparisons to be made
00542     const int size1 = size  - 1;
00543     for (register int n = size1 / 8; n > 0; --n, first += 8) {
00544         if (first[8] < first[7]) return false;
00545         if (first[7] < first[6]) return false;
00546         if (first[6] < first[5]) return false;
00547         if (first[5] < first[4]) return false;
00548         if (first[4] < first[3]) return false;
00549         if (first[3] < first[2]) return false;
00550         if (first[2] < first[1]) return false;
00551         if (first[1] < first[0]) return false;
00552     }
00553 
00554     switch (size1 % 8) {
00555     case 7: if (first[7] < first[6]) return false;
00556     case 6: if (first[6] < first[5]) return false;
00557     case 5: if (first[5] < first[4]) return false;
00558     case 4: if (first[4] < first[3]) return false;
00559     case 3: if (first[3] < first[2]) return false;
00560     case 2: if (first[2] < first[1]) return false;
00561     case 1: if (first[1] < first[0]) return false;
00562     case 0: break;
00563     }
00564 #else
00565     register const T* next = first;
00566     register const T* last = first + size;
00567     for (++next; next != last; first = next, ++next)
00568         if (*next < *first)
00569             return false;
00570 #endif   
00571     return true;
00572 }
00573 
00574 //-----------------------------------------------------------------------------
00575 
00579 template <class T> inline bool
00580 CoinIsSorted(register const T* first, register const T* last)
00581 {
00582     return CoinIsSorted(first, static_cast<int>(last - first));
00583 }
00584 
00585 //#############################################################################
00586 
00590 template <class T> inline void
00591 CoinIotaN(register T* first, const int size, register T init)
00592 {
00593     if (size == 0)
00594         return;
00595 
00596     if (size < 0)
00597         throw CoinError("negative number of entries", "CoinIotaN", "");
00598 
00599 #if 1
00600     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00601         first[0] = init;
00602         first[1] = init + 1;
00603         first[2] = init + 2;
00604         first[3] = init + 3;
00605         first[4] = init + 4;
00606         first[5] = init + 5;
00607         first[6] = init + 6;
00608         first[7] = init + 7;
00609     }
00610     switch (size % 8) {
00611     case 7: first[6] = init + 6;
00612     case 6: first[5] = init + 5;
00613     case 5: first[4] = init + 4;
00614     case 4: first[3] = init + 3;
00615     case 3: first[2] = init + 2;
00616     case 2: first[1] = init + 1;
00617     case 1: first[0] = init;
00618     case 0: break;
00619     }
00620 #else
00621     // Use Duff's device to fill
00622     register int n = (size + 7) / 8;
00623     --first;
00624     --init;
00625     switch (size % 8) {
00626     case 0: do{     *++first = ++init;
00627     case 7:         *++first = ++init;
00628     case 6:         *++first = ++init;
00629     case 5:         *++first = ++init;
00630     case 4:         *++first = ++init;
00631     case 3:         *++first = ++init;
00632     case 2:         *++first = ++init;
00633     case 1:         *++first = ++init;
00634     }while(--n>0);
00635     }
00636 #endif
00637 }
00638 
00639 //-----------------------------------------------------------------------------
00640 
00644 template <class T> inline void
00645 CoinIota(T* first, const T* last, T init)
00646 {
00647     CoinIotaN(first, last-first, init);
00648 }
00649 
00650 //#############################################################################
00651 
00657 template <class T> inline T *
00658 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00659                            const int * firstDelPos, const int * lastDelPos)
00660 {
00661     int delNum = lastDelPos - firstDelPos;
00662     if (delNum == 0)
00663         return arrayLast;
00664 
00665     if (delNum < 0)
00666         throw CoinError("trying to delete negative number of entries",
00667                         "CoinDeleteEntriesFromArray", "");
00668 
00669     int * delSortedPos = NULL;
00670     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00671            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00672         // the positions of the to be deleted is either not sorted or not unique
00673         delSortedPos = new int[delNum];
00674         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00675         std::sort(delSortedPos, delSortedPos + delNum);
00676         delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00677     }
00678     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00679 
00680     const int last = delNum - 1;
00681     int size = delSorted[0];
00682     for (int i = 0; i < last; ++i) {
00683         const int copyFirst = delSorted[i] + 1;
00684         const int copyLast = delSorted[i+1];
00685         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00686                  arrayFirst + size);
00687         size += copyLast - copyFirst;
00688     }
00689     const int copyFirst = delSorted[last] + 1;
00690     const int copyLast = arrayLast - arrayFirst;
00691     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00692              arrayFirst + size);
00693     size += copyLast - copyFirst;
00694 
00695     if (delSortedPos)
00696         delete[] delSortedPos;
00697 
00698     return arrayFirst + size;
00699 }
00700 
00701 //#############################################################################
00702 
00703 #define COIN_OWN_RANDOM_32
00704 
00705 #if defined COIN_OWN_RANDOM_32
00706 /* Thanks to Stefano Gliozzi for providing an operating system
00707    independent random number generator.  */
00708 
00709 // linear congruential generator. given the seed, the generated numbers are  
00710 // always the same regardless the (32 bit) architecture. This allows to 
00711 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
00712 // getting in most cases the same optimization path. 
00714 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00715 {
00716   static unsigned int last = 123456;
00717   if (isSeed) { 
00718     last = seed;
00719   } else {
00720     last = 1664525*last+1013904223;
00721     return (((double) last)/4294967296.0);
00722   }
00723   return(0.0);
00724 }
00726 inline void CoinSeedRandom(int iseed)
00727 {
00728   CoinDrand48(true, iseed);
00729 }
00730 
00731 #else // COIN_OWN_RANDOM_32
00732 
00733 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00734 
00735 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00736 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00737 
00738 #else
00739 
00740 inline double CoinDrand48() { return drand48(); }
00741 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00742 
00743 #endif
00744 
00745 #endif // COIN_OWN_RANDOM_32
00746 
00747 //#############################################################################
00748 
00751 inline char CoinFindDirSeparator()
00752 {
00753     int size = 1000;
00754     char* buf = 0;
00755     while (true) {
00756         buf = new char[size];
00757         if (getcwd(buf, size))
00758             break;
00759         delete[] buf;
00760         buf = 0;
00761         size = 2*size;
00762     }
00763     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we 
00764     // assume it's dos and the dirsep is '\'
00765     char dirsep = buf[0] == '/' ? '/' : '\\';
00766     delete[] buf;
00767     return dirsep;
00768 }
00769 //#############################################################################
00770 
00771 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00772                            const size_t len)
00773 {
00774     for (size_t i = 0; i < len; ++i) {
00775         if (s0[i] == 0) {
00776             return s1[i] == 0 ? 0 : -1;
00777         }
00778         if (s1[i] == 0) {
00779             return 1;
00780         }
00781         const int c0 = tolower(s0[i]);
00782         const int c1 = tolower(s1[i]);
00783         if (c0 < c1)
00784             return -1;
00785         if (c0 > c1)
00786             return 1;
00787     }
00788     return 0;
00789 }
00790 
00791 //#############################################################################
00792 
00794 template <class T> inline void CoinSwap (T &x, T &y)
00795 {
00796     T t = x;
00797     x = y;
00798     y = t;
00799 }
00800 
00801 //#############################################################################
00802 
00807 template <class T> inline int
00808 CoinToFile( const T* array, int size, FILE * fp)
00809 {
00810     int numberWritten;
00811     if (array&&size) {
00812         numberWritten = fwrite(&size,sizeof(int),1,fp);
00813         if (numberWritten!=1)
00814             return 1;
00815         numberWritten = fwrite(array,sizeof(T),size,fp);
00816         if (numberWritten!=size)
00817             return 1;
00818     } else {
00819         size = 0;
00820         numberWritten = fwrite(&size,sizeof(int),1,fp);
00821         if (numberWritten!=1)
00822             return 1;
00823     }
00824     return 0;
00825 }
00826 
00827 //#############################################################################
00828 
00835 template <class T> inline int
00836 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00837 {
00838     int numberRead;
00839     numberRead = fread(&newSize,sizeof(int),1,fp);
00840     if (numberRead!=1)
00841         return 1;
00842     int returnCode=0;
00843     if (size!=newSize&&(newSize||array))
00844         returnCode=2;
00845     if (newSize) {
00846         array = new T [newSize];
00847         numberRead = fread(array,sizeof(T),newSize,fp);
00848         if (numberRead!=newSize)
00849             returnCode=1;
00850     } else {
00851         array = NULL;
00852     }
00853     return returnCode;
00854 }
00855 
00856 //#############################################################################
00857 
00859 inline double CoinCbrt(double x)
00860 {
00861 #if defined(_MSC_VER) 
00862     return pow(x,(1./3.));
00863 #else
00864     return cbrt(x);
00865 #endif
00866 }
00869 #if defined COIN_OWN_RANDOM_32
00870 class CoinThreadRandom  {
00871 public:
00876   CoinThreadRandom()
00877   { seed_=12345678;}
00879   CoinThreadRandom(int seed)
00880   { 
00881     seed_ = seed;
00882   }
00884   ~CoinThreadRandom() {}
00885   // Copy
00886   CoinThreadRandom(const CoinThreadRandom & rhs)
00887   { seed_ = rhs.seed_;}
00888   // Assignment
00889   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00890   {
00891     if (this != &rhs) {
00892       seed_ = rhs.seed_;
00893     }
00894     return *this;
00895   }
00896 
00898   
00903   inline void setSeed(int seed)
00904   { 
00905     seed_ = seed;
00906   }
00908   inline double randomDouble() const
00909   {
00910     double retVal;
00911     seed_ = 1664525*(seed_)+1013904223;
00912     retVal = (((double) seed_)/4294967296.0);
00913     return retVal;
00914   }
00916   
00917   
00918 protected:
00922 
00923   mutable unsigned int seed_;
00925 };
00926 #else
00927 class CoinThreadRandom  {
00928 public:
00933   CoinThreadRandom()
00934   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00936   CoinThreadRandom(const unsigned short seed[3])
00937   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00939   CoinThreadRandom(int seed)
00940   { 
00941     union { int i[2]; unsigned short int s[4];} put;
00942     put.i[0]=seed;
00943     put.i[1]=seed;
00944     memcpy(seed_,put.s,3*sizeof(unsigned short));
00945   }
00947   ~CoinThreadRandom() {}
00948   // Copy
00949   CoinThreadRandom(const CoinThreadRandom & rhs)
00950   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00951   // Assignment
00952   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00953   {
00954     if (this != &rhs) {
00955       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
00956     }
00957     return *this;
00958   }
00959 
00961   
00966   inline void setSeed(const unsigned short seed[3])
00967   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00969   inline void setSeed(int seed)
00970   { 
00971     union { int i[2]; unsigned short int s[4];} put;
00972     put.i[0]=seed;
00973     put.i[1]=seed;
00974     memcpy(seed_,put.s,3*sizeof(unsigned short));
00975   }
00977   inline double randomDouble() const
00978   {
00979     double retVal;
00980 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00981     retVal=rand();
00982     retVal=retVal/(double) RAND_MAX;
00983 #else
00984     retVal = erand48(seed_);
00985 #endif
00986     return retVal;
00987   }
00989   
00990   
00991 protected:
00995 
00996   mutable unsigned short seed_[3];
00998 };
00999 #endif
01000 #endif

Generated on Thu Jul 17 03:00:30 2008 by  doxygen 1.4.7