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

- File List
- File Members

# /home/coin/SVN-release/Bcps-0.91.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 //#define USE_MEMCPY
    00013
    00014 #include <cstdlib>
    00015 #include <cstdio>
    00016 #include "CoinError.hpp"
    00017 #include "CoinFinite.hpp"
    00018 //#############################################################################
    00019
    00025 template <class T> inline void
    00026 CoinCopyN(register const T* from, const int size, register T* to)
    00027 {
    00028     if (size == 0 || from == to)
    00029         return;
    00030
    00031     if (size < 0)
    00032         throw CoinError("trying to copy negative number of entries",
    00033                         "CoinCopyN", "");
    00034
    00035     register int n = (size + 7) / 8;
    00036     if (to > from) {
    00037         register const T* downfrom = from + size;
    00038         register T* downto = to + size;
    00039         // Use Duff's device to copy
    00040         switch (size % 8) {
    00041         case 0: do{     *--downto = *--downfrom;
    00042         case 7:         *--downto = *--downfrom;
    00043         case 6:         *--downto = *--downfrom;
    00044         case 5:         *--downto = *--downfrom;
    00045         case 4:         *--downto = *--downfrom;
    00046         case 3:         *--downto = *--downfrom;
    00047         case 2:         *--downto = *--downfrom;
    00048         case 1:         *--downto = *--downfrom;
    00049         }while(--n>0);
    00050         }
    00051     } else {
    00052         // Use Duff's device to copy
    00053         --from;
    00054         --to;
    00055         switch (size % 8) {
    00056         case 0: do{     *++to = *++from;
    00057         case 7:         *++to = *++from;
    00058         case 6:         *++to = *++from;
    00059         case 5:         *++to = *++from;
    00060         case 4:         *++to = *++from;
    00061         case 3:         *++to = *++from;
    00062         case 2:         *++to = *++from;
    00063         case 1:         *++to = *++from;
    00064         }while(--n>0);
    00065         }
    00066     }
    00067 }
    00068
    00069 //-----------------------------------------------------------------------------
    00070
    00075 template <class T> inline void
    00076 CoinCopy(register const T* first, register const T* last, register T* to)
    00077 {
    00078     CoinCopyN(first, last - first, to);
    00079 }
    00080
    00081 //-----------------------------------------------------------------------------
    00082
    00090 template <class T> inline void
    00091 CoinDisjointCopyN(register const T* from, const int size, register T* to)
    00092 {
    00093 #ifndef _MSC_VER
    00094     if (size == 0 || from == to)
    00095         return;
    00096
    00097     if (size < 0)
    00098         throw CoinError("trying to copy negative number of entries",
    00099                         "CoinDisjointCopyN", "");
    00100
    00101 #if 0
    00102     /* There is no point to do this test. If to and from are from different
    00103        blocks then dist is undefined, so this can crash correct code. It's
    00104        better to trust the user that the arrays are really disjoint. */
    00105     const long dist = to - from;
    00106     if (-size < dist && dist < size)
    00107         throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
    00108 #endif
    00109
    00110     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
    00111         to[0] = from[0];
    00112         to[1] = from[1];
    00113         to[2] = from[2];
    00114         to[3] = from[3];
    00115         to[4] = from[4];
    00116         to[5] = from[5];
    00117         to[6] = from[6];
    00118         to[7] = from[7];
    00119     }
    00120     switch (size % 8) {
    00121     case 7: to[6] = from[6];
    00122     case 6: to[5] = from[5];
    00123     case 5: to[4] = from[4];
    00124     case 4: to[3] = from[3];
    00125     case 3: to[2] = from[2];
    00126     case 2: to[1] = from[1];
    00127     case 1: to[0] = from[0];
    00128     case 0: break;
    00129     }
    00130 #else
    00131     CoinCopyN(from, size, to);
    00132 #endif
    00133 }
    00134
    00135 //-----------------------------------------------------------------------------
    00136
    00141 template <class T> inline void
    00142 CoinDisjointCopy(register const T* first, register const T* last,
    00143                  register T* to)
    00144 {
    00145     CoinDisjointCopyN(first, static_cast<int>(last - first), to);
    00146 }
    00147
    00148 //-----------------------------------------------------------------------------
    00149
    00154 template <class T> inline T*
    00155 CoinCopyOfArray( const T * array, const int size)
    00156 {
    00157     if (array) {
    00158         T * arrayNew = new T[size];
    00159         std::memcpy(arrayNew,array,size*sizeof(T));
    00160         return arrayNew;
    00161     } else {
    00162         return NULL;
    00163     }
    00164 }
    00165
    00166
    00171 template <class T> inline T*
    00172 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
    00173 {
    00174     if (array||size) {
    00175         T * arrayNew = new T[size];
    00176         assert (copySize<=size);
    00177         std::memcpy(arrayNew,array,copySize*sizeof(T));
    00178         return arrayNew;
    00179     } else {
    00180         return NULL;
    00181     }
    00182 }
    00183
    00188 template <class T> inline T*
    00189 CoinCopyOfArray( const T * array, const int size, T value)
    00190 {
    00191     T * arrayNew = new T[size];
    00192     if (array) {
    00193         std::memcpy(arrayNew,array,size*sizeof(T));
    00194     } else {
    00195         int i;
    00196         for (i=0;i<size;i++)
    00197             arrayNew[i] = value;
    00198     }
    00199     return arrayNew;
    00200 }
    00201
    00202
    00207 template <class T> inline T*
    00208 CoinCopyOfArrayOrZero( const T * array , const int size)
    00209 {
    00210     T * arrayNew = new T[size];
    00211     if (array) {
    00212       std::memcpy(arrayNew,array,size*sizeof(T));
    00213     } else {
    00214       std::memset(arrayNew,0,size*sizeof(T));
    00215     }
    00216     return arrayNew;
    00217 }
    00218
    00219
    00220 //-----------------------------------------------------------------------------
    00221
    00229 #ifndef COIN_USE_RESTRICT
    00230 template <class T> inline void
    00231 CoinMemcpyN(register const T* from, const int size, register T* to)
    00232 {
    00233 #ifndef _MSC_VER
    00234 #ifdef USE_MEMCPY
    00235     // Use memcpy - seems a lot faster on Intel with gcc
    00236 #ifndef NDEBUG
    00237     // Some debug so check
    00238     if (size < 0)
    00239         throw CoinError("trying to copy negative number of entries",
    00240                         "CoinMemcpyN", "");
    00241
    00242 #if 0
    00243     /* There is no point to do this test. If to and from are from different
    00244        blocks then dist is undefined, so this can crash correct code. It's
    00245        better to trust the user that the arrays are really disjoint. */
    00246     const long dist = to - from;
    00247     if (-size < dist && dist < size)
    00248         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
    00249 #endif
    00250 #endif
    00251     std::memcpy(to,from,size*sizeof(T));
    00252 #else
    00253     if (size == 0 || from == to)
    00254         return;
    00255
    00256     if (size < 0)
    00257         throw CoinError("trying to copy negative number of entries",
    00258                         "CoinMemcpyN", "");
    00259
    00260 #if 0
    00261     /* There is no point to do this test. If to and from are from different
    00262        blocks then dist is undefined, so this can crash correct code. It's
    00263        better to trust the user that the arrays are really disjoint. */
    00264     const long dist = to - from;
    00265     if (-size < dist && dist < size)
    00266         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
    00267 #endif
    00268
    00269     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
    00270         to[0] = from[0];
    00271         to[1] = from[1];
    00272         to[2] = from[2];
    00273         to[3] = from[3];
    00274         to[4] = from[4];
    00275         to[5] = from[5];
    00276         to[6] = from[6];
    00277         to[7] = from[7];
    00278     }
    00279     switch (size % 8) {
    00280     case 7: to[6] = from[6];
    00281     case 6: to[5] = from[5];
    00282     case 5: to[4] = from[4];
    00283     case 4: to[3] = from[3];
    00284     case 3: to[2] = from[2];
    00285     case 2: to[1] = from[1];
    00286     case 1: to[0] = from[0];
    00287     case 0: break;
    00288     }
    00289 #endif
    00290 #else
    00291     CoinCopyN(from, size, to);
    00292 #endif
    00293 }
    00294 #else
    00295 template <class T> inline void
    00296 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
    00297 {
    00298 #ifdef USE_MEMCPY
    00299   std::memcpy(to,from,size*sizeof(T));
    00300 #else
    00301   T * COIN_RESTRICT put =  to;
    00302   const T * COIN_RESTRICT get = from;
    00303   for ( ; 0<size ; --size)
    00304     *put++ = *get++;
    00305 #endif
    00306 }
    00307 #endif
    00308
    00309 //-----------------------------------------------------------------------------
    00310
    00315 template <class T> inline void
    00316 CoinMemcpy(register const T* first, register const T* last,
    00317            register T* to)
    00318 {
    00319     CoinMemcpyN(first, static_cast<int>(last - first), to);
    00320 }
    00321
    00322 //#############################################################################
    00323
    00330 template <class T> inline void
    00331 CoinFillN(register T* to, const int size, register const T value)
    00332 {
    00333     if (size == 0)
    00334         return;
    00335
    00336     if (size < 0)
    00337         throw CoinError("trying to fill negative number of entries",
    00338                         "CoinFillN", "");
    00339
    00340 #if 1
    00341     for (register int n = size / 8; n > 0; --n, to += 8) {
    00342         to[0] = value;
    00343         to[1] = value;
    00344         to[2] = value;
    00345         to[3] = value;
    00346         to[4] = value;
    00347         to[5] = value;
    00348         to[6] = value;
    00349         to[7] = value;
    00350     }
    00351     switch (size % 8) {
    00352     case 7: to[6] = value;
    00353     case 6: to[5] = value;
    00354     case 5: to[4] = value;
    00355     case 4: to[3] = value;
    00356     case 3: to[2] = value;
    00357     case 2: to[1] = value;
    00358     case 1: to[0] = value;
    00359     case 0: break;
    00360     }
    00361 #else
    00362     // Use Duff's device to fill
    00363     register int n = (size + 7) / 8;
    00364     --to;
    00365     switch (size % 8) {
    00366     case 0: do{     *++to = value;
    00367     case 7:         *++to = value;
    00368     case 6:         *++to = value;
    00369     case 5:         *++to = value;
    00370     case 4:         *++to = value;
    00371     case 3:         *++to = value;
    00372     case 2:         *++to = value;
    00373     case 1:         *++to = value;
    00374     }while(--n>0);
    00375     }
    00376 #endif
    00377 }
    00378
    00379 //-----------------------------------------------------------------------------
    00380
    00384 template <class T> inline void
    00385 CoinFill(register T* first, register T* last, const T value)
    00386 {
    00387     CoinFillN(first, last - first, value);
    00388 }
    00389
    00390 //#############################################################################
    00391
    00398 template <class T> inline void
    00399 CoinZeroN(register T* to, const int size)
    00400 {
    00401 #ifdef USE_MEMCPY
    00402     // Use memset - seems faster on Intel with gcc
    00403 #ifndef NDEBUG
    00404     // Some debug so check
    00405     if (size < 0)
    00406         throw CoinError("trying to fill negative number of entries",
    00407                         "CoinZeroN", "");
    00408 #endif
    00409     memset(to,0,size*sizeof(T));
    00410 #else
    00411     if (size == 0)
    00412         return;
    00413
    00414     if (size < 0)
    00415         throw CoinError("trying to fill negative number of entries",
    00416                         "CoinZeroN", "");
    00417 #if 1
    00418     for (register int n = size / 8; n > 0; --n, to += 8) {
    00419         to[0] = 0;
    00420         to[1] = 0;
    00421         to[2] = 0;
    00422         to[3] = 0;
    00423         to[4] = 0;
    00424         to[5] = 0;
    00425         to[6] = 0;
    00426         to[7] = 0;
    00427     }
    00428     switch (size % 8) {
    00429     case 7: to[6] = 0;
    00430     case 6: to[5] = 0;
    00431     case 5: to[4] = 0;
    00432     case 4: to[3] = 0;
    00433     case 3: to[2] = 0;
    00434     case 2: to[1] = 0;
    00435     case 1: to[0] = 0;
    00436     case 0: break;
    00437     }
    00438 #else
    00439     // Use Duff's device to fill
    00440     register int n = (size + 7) / 8;
    00441     --to;
    00442     switch (size % 8) {
    00443     case 0: do{     *++to = 0;
    00444     case 7:         *++to = 0;
    00445     case 6:         *++to = 0;
    00446     case 5:         *++to = 0;
    00447     case 4:         *++to = 0;
    00448     case 3:         *++to = 0;
    00449     case 2:         *++to = 0;
    00450     case 1:         *++to = 0;
    00451     }while(--n>0);
    00452     }
    00453 #endif
    00454 #endif
    00455 }
    00457 inline void
    00458 CoinCheckDoubleZero(double * to, const int size)
    00459 {
    00460     int n=0;
    00461     for (int j=0;j<size;j++) {
    00462         if (to[j])
    00463             n++;
    00464     }
    00465     if (n) {
    00466         printf("array of length %d should be zero has %d nonzero\n",size,n);
    00467     }
    00468 }
    00470 inline void
    00471 CoinCheckIntZero(int * to, const int size)
    00472 {
    00473     int n=0;
    00474     for (int j=0;j<size;j++) {
    00475         if (to[j])
    00476             n++;
    00477     }
    00478     if (n) {
    00479         printf("array of length %d should be zero has %d nonzero\n",size,n);
    00480     }
    00481 }
    00482
    00483 //-----------------------------------------------------------------------------
    00484
    00488 template <class T> inline void
    00489 CoinZero(register T* first, register T* last)
    00490 {
    00491     CoinZeroN(first, last - first);
    00492 }
    00493
    00494 //#############################################################################
    00495
    00497 inline char * CoinStrdup(const char * name)
    00498 {
    00499   char* dup = NULL;
    00500   if (name) {
    00501     const int len = static_cast<int>(strlen(name));
    00502     dup = static_cast<char*>(malloc(len+1));
    00503     CoinMemcpyN(name, len, dup);
    00504     dup[len] = 0;
    00505   }
    00506   return dup;
    00507 }
    00508
    00509 //#############################################################################
    00510
    00514 template <class T> inline T
    00515 CoinMax(register const T x1, register const T x2)
    00516 {
    00517     return (x1 > x2) ? x1 : x2;
    00518 }
    00519
    00520 //-----------------------------------------------------------------------------
    00521
    00525 template <class T> inline T
    00526 CoinMin(register const T x1, register const T x2)
    00527 {
    00528     return (x1 < x2) ? x1 : x2;
    00529 }
    00530
    00531 //-----------------------------------------------------------------------------
    00532
    00536 template <class T> inline T
    00537 CoinAbs(const T value)
    00538 {
    00539     return value<0 ? -value : value;
    00540 }
    00541
    00542 //#############################################################################
    00543
    00547 template <class T> inline bool
    00548 CoinIsSorted(register const T* first, const int size)
    00549 {
    00550     if (size == 0)
    00551         return true;
    00552
    00553     if (size < 0)
    00554         throw CoinError("negative number of entries", "CoinIsSorted", "");
    00555
    00556 #if 1
    00557     // size1 is the number of comparisons to be made
    00558     const int size1 = size  - 1;
    00559     for (register int n = size1 / 8; n > 0; --n, first += 8) {
    00560         if (first[8] < first[7]) return false;
    00561         if (first[7] < first[6]) return false;
    00562         if (first[6] < first[5]) return false;
    00563         if (first[5] < first[4]) return false;
    00564         if (first[4] < first[3]) return false;
    00565         if (first[3] < first[2]) return false;
    00566         if (first[2] < first[1]) return false;
    00567         if (first[1] < first[0]) return false;
    00568     }
    00569
    00570     switch (size1 % 8) {
    00571     case 7: if (first[7] < first[6]) return false;
    00572     case 6: if (first[6] < first[5]) return false;
    00573     case 5: if (first[5] < first[4]) return false;
    00574     case 4: if (first[4] < first[3]) return false;
    00575     case 3: if (first[3] < first[2]) return false;
    00576     case 2: if (first[2] < first[1]) return false;
    00577     case 1: if (first[1] < first[0]) return false;
    00578     case 0: break;
    00579     }
    00580 #else
    00581     register const T* next = first;
    00582     register const T* last = first + size;
    00583     for (++next; next != last; first = next, ++next)
    00584         if (*next < *first)
    00585             return false;
    00586 #endif
    00587     return true;
    00588 }
    00589
    00590 //-----------------------------------------------------------------------------
    00591
    00595 template <class T> inline bool
    00596 CoinIsSorted(register const T* first, register const T* last)
    00597 {
    00598     return CoinIsSorted(first, static_cast<int>(last - first));
    00599 }
    00600
    00601 //#############################################################################
    00602
    00606 template <class T> inline void
    00607 CoinIotaN(register T* first, const int size, register T init)
    00608 {
    00609     if (size == 0)
    00610         return;
    00611
    00612     if (size < 0)
    00613         throw CoinError("negative number of entries", "CoinIotaN", "");
    00614
    00615 #if 1
    00616     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
    00617         first[0] = init;
    00618         first[1] = init + 1;
    00619         first[2] = init + 2;
    00620         first[3] = init + 3;
    00621         first[4] = init + 4;
    00622         first[5] = init + 5;
    00623         first[6] = init + 6;
    00624         first[7] = init + 7;
    00625     }
    00626     switch (size % 8) {
    00627     case 7: first[6] = init + 6;
    00628     case 6: first[5] = init + 5;
    00629     case 5: first[4] = init + 4;
    00630     case 4: first[3] = init + 3;
    00631     case 3: first[2] = init + 2;
    00632     case 2: first[1] = init + 1;
    00633     case 1: first[0] = init;
    00634     case 0: break;
    00635     }
    00636 #else
    00637     // Use Duff's device to fill
    00638     register int n = (size + 7) / 8;
    00639     --first;
    00640     --init;
    00641     switch (size % 8) {
    00642     case 0: do{     *++first = ++init;
    00643     case 7:         *++first = ++init;
    00644     case 6:         *++first = ++init;
    00645     case 5:         *++first = ++init;
    00646     case 4:         *++first = ++init;
    00647     case 3:         *++first = ++init;
    00648     case 2:         *++first = ++init;
    00649     case 1:         *++first = ++init;
    00650     }while(--n>0);
    00651     }
    00652 #endif
    00653 }
    00654
    00655 //-----------------------------------------------------------------------------
    00656
    00660 template <class T> inline void
    00661 CoinIota(T* first, const T* last, T init)
    00662 {
    00663     CoinIotaN(first, last-first, init);
    00664 }
    00665
    00666 //#############################################################################
    00667
    00673 template <class T> inline T *
    00674 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
    00675                            const int * firstDelPos, const int * lastDelPos)
    00676 {
    00677     int delNum = lastDelPos - firstDelPos;
    00678     if (delNum == 0)
    00679         return arrayLast;
    00680
    00681     if (delNum < 0)
    00682         throw CoinError("trying to delete negative number of entries",
    00683                         "CoinDeleteEntriesFromArray", "");
    00684
    00685     int * delSortedPos = NULL;
    00686     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
    00687            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
    00688         // the positions of the to be deleted is either not sorted or not unique
    00689         delSortedPos = new int[delNum];
    00690         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
    00691         std::sort(delSortedPos, delSortedPos + delNum);
    00692         delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
    00693     }
    00694     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
    00695
    00696     const int last = delNum - 1;
    00697     int size = delSorted[0];
    00698     for (int i = 0; i < last; ++i) {
    00699         const int copyFirst = delSorted[i] + 1;
    00700         const int copyLast = delSorted[i+1];
    00701         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
    00702                  arrayFirst + size);
    00703         size += copyLast - copyFirst;
    00704     }
    00705     const int copyFirst = delSorted[last] + 1;
    00706     const int copyLast = arrayLast - arrayFirst;
    00707     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
    00708              arrayFirst + size);
    00709     size += copyLast - copyFirst;
    00710
    00711     if (delSortedPos)
    00712         delete[] delSortedPos;
    00713
    00714     return arrayFirst + size;
    00715 }
    00716
    00717 //#############################################################################
    00718
    00719 #define COIN_OWN_RANDOM_32
    00720
    00721 #if defined COIN_OWN_RANDOM_32
    00722 /* Thanks to Stefano Gliozzi for providing an operating system
    00723    independent random number generator.  */
    00724
    00725 // linear congruential generator. given the seed, the generated numbers are
    00726 // always the same regardless the (32 bit) architecture. This allows to
    00727 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
    00728 // getting in most cases the same optimization path.
    00730 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
    00731 {
    00732   static unsigned int last = 123456;
    00733   if (isSeed) {
    00734     last = seed;
    00735   } else {
    00736     last = 1664525*last+1013904223;
    00737     return ((static_cast<double> (last))/4294967296.0);
    00738   }
    00739   return(0.0);
    00740 }
    00742 inline void CoinSeedRandom(int iseed)
    00743 {
    00744   CoinDrand48(true, iseed);
    00745 }
    00746
    00747 #else // COIN_OWN_RANDOM_32
    00748
    00749 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
    00750
    00751 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
    00752 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
    00753
    00754 #else
    00755
    00756 inline double CoinDrand48() { return drand48(); }
    00757 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
    00758
    00759 #endif
    00760
    00761 #endif // COIN_OWN_RANDOM_32
    00762
    00763 //#############################################################################
    00764
    00767 inline char CoinFindDirSeparator()
    00768 {
    00769     int size = 1000;
    00770     char* buf = 0;
    00771     while (true) {
    00772         buf = new char[size];
    00773         if (getcwd(buf, size))
    00774             break;
    00775         delete[] buf;
    00776         buf = 0;
    00777         size = 2*size;
    00778     }
    00779     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we
    00780     // assume it's dos and the dirsep is '\'
    00781     char dirsep = buf[0] == '/' ? '/' : '\\';
    00782     delete[] buf;
    00783     return dirsep;
    00784 }
    00785 //#############################################################################
    00786
    00787 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
    00788                            const size_t len)
    00789 {
    00790     for (size_t i = 0; i < len; ++i) {
    00791         if (s0[i] == 0) {
    00792             return s1[i] == 0 ? 0 : -1;
    00793         }
    00794         if (s1[i] == 0) {
    00795             return 1;
    00796         }
    00797         const int c0 = tolower(s0[i]);
    00798         const int c1 = tolower(s1[i]);
    00799         if (c0 < c1)
    00800             return -1;
    00801         if (c0 > c1)
    00802             return 1;
    00803     }
    00804     return 0;
    00805 }
    00806
    00807 //#############################################################################
    00808
    00810 template <class T> inline void CoinSwap (T &x, T &y)
    00811 {
    00812     T t = x;
    00813     x = y;
    00814     y = t;
    00815 }
    00816
    00817 //#############################################################################
    00818
    00823 template <class T> inline int
    00824 CoinToFile( const T* array, int size, FILE * fp)
    00825 {
    00826     int numberWritten;
    00827     if (array&&size) {
    00828         numberWritten = fwrite(&size,sizeof(int),1,fp);
    00829         if (numberWritten!=1)
    00830             return 1;
    00831         numberWritten = fwrite(array,sizeof(T),size,fp);
    00832         if (numberWritten!=size)
    00833             return 1;
    00834     } else {
    00835         size = 0;
    00836         numberWritten = fwrite(&size,sizeof(int),1,fp);
    00837         if (numberWritten!=1)
    00838             return 1;
    00839     }
    00840     return 0;
    00841 }
    00842
    00843 //#############################################################################
    00844
    00851 template <class T> inline int
    00852 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
    00853 {
    00854     int numberRead;
    00855     numberRead = fread(&newSize,sizeof(int),1,fp);
    00856     if (numberRead!=1)
    00857         return 1;
    00858     int returnCode=0;
    00859     if (size!=newSize&&(newSize||array))
    00860         returnCode=2;
    00861     if (newSize) {
    00862         array = new T [newSize];
    00863         numberRead = fread(array,sizeof(T),newSize,fp);
    00864         if (numberRead!=newSize)
    00865             returnCode=1;
    00866     } else {
    00867         array = NULL;
    00868     }
    00869     return returnCode;
    00870 }
    00871
    00872 //#############################################################################
    00873
    00875 inline double CoinCbrt(double x)
    00876 {
    00877 #if defined(_MSC_VER)
    00878     return pow(x,(1./3.));
    00879 #else
    00880     return cbrt(x);
    00881 #endif
    00882 }
    00885 #if defined COIN_OWN_RANDOM_32
    00886 class CoinThreadRandom  {
    00887 public:
    00892   CoinThreadRandom()
    00893   { seed_=12345678;}
    00895   CoinThreadRandom(int seed)
    00896   {
    00897     seed_ = seed;
    00898   }
    00900   ~CoinThreadRandom() {}
    00901   // Copy
    00902   CoinThreadRandom(const CoinThreadRandom & rhs)
    00903   { seed_ = rhs.seed_;}
    00904   // Assignment
    00905   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
    00906   {
    00907     if (this != &rhs) {
    00908       seed_ = rhs.seed_;
    00909     }
    00910     return *this;
    00911   }
    00912
    00914
    00919   inline void setSeed(int seed)
    00920   {
    00921     seed_ = seed;
    00922   }
    00924   inline double randomDouble() const
    00925   {
    00926     double retVal;
    00927     seed_ = 1664525*(seed_)+1013904223;
    00928     retVal = ((static_cast<double> (seed_))/4294967296.0);
    00929     return retVal;
    00930   }
    00932
    00933
    00934 protected:
    00938
    00939   mutable unsigned int seed_;
    00941 };
    00942 #else
    00943 class CoinThreadRandom  {
    00944 public:
    00949   CoinThreadRandom()
    00950   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
    00952   CoinThreadRandom(const unsigned short seed[3])
    00953   { memcpy(seed_,seed,3*sizeof(unsigned short));}
    00955   CoinThreadRandom(int seed)
    00956   {
    00957     union { int i[2]; unsigned short int s[4];} put;
    00958     put.i[0]=seed;
    00959     put.i[1]=seed;
    00960     memcpy(seed_,put.s,3*sizeof(unsigned short));
    00961   }
    00963   ~CoinThreadRandom() {}
    00964   // Copy
    00965   CoinThreadRandom(const CoinThreadRandom & rhs)
    00966   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
    00967   // Assignment
    00968   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
    00969   {
    00970     if (this != &rhs) {
    00971       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
    00972     }
    00973     return *this;
    00974   }
    00975
    00977
    00982   inline void setSeed(const unsigned short seed[3])
    00983   { memcpy(seed_,seed,3*sizeof(unsigned short));}
    00985   inline void setSeed(int seed)
    00986   {
    00987     union { int i[2]; unsigned short int s[4];} put;
    00988     put.i[0]=seed;
    00989     put.i[1]=seed;
    00990     memcpy(seed_,put.s,3*sizeof(unsigned short));
    00991   }
    00993   inline double randomDouble() const
    00994   {
    00995     double retVal;
    00996 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
    00997     retVal=rand();
    00998     retVal=retVal/(double) RAND_MAX;
    00999 #else
    01000     retVal = erand48(seed_);
    01001 #endif
    01002     return retVal;
    01003   }
    01005
    01006
    01007 protected:
    01011
    01012   mutable unsigned short seed_[3];
    01014 };
    01015 #endif
    01016 #endif