• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

/build/buildd/coinutils-2.6.4/CoinUtils/src/CoinHelperFunctions.hpp

Go to the documentation of this file.
00001 /* $Id: CoinHelperFunctions.hpp 1240 2009-12-10 17:07:20Z ladanyi $ */
00002 // Copyright (C) 2000, International Business Machines
00003 // Corporation and others.  All Rights Reserved.
00004 
00005 #ifndef CoinHelperFunctions_H
00006 #define CoinHelperFunctions_H
00007 #if defined(_MSC_VER)
00008 #  include <direct.h>
00009 #  define getcwd _getcwd
00010 #else
00011 #  include <unistd.h>
00012 #endif
00013 //#define USE_MEMCPY
00014 
00015 #include <cstdlib>
00016 #include <cstdio>
00017 #include "CoinError.hpp"
00018 #include "CoinFinite.hpp"
00019 //#############################################################################
00020 
00026 template <class T> inline void
00027 CoinCopyN(register const T* from, const int size, register T* to)
00028 {
00029     if (size == 0 || from == to)
00030         return;
00031 
00032 #ifndef NDEBUG
00033     if (size < 0)
00034         throw CoinError("trying to copy negative number of entries",
00035                         "CoinCopyN", "");
00036 #endif
00037 
00038     register int n = (size + 7) / 8;
00039     if (to > from) {
00040         register const T* downfrom = from + size;
00041         register T* downto = to + size;
00042         // Use Duff's device to copy
00043         switch (size % 8) {
00044         case 0: do{     *--downto = *--downfrom;
00045         case 7:         *--downto = *--downfrom;
00046         case 6:         *--downto = *--downfrom;
00047         case 5:         *--downto = *--downfrom;
00048         case 4:         *--downto = *--downfrom;
00049         case 3:         *--downto = *--downfrom;
00050         case 2:         *--downto = *--downfrom;
00051         case 1:         *--downto = *--downfrom;
00052         }while(--n>0);
00053         }
00054     } else {
00055         // Use Duff's device to copy
00056         --from;
00057         --to;
00058         switch (size % 8) {
00059         case 0: do{     *++to = *++from;
00060         case 7:         *++to = *++from;
00061         case 6:         *++to = *++from;
00062         case 5:         *++to = *++from;
00063         case 4:         *++to = *++from;
00064         case 3:         *++to = *++from;
00065         case 2:         *++to = *++from;
00066         case 1:         *++to = *++from;
00067         }while(--n>0);
00068         }
00069     }
00070 }
00071 
00072 //-----------------------------------------------------------------------------
00073 
00078 template <class T> inline void
00079 CoinCopy(register const T* first, register const T* last, register T* to)
00080 {
00081     CoinCopyN(first, last - first, to);
00082 }
00083 
00084 //-----------------------------------------------------------------------------
00085 
00093 template <class T> inline void
00094 CoinDisjointCopyN(register const T* from, const int size, register T* to)
00095 {
00096 #ifndef _MSC_VER
00097     if (size == 0 || from == to)
00098         return;
00099 
00100 #ifndef NDEBUG
00101     if (size < 0)
00102         throw CoinError("trying to copy negative number of entries",
00103                         "CoinDisjointCopyN", "");
00104 #endif
00105 
00106 #if 0
00107     /* There is no point to do this test. If to and from are from different
00108        blocks then dist is undefined, so this can crash correct code. It's
00109        better to trust the user that the arrays are really disjoint. */
00110     const long dist = to - from;
00111     if (-size < dist && dist < size)
00112         throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
00113 #endif
00114 
00115     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00116         to[0] = from[0];
00117         to[1] = from[1];
00118         to[2] = from[2];
00119         to[3] = from[3];
00120         to[4] = from[4];
00121         to[5] = from[5];
00122         to[6] = from[6];
00123         to[7] = from[7];
00124     }
00125     switch (size % 8) {
00126     case 7: to[6] = from[6];
00127     case 6: to[5] = from[5];
00128     case 5: to[4] = from[4];
00129     case 4: to[3] = from[3];
00130     case 3: to[2] = from[2];
00131     case 2: to[1] = from[1];
00132     case 1: to[0] = from[0];
00133     case 0: break;
00134     }
00135 #else
00136     CoinCopyN(from, size, to);
00137 #endif
00138 }
00139 
00140 //-----------------------------------------------------------------------------
00141 
00146 template <class T> inline void
00147 CoinDisjointCopy(register const T* first, register const T* last,
00148                  register T* to)
00149 {
00150     CoinDisjointCopyN(first, static_cast<int>(last - first), to);
00151 }
00152 
00153 //-----------------------------------------------------------------------------
00154 
00159 template <class T> inline T*
00160 CoinCopyOfArray( const T * array, const int size)
00161 {
00162     if (array) {
00163         T * arrayNew = new T[size];
00164         std::memcpy(arrayNew,array,size*sizeof(T));
00165         return arrayNew;
00166     } else {
00167         return NULL;
00168     }
00169 }
00170 
00171 
00176 template <class T> inline T*
00177 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
00178 {
00179     if (array||size) {
00180         T * arrayNew = new T[size];
00181         assert (copySize<=size);
00182         std::memcpy(arrayNew,array,copySize*sizeof(T));
00183         return arrayNew;
00184     } else {
00185         return NULL;
00186     }
00187 }
00188 
00193 template <class T> inline T*
00194 CoinCopyOfArray( const T * array, const int size, T value)
00195 {
00196     T * arrayNew = new T[size];
00197     if (array) {
00198         std::memcpy(arrayNew,array,size*sizeof(T));
00199     } else {
00200         int i;
00201         for (i=0;i<size;i++) 
00202             arrayNew[i] = value;
00203     }
00204     return arrayNew;
00205 }
00206 
00207 
00212 template <class T> inline T*
00213 CoinCopyOfArrayOrZero( const T * array , const int size)
00214 {
00215     T * arrayNew = new T[size];
00216     if (array) {
00217       std::memcpy(arrayNew,array,size*sizeof(T));
00218     } else {
00219       std::memset(arrayNew,0,size*sizeof(T));
00220     }
00221     return arrayNew;
00222 }
00223 
00224 
00225 //-----------------------------------------------------------------------------
00226 
00234 #ifndef COIN_USE_RESTRICT
00235 template <class T> inline void
00236 CoinMemcpyN(register const T* from, const int size, register T* to)
00237 {
00238 #ifndef _MSC_VER
00239 #ifdef USE_MEMCPY
00240     // Use memcpy - seems a lot faster on Intel with gcc
00241 #ifndef NDEBUG
00242     // Some debug so check
00243     if (size < 0)
00244         throw CoinError("trying to copy negative number of entries",
00245                         "CoinMemcpyN", "");
00246   
00247 #if 0
00248     /* There is no point to do this test. If to and from are from different
00249        blocks then dist is undefined, so this can crash correct code. It's
00250        better to trust the user that the arrays are really disjoint. */
00251     const long dist = to - from;
00252     if (-size < dist && dist < size)
00253         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00254 #endif
00255 #endif
00256     std::memcpy(to,from,size*sizeof(T));
00257 #else
00258     if (size == 0 || from == to)
00259         return;
00260 
00261 #ifndef NDEBUG
00262     if (size < 0)
00263         throw CoinError("trying to copy negative number of entries",
00264                         "CoinMemcpyN", "");
00265 #endif
00266 
00267 #if 0
00268     /* There is no point to do this test. If to and from are from different
00269        blocks then dist is undefined, so this can crash correct code. It's
00270        better to trust the user that the arrays are really disjoint. */
00271     const long dist = to - from;
00272     if (-size < dist && dist < size)
00273         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00274 #endif
00275 
00276     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00277         to[0] = from[0];
00278         to[1] = from[1];
00279         to[2] = from[2];
00280         to[3] = from[3];
00281         to[4] = from[4];
00282         to[5] = from[5];
00283         to[6] = from[6];
00284         to[7] = from[7];
00285     }
00286     switch (size % 8) {
00287     case 7: to[6] = from[6];
00288     case 6: to[5] = from[5];
00289     case 5: to[4] = from[4];
00290     case 4: to[3] = from[3];
00291     case 3: to[2] = from[2];
00292     case 2: to[1] = from[1];
00293     case 1: to[0] = from[0];
00294     case 0: break;
00295     }
00296 #endif
00297 #else
00298     CoinCopyN(from, size, to);
00299 #endif
00300 }
00301 #else
00302 template <class T> inline void
00303 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
00304 {
00305 #ifdef USE_MEMCPY
00306   std::memcpy(to,from,size*sizeof(T));
00307 #else
00308   T * COIN_RESTRICT put =  to;
00309   const T * COIN_RESTRICT get = from;
00310   for ( ; 0<size ; --size)
00311     *put++ = *get++;
00312 #endif
00313 }
00314 #endif
00315 
00316 //-----------------------------------------------------------------------------
00317 
00322 template <class T> inline void
00323 CoinMemcpy(register const T* first, register const T* last,
00324            register T* to)
00325 {
00326     CoinMemcpyN(first, static_cast<int>(last - first), to);
00327 }
00328 
00329 //#############################################################################
00330 
00337 template <class T> inline void
00338 CoinFillN(register T* to, const int size, register const T value)
00339 {
00340     if (size == 0)
00341         return;
00342 
00343 #ifndef NDEBUG
00344     if (size < 0)
00345         throw CoinError("trying to fill negative number of entries",
00346                         "CoinFillN", "");
00347 #endif
00348 #if 1
00349     for (register int n = size / 8; n > 0; --n, to += 8) {
00350         to[0] = value;
00351         to[1] = value;
00352         to[2] = value;
00353         to[3] = value;
00354         to[4] = value;
00355         to[5] = value;
00356         to[6] = value;
00357         to[7] = value;
00358     }
00359     switch (size % 8) {
00360     case 7: to[6] = value;
00361     case 6: to[5] = value;
00362     case 5: to[4] = value;
00363     case 4: to[3] = value;
00364     case 3: to[2] = value;
00365     case 2: to[1] = value;
00366     case 1: to[0] = value;
00367     case 0: break;
00368     }
00369 #else
00370     // Use Duff's device to fill
00371     register int n = (size + 7) / 8;
00372     --to;
00373     switch (size % 8) {
00374     case 0: do{     *++to = value;
00375     case 7:         *++to = value;
00376     case 6:         *++to = value;
00377     case 5:         *++to = value;
00378     case 4:         *++to = value;
00379     case 3:         *++to = value;
00380     case 2:         *++to = value;
00381     case 1:         *++to = value;
00382     }while(--n>0);
00383     }
00384 #endif
00385 }
00386 
00387 //-----------------------------------------------------------------------------
00388 
00392 template <class T> inline void
00393 CoinFill(register T* first, register T* last, const T value)
00394 {
00395     CoinFillN(first, last - first, value);
00396 }
00397 
00398 //#############################################################################
00399 
00406 template <class T> inline void
00407 CoinZeroN(register T* to, const int size)
00408 {
00409 #ifdef USE_MEMCPY
00410     // Use memset - seems faster on Intel with gcc
00411 #ifndef NDEBUG
00412     // Some debug so check
00413     if (size < 0)
00414         throw CoinError("trying to fill negative number of entries",
00415                         "CoinZeroN", "");
00416 #endif
00417     memset(to,0,size*sizeof(T));
00418 #else
00419     if (size == 0)
00420         return;
00421 
00422 #ifndef NDEBUG
00423     if (size < 0)
00424         throw CoinError("trying to fill negative number of entries",
00425                         "CoinZeroN", "");
00426 #endif
00427 #if 1
00428     for (register int n = size / 8; n > 0; --n, to += 8) {
00429         to[0] = 0;
00430         to[1] = 0;
00431         to[2] = 0;
00432         to[3] = 0;
00433         to[4] = 0;
00434         to[5] = 0;
00435         to[6] = 0;
00436         to[7] = 0;
00437     }
00438     switch (size % 8) {
00439     case 7: to[6] = 0;
00440     case 6: to[5] = 0;
00441     case 5: to[4] = 0;
00442     case 4: to[3] = 0;
00443     case 3: to[2] = 0;
00444     case 2: to[1] = 0;
00445     case 1: to[0] = 0;
00446     case 0: break;
00447     }
00448 #else
00449     // Use Duff's device to fill
00450     register int n = (size + 7) / 8;
00451     --to;
00452     switch (size % 8) {
00453     case 0: do{     *++to = 0;
00454     case 7:         *++to = 0;
00455     case 6:         *++to = 0;
00456     case 5:         *++to = 0;
00457     case 4:         *++to = 0;
00458     case 3:         *++to = 0;
00459     case 2:         *++to = 0;
00460     case 1:         *++to = 0;
00461     }while(--n>0);
00462     }
00463 #endif
00464 #endif
00465 }
00467 inline void
00468 CoinCheckDoubleZero(double * to, const int size)
00469 {
00470     int n=0;
00471     for (int j=0;j<size;j++) {
00472         if (to[j]) 
00473             n++;
00474     }
00475     if (n) {
00476         printf("array of length %d should be zero has %d nonzero\n",size,n);
00477     }
00478 }
00480 inline void
00481 CoinCheckIntZero(int * to, const int size)
00482 {
00483     int n=0;
00484     for (int j=0;j<size;j++) {
00485         if (to[j]) 
00486             n++;
00487     }
00488     if (n) {
00489         printf("array of length %d should be zero has %d nonzero\n",size,n);
00490     }
00491 }
00492 
00493 //-----------------------------------------------------------------------------
00494 
00498 template <class T> inline void
00499 CoinZero(register T* first, register T* last)
00500 {
00501     CoinZeroN(first, last - first);
00502 }
00503 
00504 //#############################################################################
00505 
00507 inline char * CoinStrdup(const char * name)
00508 {
00509   char* dup = NULL;
00510   if (name) {
00511     const int len = static_cast<int>(strlen(name));
00512     dup = static_cast<char*>(malloc(len+1));
00513     CoinMemcpyN(name, len, dup);
00514     dup[len] = 0;
00515   }
00516   return dup;
00517 }
00518 
00519 //#############################################################################
00520 
00524 template <class T> inline T
00525 CoinMax(register const T x1, register const T x2)
00526 {
00527     return (x1 > x2) ? x1 : x2;
00528 }
00529 
00530 //-----------------------------------------------------------------------------
00531 
00535 template <class T> inline T
00536 CoinMin(register const T x1, register const T x2)
00537 {
00538     return (x1 < x2) ? x1 : x2;
00539 }
00540 
00541 //-----------------------------------------------------------------------------
00542 
00546 template <class T> inline T
00547 CoinAbs(const T value)
00548 {
00549     return value<0 ? -value : value;
00550 }
00551 
00552 //#############################################################################
00553 
00557 template <class T> inline bool
00558 CoinIsSorted(register const T* first, const int size)
00559 {
00560     if (size == 0)
00561         return true;
00562 
00563 #ifndef NDEBUG
00564     if (size < 0)
00565         throw CoinError("negative number of entries", "CoinIsSorted", "");
00566 #endif
00567 #if 1
00568     // size1 is the number of comparisons to be made
00569     const int size1 = size  - 1;
00570     for (register int n = size1 / 8; n > 0; --n, first += 8) {
00571         if (first[8] < first[7]) return false;
00572         if (first[7] < first[6]) return false;
00573         if (first[6] < first[5]) return false;
00574         if (first[5] < first[4]) return false;
00575         if (first[4] < first[3]) return false;
00576         if (first[3] < first[2]) return false;
00577         if (first[2] < first[1]) return false;
00578         if (first[1] < first[0]) return false;
00579     }
00580 
00581     switch (size1 % 8) {
00582     case 7: if (first[7] < first[6]) return false;
00583     case 6: if (first[6] < first[5]) return false;
00584     case 5: if (first[5] < first[4]) return false;
00585     case 4: if (first[4] < first[3]) return false;
00586     case 3: if (first[3] < first[2]) return false;
00587     case 2: if (first[2] < first[1]) return false;
00588     case 1: if (first[1] < first[0]) return false;
00589     case 0: break;
00590     }
00591 #else
00592     register const T* next = first;
00593     register const T* last = first + size;
00594     for (++next; next != last; first = next, ++next)
00595         if (*next < *first)
00596             return false;
00597 #endif   
00598     return true;
00599 }
00600 
00601 //-----------------------------------------------------------------------------
00602 
00606 template <class T> inline bool
00607 CoinIsSorted(register const T* first, register const T* last)
00608 {
00609     return CoinIsSorted(first, static_cast<int>(last - first));
00610 }
00611 
00612 //#############################################################################
00613 
00617 template <class T> inline void
00618 CoinIotaN(register T* first, const int size, register T init)
00619 {
00620     if (size == 0)
00621         return;
00622 
00623 #ifndef NDEBUG
00624     if (size < 0)
00625         throw CoinError("negative number of entries", "CoinIotaN", "");
00626 #endif
00627 #if 1
00628     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00629         first[0] = init;
00630         first[1] = init + 1;
00631         first[2] = init + 2;
00632         first[3] = init + 3;
00633         first[4] = init + 4;
00634         first[5] = init + 5;
00635         first[6] = init + 6;
00636         first[7] = init + 7;
00637     }
00638     switch (size % 8) {
00639     case 7: first[6] = init + 6;
00640     case 6: first[5] = init + 5;
00641     case 5: first[4] = init + 4;
00642     case 4: first[3] = init + 3;
00643     case 3: first[2] = init + 2;
00644     case 2: first[1] = init + 1;
00645     case 1: first[0] = init;
00646     case 0: break;
00647     }
00648 #else
00649     // Use Duff's device to fill
00650     register int n = (size + 7) / 8;
00651     --first;
00652     --init;
00653     switch (size % 8) {
00654     case 0: do{     *++first = ++init;
00655     case 7:         *++first = ++init;
00656     case 6:         *++first = ++init;
00657     case 5:         *++first = ++init;
00658     case 4:         *++first = ++init;
00659     case 3:         *++first = ++init;
00660     case 2:         *++first = ++init;
00661     case 1:         *++first = ++init;
00662     }while(--n>0);
00663     }
00664 #endif
00665 }
00666 
00667 //-----------------------------------------------------------------------------
00668 
00672 template <class T> inline void
00673 CoinIota(T* first, const T* last, T init)
00674 {
00675     CoinIotaN(first, last-first, init);
00676 }
00677 
00678 //#############################################################################
00679 
00685 template <class T> inline T *
00686 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00687                            const int * firstDelPos, const int * lastDelPos)
00688 {
00689     int delNum = lastDelPos - firstDelPos;
00690     if (delNum == 0)
00691         return arrayLast;
00692 
00693     if (delNum < 0)
00694         throw CoinError("trying to delete negative number of entries",
00695                         "CoinDeleteEntriesFromArray", "");
00696 
00697     int * delSortedPos = NULL;
00698     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00699            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00700         // the positions of the to be deleted is either not sorted or not unique
00701         delSortedPos = new int[delNum];
00702         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00703         std::sort(delSortedPos, delSortedPos + delNum);
00704         delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00705     }
00706     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00707 
00708     const int last = delNum - 1;
00709     int size = delSorted[0];
00710     for (int i = 0; i < last; ++i) {
00711         const int copyFirst = delSorted[i] + 1;
00712         const int copyLast = delSorted[i+1];
00713         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00714                  arrayFirst + size);
00715         size += copyLast - copyFirst;
00716     }
00717     const int copyFirst = delSorted[last] + 1;
00718     const int copyLast = arrayLast - arrayFirst;
00719     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00720              arrayFirst + size);
00721     size += copyLast - copyFirst;
00722 
00723     if (delSortedPos)
00724         delete[] delSortedPos;
00725 
00726     return arrayFirst + size;
00727 }
00728 
00729 //#############################################################################
00730 
00731 #define COIN_OWN_RANDOM_32
00732 
00733 #if defined COIN_OWN_RANDOM_32
00734 /* Thanks to Stefano Gliozzi for providing an operating system
00735    independent random number generator.  */
00736 
00737 // linear congruential generator. given the seed, the generated numbers are  
00738 // always the same regardless the (32 bit) architecture. This allows to 
00739 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
00740 // getting in most cases the same optimization path. 
00742 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00743 {
00744   static unsigned int last = 123456;
00745   if (isSeed) { 
00746     last = seed;
00747   } else {
00748     last = 1664525*last+1013904223;
00749     return ((static_cast<double> (last))/4294967296.0);
00750   }
00751   return(0.0);
00752 }
00754 inline void CoinSeedRandom(int iseed)
00755 {
00756   CoinDrand48(true, iseed);
00757 }
00758 
00759 #else // COIN_OWN_RANDOM_32
00760 
00761 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00762 
00763 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00764 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00765 
00766 #else
00767 
00768 inline double CoinDrand48() { return drand48(); }
00769 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00770 
00771 #endif
00772 
00773 #endif // COIN_OWN_RANDOM_32
00774 
00775 //#############################################################################
00776 
00779 inline char CoinFindDirSeparator()
00780 {
00781     int size = 1000;
00782     char* buf = 0;
00783     while (true) {
00784         buf = new char[size];
00785         if (getcwd(buf, size))
00786             break;
00787         delete[] buf;
00788         buf = 0;
00789         size = 2*size;
00790     }
00791     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we 
00792     // assume it's dos and the dirsep is '\'
00793     char dirsep = buf[0] == '/' ? '/' : '\\';
00794     delete[] buf;
00795     return dirsep;
00796 }
00797 //#############################################################################
00798 
00799 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00800                            const size_t len)
00801 {
00802     for (size_t i = 0; i < len; ++i) {
00803         if (s0[i] == 0) {
00804             return s1[i] == 0 ? 0 : -1;
00805         }
00806         if (s1[i] == 0) {
00807             return 1;
00808         }
00809         const int c0 = tolower(s0[i]);
00810         const int c1 = tolower(s1[i]);
00811         if (c0 < c1)
00812             return -1;
00813         if (c0 > c1)
00814             return 1;
00815     }
00816     return 0;
00817 }
00818 
00819 //#############################################################################
00820 
00822 template <class T> inline void CoinSwap (T &x, T &y)
00823 {
00824     T t = x;
00825     x = y;
00826     y = t;
00827 }
00828 
00829 //#############################################################################
00830 
00835 /* FIXME64 */
00836 
00837 template <class T> inline int
00838 CoinToFile( const T* array, int size, FILE * fp)
00839 {
00840     size_t numberWritten;
00841     if (array&&size) {
00842         numberWritten = fwrite(&size,sizeof(int),1,fp);
00843         if (numberWritten!=1)
00844             return 1;
00845         numberWritten = fwrite(array,sizeof(T),size_t(size),fp);
00846         if (numberWritten!=size)
00847             return 1;
00848     } else {
00849         size = 0;
00850         numberWritten = fwrite(&size,sizeof(int),1,fp);
00851         if (numberWritten!=1)
00852             return 1;
00853     }
00854     return 0;
00855 }
00856 
00857 //#############################################################################
00858 
00865 /* FIXME64 */
00866 
00867 template <class T> inline int
00868 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00869 {
00870     size_t numberRead;
00871     numberRead = fread(&newSize,sizeof(int),1,fp);
00872     if (numberRead!=1)
00873         return 1;
00874     int returnCode=0;
00875     if (size!=newSize&&(newSize||array))
00876         returnCode=2;
00877     if (newSize) {
00878         array = new T [newSize];
00879         numberRead = fread(array,sizeof(T),size_t(newSize),fp);
00880         if (numberRead!=newSize)
00881             returnCode=1;
00882     } else {
00883         array = NULL;
00884     }
00885     return returnCode;
00886 }
00887 
00888 //#############################################################################
00889 
00891 inline double CoinCbrt(double x)
00892 {
00893 #if defined(_MSC_VER) 
00894     return pow(x,(1./3.));
00895 #else
00896     return cbrt(x);
00897 #endif
00898 }
00899 //-----------------------------------------------------------------------------
00900 
00902 #define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type)))
00903 
00904 inline int
00905 CoinStrlenAsInt(const char * string)
00906 {
00907     return static_cast<int>(strlen(string));
00908 }
00909 
00912 #if defined COIN_OWN_RANDOM_32
00913 class CoinThreadRandom  {
00914 public:
00919   CoinThreadRandom()
00920   { seed_=12345678;}
00922   CoinThreadRandom(int seed)
00923   { 
00924     seed_ = seed;
00925   }
00927   ~CoinThreadRandom() {}
00928   // Copy
00929   CoinThreadRandom(const CoinThreadRandom & rhs)
00930   { seed_ = rhs.seed_;}
00931   // Assignment
00932   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00933   {
00934     if (this != &rhs) {
00935       seed_ = rhs.seed_;
00936     }
00937     return *this;
00938   }
00939 
00941   
00946   inline void setSeed(int seed)
00947   { 
00948     seed_ = seed;
00949   }
00951   inline unsigned int getSeed() const
00952   { 
00953     return seed_;
00954   }
00956   inline double randomDouble() const
00957   {
00958     double retVal;
00959     seed_ = 1664525*(seed_)+1013904223;
00960     retVal = ((static_cast<double> (seed_))/4294967296.0);
00961     return retVal;
00962   }
00964   
00965   
00966 protected:
00970 
00971   mutable unsigned int seed_;
00973 };
00974 #else
00975 class CoinThreadRandom  {
00976 public:
00981   CoinThreadRandom()
00982   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00984   CoinThreadRandom(const unsigned short seed[3])
00985   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00987   CoinThreadRandom(int seed)
00988   { 
00989     union { int i[2]; unsigned short int s[4];} put;
00990     put.i[0]=seed;
00991     put.i[1]=seed;
00992     memcpy(seed_,put.s,3*sizeof(unsigned short));
00993   }
00995   ~CoinThreadRandom() {}
00996   // Copy
00997   CoinThreadRandom(const CoinThreadRandom & rhs)
00998   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00999   // Assignment
01000   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
01001   {
01002     if (this != &rhs) {
01003       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
01004     }
01005     return *this;
01006   }
01007 
01009   
01014   inline void setSeed(const unsigned short seed[3])
01015   { memcpy(seed_,seed,3*sizeof(unsigned short));}
01017   inline void setSeed(int seed)
01018   { 
01019     union { int i[2]; unsigned short int s[4];} put;
01020     put.i[0]=seed;
01021     put.i[1]=seed;
01022     memcpy(seed_,put.s,3*sizeof(unsigned short));
01023   }
01025   inline double randomDouble() const
01026   {
01027     double retVal;
01028 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
01029     retVal=rand();
01030     retVal=retVal/(double) RAND_MAX;
01031 #else
01032     retVal = erand48(seed_);
01033 #endif
01034     return retVal;
01035   }
01037   
01038   
01039 protected:
01043 
01044   mutable unsigned short seed_[3];
01046 };
01047 #endif
01048 #endif

Generated on Fri Oct 15 2010 18:21:02 by  doxygen 1.7.1