- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# /home/coin/SVN-release/Cgl-0.53.1/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||size) {
    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 #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     std::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
    00492 inline char * CoinStrdup(const char * name)
    00493 {
    00494   char* dup = NULL;
    00495   if (name) {
    00496     const int len = strlen(name);
    00497     dup = (char*)malloc(len+1);
    00498     CoinMemcpyN(name, len, dup);
    00499     dup[len] = 0;
    00500   }
    00501   return dup;
    00502 }
    00503
    00504 //#############################################################################
    00505
    00509 template <class T> inline T
    00510 CoinMax(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 CoinMin(register const T x1, register const T x2)
    00522 {
    00523     return (x1 < x2) ? x1 : x2;
    00524 }
    00525
    00526 //-----------------------------------------------------------------------------
    00527
    00531 template <class T> inline T
    00532 CoinAbs(const T value)
    00533 {
    00534     return value<0 ? -value : value;
    00535 }
    00536
    00537 //#############################################################################
    00538
    00542 template <class T> inline bool
    00543 CoinIsSorted(register const T* first, const int size)
    00544 {
    00545     if (size == 0)
    00546         return true;
    00547
    00548     if (size < 0)
    00549         throw CoinError("negative number of entries", "CoinIsSorted", "");
    00550
    00551 #if 1
    00552     // size1 is the number of comparisons to be made
    00553     const int size1 = size  - 1;
    00554     for (register int n = size1 / 8; n > 0; --n, first += 8) {
    00555         if (first[8] < first[7]) return false;
    00556         if (first[7] < first[6]) return false;
    00557         if (first[6] < first[5]) return false;
    00558         if (first[5] < first[4]) return false;
    00559         if (first[4] < first[3]) return false;
    00560         if (first[3] < first[2]) return false;
    00561         if (first[2] < first[1]) return false;
    00562         if (first[1] < first[0]) return false;
    00563     }
    00564
    00565     switch (size1 % 8) {
    00566     case 7: if (first[7] < first[6]) return false;
    00567     case 6: if (first[6] < first[5]) return false;
    00568     case 5: if (first[5] < first[4]) return false;
    00569     case 4: if (first[4] < first[3]) return false;
    00570     case 3: if (first[3] < first[2]) return false;
    00571     case 2: if (first[2] < first[1]) return false;
    00572     case 1: if (first[1] < first[0]) return false;
    00573     case 0: break;
    00574     }
    00575 #else
    00576     register const T* next = first;
    00577     register const T* last = first + size;
    00578     for (++next; next != last; first = next, ++next)
    00579         if (*next < *first)
    00580             return false;
    00581 #endif
    00582     return true;
    00583 }
    00584
    00585 //-----------------------------------------------------------------------------
    00586
    00590 template <class T> inline bool
    00591 CoinIsSorted(register const T* first, register const T* last)
    00592 {
    00593     return CoinIsSorted(first, static_cast<int>(last - first));
    00594 }
    00595
    00596 //#############################################################################
    00597
    00601 template <class T> inline void
    00602 CoinIotaN(register T* first, const int size, register T init)
    00603 {
    00604     if (size == 0)
    00605         return;
    00606
    00607     if (size < 0)
    00608         throw CoinError("negative number of entries", "CoinIotaN", "");
    00609
    00610 #if 1
    00611     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
    00612         first[0] = init;
    00613         first[1] = init + 1;
    00614         first[2] = init + 2;
    00615         first[3] = init + 3;
    00616         first[4] = init + 4;
    00617         first[5] = init + 5;
    00618         first[6] = init + 6;
    00619         first[7] = init + 7;
    00620     }
    00621     switch (size % 8) {
    00622     case 7: first[6] = init + 6;
    00623     case 6: first[5] = init + 5;
    00624     case 5: first[4] = init + 4;
    00625     case 4: first[3] = init + 3;
    00626     case 3: first[2] = init + 2;
    00627     case 2: first[1] = init + 1;
    00628     case 1: first[0] = init;
    00629     case 0: break;
    00630     }
    00631 #else
    00632     // Use Duff's device to fill
    00633     register int n = (size + 7) / 8;
    00634     --first;
    00635     --init;
    00636     switch (size % 8) {
    00637     case 0: do{     *++first = ++init;
    00638     case 7:         *++first = ++init;
    00639     case 6:         *++first = ++init;
    00640     case 5:         *++first = ++init;
    00641     case 4:         *++first = ++init;
    00642     case 3:         *++first = ++init;
    00643     case 2:         *++first = ++init;
    00644     case 1:         *++first = ++init;
    00645     }while(--n>0);
    00646     }
    00647 #endif
    00648 }
    00649
    00650 //-----------------------------------------------------------------------------
    00651
    00655 template <class T> inline void
    00656 CoinIota(T* first, const T* last, T init)
    00657 {
    00658     CoinIotaN(first, last-first, init);
    00659 }
    00660
    00661 //#############################################################################
    00662
    00668 template <class T> inline T *
    00669 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
    00670                            const int * firstDelPos, const int * lastDelPos)
    00671 {
    00672     int delNum = lastDelPos - firstDelPos;
    00673     if (delNum == 0)
    00674         return arrayLast;
    00675
    00676     if (delNum < 0)
    00677         throw CoinError("trying to delete negative number of entries",
    00678                         "CoinDeleteEntriesFromArray", "");
    00679
    00680     int * delSortedPos = NULL;
    00681     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
    00682            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
    00683         // the positions of the to be deleted is either not sorted or not unique
    00684         delSortedPos = new int[delNum];
    00685         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
    00686         std::sort(delSortedPos, delSortedPos + delNum);
    00687         delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
    00688     }
    00689     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
    00690
    00691     const int last = delNum - 1;
    00692     int size = delSorted[0];
    00693     for (int i = 0; i < last; ++i) {
    00694         const int copyFirst = delSorted[i] + 1;
    00695         const int copyLast = delSorted[i+1];
    00696         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
    00697                  arrayFirst + size);
    00698         size += copyLast - copyFirst;
    00699     }
    00700     const int copyFirst = delSorted[last] + 1;
    00701     const int copyLast = arrayLast - arrayFirst;
    00702     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
    00703              arrayFirst + size);
    00704     size += copyLast - copyFirst;
    00705
    00706     if (delSortedPos)
    00707         delete[] delSortedPos;
    00708
    00709     return arrayFirst + size;
    00710 }
    00711
    00712 //#############################################################################
    00713
    00714 #define COIN_OWN_RANDOM_32
    00715
    00716 #if defined COIN_OWN_RANDOM_32
    00717 /* Thanks to Stefano Gliozzi for providing an operating system
    00718    independent random number generator.  */
    00719
    00720 // linear congruential generator. given the seed, the generated numbers are
    00721 // always the same regardless the (32 bit) architecture. This allows to
    00722 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
    00723 // getting in most cases the same optimization path.
    00725 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
    00726 {
    00727   static unsigned int last = 123456;
    00728   if (isSeed) {
    00729     last = seed;
    00730   } else {
    00731     last = 1664525*last+1013904223;
    00732     return (((double) last)/4294967296.0);
    00733   }
    00734   return(0.0);
    00735 }
    00737 inline void CoinSeedRandom(int iseed)
    00738 {
    00739   CoinDrand48(true, iseed);
    00740 }
    00741
    00742 #else // COIN_OWN_RANDOM_32
    00743
    00744 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
    00745
    00746 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
    00747 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
    00748
    00749 #else
    00750
    00751 inline double CoinDrand48() { return drand48(); }
    00752 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
    00753
    00754 #endif
    00755
    00756 #endif // COIN_OWN_RANDOM_32
    00757
    00758 //#############################################################################
    00759
    00762 inline char CoinFindDirSeparator()
    00763 {
    00764     int size = 1000;
    00765     char* buf = 0;
    00766     while (true) {
    00767         buf = new char[size];
    00768         if (getcwd(buf, size))
    00769             break;
    00770         delete[] buf;
    00771         buf = 0;
    00772         size = 2*size;
    00773     }
    00774     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we
    00775     // assume it's dos and the dirsep is '\'
    00776     char dirsep = buf[0] == '/' ? '/' : '\\';
    00777     delete[] buf;
    00778     return dirsep;
    00779 }
    00780 //#############################################################################
    00781
    00782 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
    00783                            const size_t len)
    00784 {
    00785     for (size_t i = 0; i < len; ++i) {
    00786         if (s0[i] == 0) {
    00787             return s1[i] == 0 ? 0 : -1;
    00788         }
    00789         if (s1[i] == 0) {
    00790             return 1;
    00791         }
    00792         const int c0 = tolower(s0[i]);
    00793         const int c1 = tolower(s1[i]);
    00794         if (c0 < c1)
    00795             return -1;
    00796         if (c0 > c1)
    00797             return 1;
    00798     }
    00799     return 0;
    00800 }
    00801
    00802 //#############################################################################
    00803
    00805 template <class T> inline void CoinSwap (T &x, T &y)
    00806 {
    00807     T t = x;
    00808     x = y;
    00809     y = t;
    00810 }
    00811
    00812 //#############################################################################
    00813
    00818 template <class T> inline int
    00819 CoinToFile( const T* array, int size, FILE * fp)
    00820 {
    00821     int numberWritten;
    00822     if (array&&size) {
    00823         numberWritten = fwrite(&size,sizeof(int),1,fp);
    00824         if (numberWritten!=1)
    00825             return 1;
    00826         numberWritten = fwrite(array,sizeof(T),size,fp);
    00827         if (numberWritten!=size)
    00828             return 1;
    00829     } else {
    00830         size = 0;
    00831         numberWritten = fwrite(&size,sizeof(int),1,fp);
    00832         if (numberWritten!=1)
    00833             return 1;
    00834     }
    00835     return 0;
    00836 }
    00837
    00838 //#############################################################################
    00839
    00846 template <class T> inline int
    00847 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
    00848 {
    00849     int numberRead;
    00850     numberRead = fread(&newSize,sizeof(int),1,fp);
    00851     if (numberRead!=1)
    00852         return 1;
    00853     int returnCode=0;
    00854     if (size!=newSize&&(newSize||array))
    00855         returnCode=2;
    00856     if (newSize) {
    00857         array = new T [newSize];
    00858         numberRead = fread(array,sizeof(T),newSize,fp);
    00859         if (numberRead!=newSize)
    00860             returnCode=1;
    00861     } else {
    00862         array = NULL;
    00863     }
    00864     return returnCode;
    00865 }
    00866
    00867 //#############################################################################
    00868
    00870 inline double CoinCbrt(double x)
    00871 {
    00872 #if defined(_MSC_VER)
    00873     return pow(x,(1./3.));
    00874 #else
    00875     return cbrt(x);
    00876 #endif
    00877 }
    00880 #if defined COIN_OWN_RANDOM_32
    00881 class CoinThreadRandom  {
    00882 public:
    00887   CoinThreadRandom()
    00888   { seed_=12345678;}
    00890   CoinThreadRandom(int seed)
    00891   {
    00892     seed_ = seed;
    00893   }
    00895   ~CoinThreadRandom() {}
    00896   // Copy
    00897   CoinThreadRandom(const CoinThreadRandom & rhs)
    00898   { seed_ = rhs.seed_;}
    00899   // Assignment
    00900   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
    00901   {
    00902     if (this != &rhs) {
    00903       seed_ = rhs.seed_;
    00904     }
    00905     return *this;
    00906   }
    00907
    00909
    00914   inline void setSeed(int seed)
    00915   {
    00916     seed_ = seed;
    00917   }
    00919   inline double randomDouble() const
    00920   {
    00921     double retVal;
    00922     seed_ = 1664525*(seed_)+1013904223;
    00923     retVal = (((double) seed_)/4294967296.0);
    00924     return retVal;
    00925   }
    00927
    00928
    00929 protected:
    00933
    00934   mutable unsigned int seed_;
    00936 };
    00937 #else
    00938 class CoinThreadRandom  {
    00939 public:
    00944   CoinThreadRandom()
    00945   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
    00947   CoinThreadRandom(const unsigned short seed[3])
    00948   { memcpy(seed_,seed,3*sizeof(unsigned short));}
    00950   CoinThreadRandom(int seed)
    00951   {
    00952     union { int i[2]; unsigned short int s[4];} put;
    00953     put.i[0]=seed;
    00954     put.i[1]=seed;
    00955     memcpy(seed_,put.s,3*sizeof(unsigned short));
    00956   }
    00958   ~CoinThreadRandom() {}
    00959   // Copy
    00960   CoinThreadRandom(const CoinThreadRandom & rhs)
    00961   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
    00962   // Assignment
    00963   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
    00964   {
    00965     if (this != &rhs) {
    00966       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
    00967     }
    00968     return *this;
    00969   }
    00970
    00972
    00977   inline void setSeed(const unsigned short seed[3])
    00978   { memcpy(seed_,seed,3*sizeof(unsigned short));}
    00980   inline void setSeed(int seed)
    00981   {
    00982     union { int i[2]; unsigned short int s[4];} put;
    00983     put.i[0]=seed;
    00984     put.i[1]=seed;
    00985     memcpy(seed_,put.s,3*sizeof(unsigned short));
    00986   }
    00988   inline double randomDouble() const
    00989   {
    00990     double retVal;
    00991 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
    00992     retVal=rand();
    00993     retVal=retVal/(double) RAND_MAX;
    00994 #else
    00995     retVal = erand48(seed_);
    00996 #endif
    00997     return retVal;
    00998   }
    01000
    01001
    01002 protected:
    01006
    01007   mutable unsigned short seed_[3];
    01009 };
    01010 #endif
    01011 #endif