/home/coin/SVN-release/CoinUtils-2.3.0/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         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||size) {
00174         T * arrayNew = new T[size];
00175         assert (copySize<=size);
00176         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         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         memcpy(arrayNew,array,size*sizeof(T));
00212     } else {
00213         memset(arrayNew,0,size*sizeof(T));
00214     }
00215     return arrayNew;
00216 }
00217 
00218 
00219 //-----------------------------------------------------------------------------
00220 
00228 #ifndef COIN_USE_RESTRICT
00229 template <class T> inline void
00230 CoinMemcpyN(register const T* from, const int size, register T* to)
00231 {
00232 #ifndef _MSC_VER
00233 #ifdef USE_MEMCPY
00234     // Use memcpy - seems a lot faster on Intel with gcc
00235 #ifndef NDEBUG
00236     // Some debug so check
00237     if (size < 0)
00238         throw CoinError("trying to copy negative number of entries",
00239                         "CoinMemcpyN", "");
00240   
00241 #if 0
00242     /* There is no point to do this test. If to and from are from different
00243        blocks then dist is undefined, so this can crash correct code. It's
00244        better to trust the user that the arrays are really disjoint. */
00245     const long dist = to - from;
00246     if (-size < dist && dist < size)
00247         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00248 #endif
00249 #endif
00250     memcpy(to,from,size*sizeof(T));
00251 #else
00252     if (size == 0 || from == to)
00253         return;
00254 
00255     if (size < 0)
00256         throw CoinError("trying to copy negative number of entries",
00257                         "CoinMemcpyN", "");
00258 
00259 #if 0
00260     /* There is no point to do this test. If to and from are from different
00261        blocks then dist is undefined, so this can crash correct code. It's
00262        better to trust the user that the arrays are really disjoint. */
00263     const long dist = to - from;
00264     if (-size < dist && dist < size)
00265         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00266 #endif
00267 
00268     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00269         to[0] = from[0];
00270         to[1] = from[1];
00271         to[2] = from[2];
00272         to[3] = from[3];
00273         to[4] = from[4];
00274         to[5] = from[5];
00275         to[6] = from[6];
00276         to[7] = from[7];
00277     }
00278     switch (size % 8) {
00279     case 7: to[6] = from[6];
00280     case 6: to[5] = from[5];
00281     case 5: to[4] = from[4];
00282     case 4: to[3] = from[3];
00283     case 3: to[2] = from[2];
00284     case 2: to[1] = from[1];
00285     case 1: to[0] = from[0];
00286     case 0: break;
00287     }
00288 #endif
00289 #else
00290     CoinCopyN(from, size, to);
00291 #endif
00292 }
00293 #else
00294 template <class T> inline void
00295 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
00296 {
00297   T * put = (T *) to;
00298   const T * get = (const T *) from;
00299   for ( ; 0<size ; --size)
00300     *put++ = *get++;
00301 }
00302 #endif
00303 
00304 //-----------------------------------------------------------------------------
00305 
00310 template <class T> inline void
00311 CoinMemcpy(register const T* first, register const T* last,
00312            register T* to)
00313 {
00314     CoinMemcpyN(first, static_cast<int>(last - first), to);
00315 }
00316 
00317 //#############################################################################
00318 
00325 template <class T> inline void
00326 CoinFillN(register T* to, const int size, register const T value)
00327 {
00328     if (size == 0)
00329         return;
00330 
00331     if (size < 0)
00332         throw CoinError("trying to fill negative number of entries",
00333                         "CoinFillN", "");
00334 
00335 #if 1
00336     for (register int n = size / 8; n > 0; --n, to += 8) {
00337         to[0] = value;
00338         to[1] = value;
00339         to[2] = value;
00340         to[3] = value;
00341         to[4] = value;
00342         to[5] = value;
00343         to[6] = value;
00344         to[7] = value;
00345     }
00346     switch (size % 8) {
00347     case 7: to[6] = value;
00348     case 6: to[5] = value;
00349     case 5: to[4] = value;
00350     case 4: to[3] = value;
00351     case 3: to[2] = value;
00352     case 2: to[1] = value;
00353     case 1: to[0] = value;
00354     case 0: break;
00355     }
00356 #else
00357     // Use Duff's device to fill
00358     register int n = (size + 7) / 8;
00359     --to;
00360     switch (size % 8) {
00361     case 0: do{     *++to = value;
00362     case 7:         *++to = value;
00363     case 6:         *++to = value;
00364     case 5:         *++to = value;
00365     case 4:         *++to = value;
00366     case 3:         *++to = value;
00367     case 2:         *++to = value;
00368     case 1:         *++to = value;
00369     }while(--n>0);
00370     }
00371 #endif
00372 }
00373 
00374 //-----------------------------------------------------------------------------
00375 
00379 template <class T> inline void
00380 CoinFill(register T* first, register T* last, const T value)
00381 {
00382     CoinFillN(first, last - first, value);
00383 }
00384 
00385 //#############################################################################
00386 
00393 template <class T> inline void
00394 CoinZeroN(register T* to, const int size)
00395 {
00396 #ifdef USE_MEMCPY
00397     // Use memset - seems faster on Intel with gcc
00398 #ifndef NDEBUG
00399     // Some debug so check
00400     if (size < 0)
00401         throw CoinError("trying to fill negative number of entries",
00402                         "CoinZeroN", "");
00403 #endif
00404     memset(to,0,size*sizeof(T));
00405 #else
00406     if (size == 0)
00407         return;
00408 
00409     if (size < 0)
00410         throw CoinError("trying to fill negative number of entries",
00411                         "CoinZeroN", "");
00412 #if 1
00413     for (register int n = size / 8; n > 0; --n, to += 8) {
00414         to[0] = 0;
00415         to[1] = 0;
00416         to[2] = 0;
00417         to[3] = 0;
00418         to[4] = 0;
00419         to[5] = 0;
00420         to[6] = 0;
00421         to[7] = 0;
00422     }
00423     switch (size % 8) {
00424     case 7: to[6] = 0;
00425     case 6: to[5] = 0;
00426     case 5: to[4] = 0;
00427     case 4: to[3] = 0;
00428     case 3: to[2] = 0;
00429     case 2: to[1] = 0;
00430     case 1: to[0] = 0;
00431     case 0: break;
00432     }
00433 #else
00434     // Use Duff's device to fill
00435     register int n = (size + 7) / 8;
00436     --to;
00437     switch (size % 8) {
00438     case 0: do{     *++to = 0;
00439     case 7:         *++to = 0;
00440     case 6:         *++to = 0;
00441     case 5:         *++to = 0;
00442     case 4:         *++to = 0;
00443     case 3:         *++to = 0;
00444     case 2:         *++to = 0;
00445     case 1:         *++to = 0;
00446     }while(--n>0);
00447     }
00448 #endif
00449 #endif
00450 }
00452 inline void
00453 CoinCheckDoubleZero(double * to, const int size)
00454 {
00455     int n=0;
00456     for (int j=0;j<size;j++) {
00457         if (to[j]) 
00458             n++;
00459     }
00460     if (n) {
00461         printf("array of length %d should be zero has %d nonzero\n",size,n);
00462     }
00463 }
00465 inline void
00466 CoinCheckIntZero(int * to, const int size)
00467 {
00468     int n=0;
00469     for (int j=0;j<size;j++) {
00470         if (to[j]) 
00471             n++;
00472     }
00473     if (n) {
00474         printf("array of length %d should be zero has %d nonzero\n",size,n);
00475     }
00476 }
00477 
00478 //-----------------------------------------------------------------------------
00479 
00483 template <class T> inline void
00484 CoinZero(register T* first, register T* last)
00485 {
00486     CoinZeroN(first, last - first);
00487 }
00488 
00489 //#############################################################################
00490 
00494 template <class T> inline T
00495 CoinMax(register const T x1, register const T x2)
00496 {
00497     return (x1 > x2) ? x1 : x2;
00498 }
00499 
00500 //-----------------------------------------------------------------------------
00501 
00505 template <class T> inline T
00506 CoinMin(register const T x1, register const T x2)
00507 {
00508     return (x1 < x2) ? x1 : x2;
00509 }
00510 
00511 //-----------------------------------------------------------------------------
00512 
00516 template <class T> inline T
00517 CoinAbs(const T value)
00518 {
00519     return value<0 ? -value : value;
00520 }
00521 
00522 //#############################################################################
00523 
00527 template <class T> inline bool
00528 CoinIsSorted(register const T* first, const int size)
00529 {
00530     if (size == 0)
00531         return true;
00532 
00533     if (size < 0)
00534         throw CoinError("negative number of entries", "CoinIsSorted", "");
00535 
00536 #if 1
00537     // size1 is the number of comparisons to be made
00538     const int size1 = size  - 1;
00539     for (register int n = size1 / 8; n > 0; --n, first += 8) {
00540         if (first[8] < first[7]) return false;
00541         if (first[7] < first[6]) return false;
00542         if (first[6] < first[5]) return false;
00543         if (first[5] < first[4]) return false;
00544         if (first[4] < first[3]) return false;
00545         if (first[3] < first[2]) return false;
00546         if (first[2] < first[1]) return false;
00547         if (first[1] < first[0]) return false;
00548     }
00549 
00550     switch (size1 % 8) {
00551     case 7: if (first[7] < first[6]) return false;
00552     case 6: if (first[6] < first[5]) return false;
00553     case 5: if (first[5] < first[4]) return false;
00554     case 4: if (first[4] < first[3]) return false;
00555     case 3: if (first[3] < first[2]) return false;
00556     case 2: if (first[2] < first[1]) return false;
00557     case 1: if (first[1] < first[0]) return false;
00558     case 0: break;
00559     }
00560 #else
00561     register const T* next = first;
00562     register const T* last = first + size;
00563     for (++next; next != last; first = next, ++next)
00564         if (*next < *first)
00565             return false;
00566 #endif   
00567     return true;
00568 }
00569 
00570 //-----------------------------------------------------------------------------
00571 
00575 template <class T> inline bool
00576 CoinIsSorted(register const T* first, register const T* last)
00577 {
00578     return CoinIsSorted(first, static_cast<int>(last - first));
00579 }
00580 
00581 //#############################################################################
00582 
00586 template <class T> inline void
00587 CoinIotaN(register T* first, const int size, register T init)
00588 {
00589     if (size == 0)
00590         return;
00591 
00592     if (size < 0)
00593         throw CoinError("negative number of entries", "CoinIotaN", "");
00594 
00595 #if 1
00596     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00597         first[0] = init;
00598         first[1] = init + 1;
00599         first[2] = init + 2;
00600         first[3] = init + 3;
00601         first[4] = init + 4;
00602         first[5] = init + 5;
00603         first[6] = init + 6;
00604         first[7] = init + 7;
00605     }
00606     switch (size % 8) {
00607     case 7: first[6] = init + 6;
00608     case 6: first[5] = init + 5;
00609     case 5: first[4] = init + 4;
00610     case 4: first[3] = init + 3;
00611     case 3: first[2] = init + 2;
00612     case 2: first[1] = init + 1;
00613     case 1: first[0] = init;
00614     case 0: break;
00615     }
00616 #else
00617     // Use Duff's device to fill
00618     register int n = (size + 7) / 8;
00619     --first;
00620     --init;
00621     switch (size % 8) {
00622     case 0: do{     *++first = ++init;
00623     case 7:         *++first = ++init;
00624     case 6:         *++first = ++init;
00625     case 5:         *++first = ++init;
00626     case 4:         *++first = ++init;
00627     case 3:         *++first = ++init;
00628     case 2:         *++first = ++init;
00629     case 1:         *++first = ++init;
00630     }while(--n>0);
00631     }
00632 #endif
00633 }
00634 
00635 //-----------------------------------------------------------------------------
00636 
00640 template <class T> inline void
00641 CoinIota(T* first, const T* last, T init)
00642 {
00643     CoinIotaN(first, last-first, init);
00644 }
00645 
00646 //#############################################################################
00647 
00653 template <class T> inline T *
00654 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00655                            const int * firstDelPos, const int * lastDelPos)
00656 {
00657     int delNum = lastDelPos - firstDelPos;
00658     if (delNum == 0)
00659         return arrayLast;
00660 
00661     if (delNum < 0)
00662         throw CoinError("trying to delete negative number of entries",
00663                         "CoinDeleteEntriesFromArray", "");
00664 
00665     int * delSortedPos = NULL;
00666     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00667            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00668         // the positions of the to be deleted is either not sorted or not unique
00669         delSortedPos = new int[delNum];
00670         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00671         std::sort(delSortedPos, delSortedPos + delNum);
00672         delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00673     }
00674     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00675 
00676     const int last = delNum - 1;
00677     int size = delSorted[0];
00678     for (int i = 0; i < last; ++i) {
00679         const int copyFirst = delSorted[i] + 1;
00680         const int copyLast = delSorted[i+1];
00681         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00682                  arrayFirst + size);
00683         size += copyLast - copyFirst;
00684     }
00685     const int copyFirst = delSorted[last] + 1;
00686     const int copyLast = arrayLast - arrayFirst;
00687     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00688              arrayFirst + size);
00689     size += copyLast - copyFirst;
00690 
00691     if (delSortedPos)
00692         delete[] delSortedPos;
00693 
00694     return arrayFirst + size;
00695 }
00696 
00697 //#############################################################################
00698 
00699 #define COIN_OWN_RANDOM_32
00700 
00701 #if defined COIN_OWN_RANDOM_32
00702 /* Thanks to Stefano Gliozzi for providing an operating system
00703    independent random number generator.  */
00704 
00705 // linear congruential generator. given the seed, the generated numbers are  
00706 // always the same regardless the (32 bit) architecture. This allows to 
00707 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
00708 // getting in most cases the same optimization path. 
00710 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00711 {
00712   static unsigned int last = 123456;
00713   if (isSeed) { 
00714     last = seed;
00715   } else {
00716     last = 1664525*last+1013904223;
00717     return (((double) last)/4294967296.0);
00718   }
00719   return(0.0);
00720 }
00722 inline void CoinSeedRandom(int iseed)
00723 {
00724   CoinDrand48(true, iseed);
00725 }
00726 
00727 #else // COIN_OWN_RANDOM_32
00728 
00729 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00730 
00731 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00732 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00733 
00734 #else
00735 
00736 inline double CoinDrand48() { return drand48(); }
00737 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00738 
00739 #endif
00740 
00741 #endif // COIN_OWN_RANDOM_32
00742 
00743 //#############################################################################
00744 
00747 inline char CoinFindDirSeparator()
00748 {
00749     int size = 1000;
00750     char* buf = 0;
00751     while (true) {
00752         buf = new char[size];
00753         if (getcwd(buf, size))
00754             break;
00755         delete[] buf;
00756         buf = 0;
00757         size = 2*size;
00758     }
00759     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we 
00760     // assume it's dos and the dirsep is '\'
00761     char dirsep = buf[0] == '/' ? '/' : '\\';
00762     delete[] buf;
00763     return dirsep;
00764 }
00765 //#############################################################################
00766 
00767 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00768                            const size_t len)
00769 {
00770     for (size_t i = 0; i < len; ++i) {
00771         if (s0[i] == 0) {
00772             return s1[i] == 0 ? 0 : -1;
00773         }
00774         if (s1[i] == 0) {
00775             return 1;
00776         }
00777         const int c0 = tolower(s0[i]);
00778         const int c1 = tolower(s1[i]);
00779         if (c0 < c1)
00780             return -1;
00781         if (c0 > c1)
00782             return 1;
00783     }
00784     return 0;
00785 }
00786 
00787 //#############################################################################
00788 
00790 template <class T> inline void CoinSwap (T &x, T &y)
00791 {
00792     T t = x;
00793     x = y;
00794     y = t;
00795 }
00796 
00797 //#############################################################################
00798 
00803 template <class T> inline int
00804 CoinToFile( const T* array, int size, FILE * fp)
00805 {
00806     int numberWritten;
00807     if (array&&size) {
00808         numberWritten = fwrite(&size,sizeof(int),1,fp);
00809         if (numberWritten!=1)
00810             return 1;
00811         numberWritten = fwrite(array,sizeof(T),size,fp);
00812         if (numberWritten!=size)
00813             return 1;
00814     } else {
00815         size = 0;
00816         numberWritten = fwrite(&size,sizeof(int),1,fp);
00817         if (numberWritten!=1)
00818             return 1;
00819     }
00820     return 0;
00821 }
00822 
00823 //#############################################################################
00824 
00831 template <class T> inline int
00832 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00833 {
00834     int numberRead;
00835     numberRead = fread(&newSize,sizeof(int),1,fp);
00836     if (numberRead!=1)
00837         return 1;
00838     int returnCode=0;
00839     if (size!=newSize&&(newSize||array))
00840         returnCode=2;
00841     if (newSize) {
00842         array = new T [newSize];
00843         numberRead = fread(array,sizeof(T),newSize,fp);
00844         if (numberRead!=newSize)
00845             returnCode=1;
00846     } else {
00847         array = NULL;
00848     }
00849     return returnCode;
00850 }
00851 
00852 //#############################################################################
00853 
00855 inline double CoinCbrt(double x)
00856 {
00857 #if defined(_MSC_VER) 
00858     return pow(x,(1./3.));
00859 #else
00860     return cbrt(x);
00861 #endif
00862 }
00865 #if defined COIN_OWN_RANDOM_32
00866 class CoinThreadRandom  {
00867 public:
00872   CoinThreadRandom()
00873   { seed_=12345678;}
00875   CoinThreadRandom(int seed)
00876   { 
00877     seed_ = seed;
00878   }
00880   ~CoinThreadRandom() {}
00881   // Copy
00882   CoinThreadRandom(const CoinThreadRandom & rhs)
00883   { seed_ = rhs.seed_;}
00884   // Assignment
00885   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00886   {
00887     if (this != &rhs) {
00888       seed_ = rhs.seed_;
00889     }
00890     return *this;
00891   }
00892 
00894   
00899   inline void setSeed(int seed)
00900   { 
00901     seed_ = seed;
00902   }
00904   inline double randomDouble() const
00905   {
00906     double retVal;
00907     seed_ = 1664525*(seed_)+1013904223;
00908     retVal = (((double) seed_)/4294967296.0);
00909     return retVal;
00910   }
00912   
00913   
00914 protected:
00918 
00919   mutable unsigned int seed_;
00921 };
00922 #else
00923 class CoinThreadRandom  {
00924 public:
00929   CoinThreadRandom()
00930   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00932   CoinThreadRandom(const unsigned short seed[3])
00933   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00935   CoinThreadRandom(int seed)
00936   { 
00937     union { int i[2]; unsigned short int s[4];} put;
00938     put.i[0]=seed;
00939     put.i[1]=seed;
00940     memcpy(seed_,put.s,3*sizeof(unsigned short));
00941   }
00943   ~CoinThreadRandom() {}
00944   // Copy
00945   CoinThreadRandom(const CoinThreadRandom & rhs)
00946   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00947   // Assignment
00948   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00949   {
00950     if (this != &rhs) {
00951       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
00952     }
00953     return *this;
00954   }
00955 
00957   
00962   inline void setSeed(const unsigned short seed[3])
00963   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00965   inline void setSeed(int seed)
00966   { 
00967     union { int i[2]; unsigned short int s[4];} put;
00968     put.i[0]=seed;
00969     put.i[1]=seed;
00970     memcpy(seed_,put.s,3*sizeof(unsigned short));
00971   }
00973   inline double randomDouble() const
00974   {
00975     double retVal;
00976 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00977     retVal=rand();
00978     retVal=retVal/(double) RAND_MAX;
00979 #else
00980     retVal = erand48(seed_);
00981 #endif
00982     return retVal;
00983   }
00985   
00986   
00987 protected:
00991 
00992   mutable unsigned short seed_[3];
00994 };
00995 #endif
00996 #endif

Generated on Fri Jul 4 03:00:36 2008 by  doxygen 1.4.7