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

- File List
- File Members

# /home/coin/SVN-release/CoinUtils-2.6.1/CoinUtils/src/CoinHelperFunctions.hpp

Go to the documentation of this file.

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