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

- File List
- File Members

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

Go to the documentation of this file.

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