/home/coin/SVN-release/Alps-1.2.0/CoinUtils/src/CoinHelperFunctions.hpp

Go to the documentation of this file.
00001 /* $Id: CoinHelperFunctions.hpp 1313 2010-08-24 15:39:49Z lou $ */
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 
00084 template <class T> inline void
00085 CoinCopy(register const T* first, register const T* last, register T* to)
00086 {
00087     CoinCopyN(first, static_cast<int>(last-first), to);
00088 }
00089 
00090 //-----------------------------------------------------------------------------
00091 
00099 template <class T> inline void
00100 CoinDisjointCopyN(register const T* from, const int size, register T* to)
00101 {
00102 #ifndef _MSC_VER
00103     if (size == 0 || from == to)
00104         return;
00105 
00106 #ifndef NDEBUG
00107     if (size < 0)
00108         throw CoinError("trying to copy negative number of entries",
00109                         "CoinDisjointCopyN", "");
00110 #endif
00111 
00112 #if 0
00113     /* There is no point to do this test. If to and from are from different
00114        blocks then dist is undefined, so this can crash correct code. It's
00115        better to trust the user that the arrays are really disjoint. */
00116     const long dist = to - from;
00117     if (-size < dist && dist < size)
00118         throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
00119 #endif
00120 
00121     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00122         to[0] = from[0];
00123         to[1] = from[1];
00124         to[2] = from[2];
00125         to[3] = from[3];
00126         to[4] = from[4];
00127         to[5] = from[5];
00128         to[6] = from[6];
00129         to[7] = from[7];
00130     }
00131     switch (size % 8) {
00132     case 7: to[6] = from[6];
00133     case 6: to[5] = from[5];
00134     case 5: to[4] = from[4];
00135     case 4: to[3] = from[3];
00136     case 3: to[2] = from[2];
00137     case 2: to[1] = from[1];
00138     case 1: to[0] = from[0];
00139     case 0: break;
00140     }
00141 #else
00142     CoinCopyN(from, size, to);
00143 #endif
00144 }
00145 
00146 //-----------------------------------------------------------------------------
00147 
00152 template <class T> inline void
00153 CoinDisjointCopy(register const T* first, register const T* last,
00154                  register T* to)
00155 {
00156     CoinDisjointCopyN(first, static_cast<int>(last - first), to);
00157 }
00158 
00159 //-----------------------------------------------------------------------------
00160 
00165 template <class T> inline T*
00166 CoinCopyOfArray( const T * array, const int size)
00167 {
00168     if (array) {
00169         T * arrayNew = new T[size];
00170         std::memcpy(arrayNew,array,size*sizeof(T));
00171         return arrayNew;
00172     } else {
00173         return NULL;
00174     }
00175 }
00176 
00177 
00182 template <class T> inline T*
00183 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
00184 {
00185     if (array||size) {
00186         T * arrayNew = new T[size];
00187         assert (copySize<=size);
00188         std::memcpy(arrayNew,array,copySize*sizeof(T));
00189         return arrayNew;
00190     } else {
00191         return NULL;
00192     }
00193 }
00194 
00199 template <class T> inline T*
00200 CoinCopyOfArray( const T * array, const int size, T value)
00201 {
00202     T * arrayNew = new T[size];
00203     if (array) {
00204         std::memcpy(arrayNew,array,size*sizeof(T));
00205     } else {
00206         int i;
00207         for (i=0;i<size;i++) 
00208             arrayNew[i] = value;
00209     }
00210     return arrayNew;
00211 }
00212 
00213 
00218 template <class T> inline T*
00219 CoinCopyOfArrayOrZero( const T * array , const int size)
00220 {
00221     T * arrayNew = new T[size];
00222     if (array) {
00223       std::memcpy(arrayNew,array,size*sizeof(T));
00224     } else {
00225       std::memset(arrayNew,0,size*sizeof(T));
00226     }
00227     return arrayNew;
00228 }
00229 
00230 
00231 //-----------------------------------------------------------------------------
00232 
00240 #ifndef COIN_USE_RESTRICT
00241 template <class T> inline void
00242 CoinMemcpyN(register const T* from, const int size, register T* to)
00243 {
00244 #ifndef _MSC_VER
00245 #ifdef USE_MEMCPY
00246     // Use memcpy - seems a lot faster on Intel with gcc
00247 #ifndef NDEBUG
00248     // Some debug so check
00249     if (size < 0)
00250         throw CoinError("trying to copy negative number of entries",
00251                         "CoinMemcpyN", "");
00252   
00253 #if 0
00254     /* There is no point to do this test. If to and from are from different
00255        blocks then dist is undefined, so this can crash correct code. It's
00256        better to trust the user that the arrays are really disjoint. */
00257     const long dist = to - from;
00258     if (-size < dist && dist < size)
00259         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00260 #endif
00261 #endif
00262     std::memcpy(to,from,size*sizeof(T));
00263 #else
00264     if (size == 0 || from == to)
00265         return;
00266 
00267 #ifndef NDEBUG
00268     if (size < 0)
00269         throw CoinError("trying to copy negative number of entries",
00270                         "CoinMemcpyN", "");
00271 #endif
00272 
00273 #if 0
00274     /* There is no point to do this test. If to and from are from different
00275        blocks then dist is undefined, so this can crash correct code. It's
00276        better to trust the user that the arrays are really disjoint. */
00277     const long dist = to - from;
00278     if (-size < dist && dist < size)
00279         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00280 #endif
00281 
00282     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00283         to[0] = from[0];
00284         to[1] = from[1];
00285         to[2] = from[2];
00286         to[3] = from[3];
00287         to[4] = from[4];
00288         to[5] = from[5];
00289         to[6] = from[6];
00290         to[7] = from[7];
00291     }
00292     switch (size % 8) {
00293     case 7: to[6] = from[6];
00294     case 6: to[5] = from[5];
00295     case 5: to[4] = from[4];
00296     case 4: to[3] = from[3];
00297     case 3: to[2] = from[2];
00298     case 2: to[1] = from[1];
00299     case 1: to[0] = from[0];
00300     case 0: break;
00301     }
00302 #endif
00303 #else
00304     CoinCopyN(from, size, to);
00305 #endif
00306 }
00307 #else
00308 template <class T> inline void
00309 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
00310 {
00311 #ifdef USE_MEMCPY
00312   std::memcpy(to,from,size*sizeof(T));
00313 #else
00314   T * COIN_RESTRICT put =  to;
00315   const T * COIN_RESTRICT get = from;
00316   for ( ; 0<size ; --size)
00317     *put++ = *get++;
00318 #endif
00319 }
00320 #endif
00321 
00322 //-----------------------------------------------------------------------------
00323 
00328 template <class T> inline void
00329 CoinMemcpy(register const T* first, register const T* last,
00330            register T* to)
00331 {
00332     CoinMemcpyN(first, static_cast<int>(last - first), to);
00333 }
00334 
00335 //#############################################################################
00336 
00343 template <class T> inline void
00344 CoinFillN(register T* to, const int size, register const T value)
00345 {
00346     if (size == 0)
00347         return;
00348 
00349 #ifndef NDEBUG
00350     if (size < 0)
00351         throw CoinError("trying to fill negative number of entries",
00352                         "CoinFillN", "");
00353 #endif
00354 #if 1
00355     for (register int n = size / 8; n > 0; --n, to += 8) {
00356         to[0] = value;
00357         to[1] = value;
00358         to[2] = value;
00359         to[3] = value;
00360         to[4] = value;
00361         to[5] = value;
00362         to[6] = value;
00363         to[7] = value;
00364     }
00365     switch (size % 8) {
00366     case 7: to[6] = value;
00367     case 6: to[5] = value;
00368     case 5: to[4] = value;
00369     case 4: to[3] = value;
00370     case 3: to[2] = value;
00371     case 2: to[1] = value;
00372     case 1: to[0] = value;
00373     case 0: break;
00374     }
00375 #else
00376     // Use Duff's device to fill
00377     register int n = (size + 7) / 8;
00378     --to;
00379     switch (size % 8) {
00380     case 0: do{     *++to = value;
00381     case 7:         *++to = value;
00382     case 6:         *++to = value;
00383     case 5:         *++to = value;
00384     case 4:         *++to = value;
00385     case 3:         *++to = value;
00386     case 2:         *++to = value;
00387     case 1:         *++to = value;
00388     }while(--n>0);
00389     }
00390 #endif
00391 }
00392 
00393 //-----------------------------------------------------------------------------
00394 
00398 template <class T> inline void
00399 CoinFill(register T* first, register T* last, const T value)
00400 {
00401     CoinFillN(first, last - first, value);
00402 }
00403 
00404 //#############################################################################
00405 
00412 template <class T> inline void
00413 CoinZeroN(register T* to, const int size)
00414 {
00415 #ifdef USE_MEMCPY
00416     // Use memset - seems faster on Intel with gcc
00417 #ifndef NDEBUG
00418     // Some debug so check
00419     if (size < 0)
00420         throw CoinError("trying to fill negative number of entries",
00421                         "CoinZeroN", "");
00422 #endif
00423     memset(to,0,size*sizeof(T));
00424 #else
00425     if (size == 0)
00426         return;
00427 
00428 #ifndef NDEBUG
00429     if (size < 0)
00430         throw CoinError("trying to fill negative number of entries",
00431                         "CoinZeroN", "");
00432 #endif
00433 #if 1
00434     for (register int n = size / 8; n > 0; --n, to += 8) {
00435         to[0] = 0;
00436         to[1] = 0;
00437         to[2] = 0;
00438         to[3] = 0;
00439         to[4] = 0;
00440         to[5] = 0;
00441         to[6] = 0;
00442         to[7] = 0;
00443     }
00444     switch (size % 8) {
00445     case 7: to[6] = 0;
00446     case 6: to[5] = 0;
00447     case 5: to[4] = 0;
00448     case 4: to[3] = 0;
00449     case 3: to[2] = 0;
00450     case 2: to[1] = 0;
00451     case 1: to[0] = 0;
00452     case 0: break;
00453     }
00454 #else
00455     // Use Duff's device to fill
00456     register int n = (size + 7) / 8;
00457     --to;
00458     switch (size % 8) {
00459     case 0: do{     *++to = 0;
00460     case 7:         *++to = 0;
00461     case 6:         *++to = 0;
00462     case 5:         *++to = 0;
00463     case 4:         *++to = 0;
00464     case 3:         *++to = 0;
00465     case 2:         *++to = 0;
00466     case 1:         *++to = 0;
00467     }while(--n>0);
00468     }
00469 #endif
00470 #endif
00471 }
00473 inline void
00474 CoinCheckDoubleZero(double * to, const int size)
00475 {
00476     int n=0;
00477     for (int j=0;j<size;j++) {
00478         if (to[j]) 
00479             n++;
00480     }
00481     if (n) {
00482         printf("array of length %d should be zero has %d nonzero\n",size,n);
00483     }
00484 }
00486 inline void
00487 CoinCheckIntZero(int * to, const int size)
00488 {
00489     int n=0;
00490     for (int j=0;j<size;j++) {
00491         if (to[j]) 
00492             n++;
00493     }
00494     if (n) {
00495         printf("array of length %d should be zero has %d nonzero\n",size,n);
00496     }
00497 }
00498 
00499 //-----------------------------------------------------------------------------
00500 
00504 template <class T> inline void
00505 CoinZero(register T* first, register T* last)
00506 {
00507     CoinZeroN(first, last - first);
00508 }
00509 
00510 //#############################################################################
00511 
00513 inline char * CoinStrdup(const char * name)
00514 {
00515   char* dup = NULL;
00516   if (name) {
00517     const int len = static_cast<int>(strlen(name));
00518     dup = static_cast<char*>(malloc(len+1));
00519     CoinMemcpyN(name, len, dup);
00520     dup[len] = 0;
00521   }
00522   return dup;
00523 }
00524 
00525 //#############################################################################
00526 
00530 template <class T> inline T
00531 CoinMax(register const T x1, register const T x2)
00532 {
00533     return (x1 > x2) ? x1 : x2;
00534 }
00535 
00536 //-----------------------------------------------------------------------------
00537 
00541 template <class T> inline T
00542 CoinMin(register const T x1, register const T x2)
00543 {
00544     return (x1 < x2) ? x1 : x2;
00545 }
00546 
00547 //-----------------------------------------------------------------------------
00548 
00552 template <class T> inline T
00553 CoinAbs(const T value)
00554 {
00555     return value<0 ? -value : value;
00556 }
00557 
00558 //#############################################################################
00559 
00563 template <class T> inline bool
00564 CoinIsSorted(register const T* first, const int size)
00565 {
00566     if (size == 0)
00567         return true;
00568 
00569 #ifndef NDEBUG
00570     if (size < 0)
00571         throw CoinError("negative number of entries", "CoinIsSorted", "");
00572 #endif
00573 #if 1
00574     // size1 is the number of comparisons to be made
00575     const int size1 = size  - 1;
00576     for (register int n = size1 / 8; n > 0; --n, first += 8) {
00577         if (first[8] < first[7]) return false;
00578         if (first[7] < first[6]) return false;
00579         if (first[6] < first[5]) return false;
00580         if (first[5] < first[4]) return false;
00581         if (first[4] < first[3]) return false;
00582         if (first[3] < first[2]) return false;
00583         if (first[2] < first[1]) return false;
00584         if (first[1] < first[0]) return false;
00585     }
00586 
00587     switch (size1 % 8) {
00588     case 7: if (first[7] < first[6]) return false;
00589     case 6: if (first[6] < first[5]) return false;
00590     case 5: if (first[5] < first[4]) return false;
00591     case 4: if (first[4] < first[3]) return false;
00592     case 3: if (first[3] < first[2]) return false;
00593     case 2: if (first[2] < first[1]) return false;
00594     case 1: if (first[1] < first[0]) return false;
00595     case 0: break;
00596     }
00597 #else
00598     register const T* next = first;
00599     register const T* last = first + size;
00600     for (++next; next != last; first = next, ++next)
00601         if (*next < *first)
00602             return false;
00603 #endif   
00604     return true;
00605 }
00606 
00607 //-----------------------------------------------------------------------------
00608 
00612 template <class T> inline bool
00613 CoinIsSorted(register const T* first, register const T* last)
00614 {
00615     return CoinIsSorted(first, static_cast<int>(last - first));
00616 }
00617 
00618 //#############################################################################
00619 
00623 template <class T> inline void
00624 CoinIotaN(register T* first, const int size, register T init)
00625 {
00626     if (size == 0)
00627         return;
00628 
00629 #ifndef NDEBUG
00630     if (size < 0)
00631         throw CoinError("negative number of entries", "CoinIotaN", "");
00632 #endif
00633 #if 1
00634     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00635         first[0] = init;
00636         first[1] = init + 1;
00637         first[2] = init + 2;
00638         first[3] = init + 3;
00639         first[4] = init + 4;
00640         first[5] = init + 5;
00641         first[6] = init + 6;
00642         first[7] = init + 7;
00643     }
00644     switch (size % 8) {
00645     case 7: first[6] = init + 6;
00646     case 6: first[5] = init + 5;
00647     case 5: first[4] = init + 4;
00648     case 4: first[3] = init + 3;
00649     case 3: first[2] = init + 2;
00650     case 2: first[1] = init + 1;
00651     case 1: first[0] = init;
00652     case 0: break;
00653     }
00654 #else
00655     // Use Duff's device to fill
00656     register int n = (size + 7) / 8;
00657     --first;
00658     --init;
00659     switch (size % 8) {
00660     case 0: do{     *++first = ++init;
00661     case 7:         *++first = ++init;
00662     case 6:         *++first = ++init;
00663     case 5:         *++first = ++init;
00664     case 4:         *++first = ++init;
00665     case 3:         *++first = ++init;
00666     case 2:         *++first = ++init;
00667     case 1:         *++first = ++init;
00668     }while(--n>0);
00669     }
00670 #endif
00671 }
00672 
00673 //-----------------------------------------------------------------------------
00674 
00678 template <class T> inline void
00679 CoinIota(T* first, const T* last, T init)
00680 {
00681     CoinIotaN(first, last-first, init);
00682 }
00683 
00684 //#############################################################################
00685 
00691 template <class T> inline T *
00692 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00693                            const int * firstDelPos, const int * lastDelPos)
00694 {
00695     int delNum = static_cast<int>(lastDelPos - firstDelPos);
00696     if (delNum == 0)
00697         return arrayLast;
00698 
00699     if (delNum < 0)
00700         throw CoinError("trying to delete negative number of entries",
00701                         "CoinDeleteEntriesFromArray", "");
00702 
00703     int * delSortedPos = NULL;
00704     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00705            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00706         // the positions of the to be deleted is either not sorted or not unique
00707         delSortedPos = new int[delNum];
00708         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00709         std::sort(delSortedPos, delSortedPos + delNum);
00710         delNum = static_cast<int>(std::unique(delSortedPos,
00711                                   delSortedPos+delNum) - delSortedPos);
00712     }
00713     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00714 
00715     const int last = delNum - 1;
00716     int size = delSorted[0];
00717     for (int i = 0; i < last; ++i) {
00718         const int copyFirst = delSorted[i] + 1;
00719         const int copyLast = delSorted[i+1];
00720         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00721                  arrayFirst + size);
00722         size += copyLast - copyFirst;
00723     }
00724     const int copyFirst = delSorted[last] + 1;
00725     const int copyLast = static_cast<int>(arrayLast - arrayFirst);
00726     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00727              arrayFirst + size);
00728     size += copyLast - copyFirst;
00729 
00730     if (delSortedPos)
00731         delete[] delSortedPos;
00732 
00733     return arrayFirst + size;
00734 }
00735 
00736 //#############################################################################
00737 
00738 #define COIN_OWN_RANDOM_32
00739 
00740 #if defined COIN_OWN_RANDOM_32
00741 /* Thanks to Stefano Gliozzi for providing an operating system
00742    independent random number generator.  */
00743 
00744 // linear congruential generator. given the seed, the generated numbers are  
00745 // always the same regardless the (32 bit) architecture. This allows to 
00746 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
00747 // getting in most cases the same optimization path. 
00749 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00750 {
00751   static unsigned int last = 123456;
00752   if (isSeed) { 
00753     last = seed;
00754   } else {
00755     last = 1664525*last+1013904223;
00756     return ((static_cast<double> (last))/4294967296.0);
00757   }
00758   return(0.0);
00759 }
00761 inline void CoinSeedRandom(int iseed)
00762 {
00763   CoinDrand48(true, iseed);
00764 }
00765 
00766 #else // COIN_OWN_RANDOM_32
00767 
00768 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00769 
00770 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00771 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00772 
00773 #else
00774 
00775 inline double CoinDrand48() { return drand48(); }
00776 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00777 
00778 #endif
00779 
00780 #endif // COIN_OWN_RANDOM_32
00781 
00782 //#############################################################################
00783 
00786 inline char CoinFindDirSeparator()
00787 {
00788     int size = 1000;
00789     char* buf = 0;
00790     while (true) {
00791         buf = new char[size];
00792         if (getcwd(buf, size))
00793             break;
00794         delete[] buf;
00795         buf = 0;
00796         size = 2*size;
00797     }
00798     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we 
00799     // assume it's dos and the dirsep is '\'
00800     char dirsep = buf[0] == '/' ? '/' : '\\';
00801     delete[] buf;
00802     return dirsep;
00803 }
00804 //#############################################################################
00805 
00806 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00807                            const size_t len)
00808 {
00809     for (size_t i = 0; i < len; ++i) {
00810         if (s0[i] == 0) {
00811             return s1[i] == 0 ? 0 : -1;
00812         }
00813         if (s1[i] == 0) {
00814             return 1;
00815         }
00816         const int c0 = tolower(s0[i]);
00817         const int c1 = tolower(s1[i]);
00818         if (c0 < c1)
00819             return -1;
00820         if (c0 > c1)
00821             return 1;
00822     }
00823     return 0;
00824 }
00825 
00826 //#############################################################################
00827 
00829 template <class T> inline void CoinSwap (T &x, T &y)
00830 {
00831     T t = x;
00832     x = y;
00833     y = t;
00834 }
00835 
00836 //#############################################################################
00837 
00842 template <class T> inline int
00843 CoinToFile( const T* array, CoinBigIndex size, FILE * fp)
00844 {
00845     CoinBigIndex numberWritten;
00846     if (array&&size) {
00847         numberWritten =
00848             static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp));
00849         if (numberWritten!=1)
00850             return 1;
00851         numberWritten =
00852             static_cast<CoinBigIndex>(fwrite(array,sizeof(T),size_t(size),fp));
00853         if (numberWritten!=size)
00854             return 1;
00855     } else {
00856         size = 0;
00857         numberWritten = 
00858             static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp));
00859         if (numberWritten!=1)
00860             return 1;
00861     }
00862     return 0;
00863 }
00864 
00865 //#############################################################################
00866 
00873 template <class T> inline int
00874 CoinFromFile( T* &array, CoinBigIndex size, FILE * fp, CoinBigIndex & newSize)
00875 {
00876     CoinBigIndex numberRead;
00877     numberRead =
00878         static_cast<CoinBigIndex>(fread(&newSize,sizeof(int),1,fp));
00879     if (numberRead!=1)
00880         return 1;
00881     int returnCode=0;
00882     if (size!=newSize&&(newSize||array))
00883         returnCode=2;
00884     if (newSize) {
00885         array = new T [newSize];
00886         numberRead =
00887             static_cast<CoinBigIndex>(fread(array,sizeof(T),newSize,fp));
00888         if (numberRead!=newSize)
00889             returnCode=1;
00890     } else {
00891         array = NULL;
00892     }
00893     return returnCode;
00894 }
00895 
00896 //#############################################################################
00897 
00899 inline double CoinCbrt(double x)
00900 {
00901 #if defined(_MSC_VER) 
00902     return pow(x,(1./3.));
00903 #else
00904     return cbrt(x);
00905 #endif
00906 }
00907 //-----------------------------------------------------------------------------
00908 
00910 #define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type)))
00912 inline int
00913 CoinStrlenAsInt(const char * string)
00914 {
00915     return static_cast<int>(strlen(string));
00916 }
00917 
00920 #if defined COIN_OWN_RANDOM_32
00921 class CoinThreadRandom  {
00922 public:
00927   CoinThreadRandom()
00928   { seed_=12345678;}
00930   CoinThreadRandom(int seed)
00931   { 
00932     seed_ = seed;
00933   }
00935   ~CoinThreadRandom() {}
00936   // Copy
00937   CoinThreadRandom(const CoinThreadRandom & rhs)
00938   { seed_ = rhs.seed_;}
00939   // Assignment
00940   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00941   {
00942     if (this != &rhs) {
00943       seed_ = rhs.seed_;
00944     }
00945     return *this;
00946   }
00947 
00949   
00954   inline void setSeed(int seed)
00955   { 
00956     seed_ = seed;
00957   }
00959   inline unsigned int getSeed() const
00960   { 
00961     return seed_;
00962   }
00964   inline double randomDouble() const
00965   {
00966     double retVal;
00967     seed_ = 1664525*(seed_)+1013904223;
00968     retVal = ((static_cast<double> (seed_))/4294967296.0);
00969     return retVal;
00970   }
00972   
00973   
00974 protected:
00978 
00979   mutable unsigned int seed_;
00981 };
00982 #else
00983 class CoinThreadRandom  {
00984 public:
00989   CoinThreadRandom()
00990   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00992   CoinThreadRandom(const unsigned short seed[3])
00993   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00995   CoinThreadRandom(int seed)
00996   { 
00997     union { int i[2]; unsigned short int s[4];} put;
00998     put.i[0]=seed;
00999     put.i[1]=seed;
01000     memcpy(seed_,put.s,3*sizeof(unsigned short));
01001   }
01003   ~CoinThreadRandom() {}
01004   // Copy
01005   CoinThreadRandom(const CoinThreadRandom & rhs)
01006   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
01007   // Assignment
01008   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
01009   {
01010     if (this != &rhs) {
01011       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
01012     }
01013     return *this;
01014   }
01015 
01017   
01022   inline void setSeed(const unsigned short seed[3])
01023   { memcpy(seed_,seed,3*sizeof(unsigned short));}
01025   inline void setSeed(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   inline double randomDouble() const
01034   {
01035     double retVal;
01036 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
01037     retVal=rand();
01038     retVal=retVal/(double) RAND_MAX;
01039 #else
01040     retVal = erand48(seed_);
01041 #endif
01042     return retVal;
01043   }
01045   
01046   
01047 protected:
01051 
01052   mutable unsigned short seed_[3];
01054 };
01055 #endif
01056 #endif

Generated on Fri Nov 5 03:05:36 2010 by  doxygen 1.4.7