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

- File List
- File Members

# /home/coin/svn-release/Blis-0.93.10/CoinUtils/src/CoinHelperFunctions.hpp

Go to the documentation of this file.

    00001 /* $Id: CoinHelperFunctions.hpp 1678 2013-12-05 11:27:05Z forrest $ */
    00002 // Copyright (C) 2000, International Business Machines
    00003 // Corporation and others.  All Rights Reserved.
    00004 // This code is licensed under the terms of the Eclipse Public License (EPL).
    00005
    00006 #ifndef CoinHelperFunctions_H
    00007 #define CoinHelperFunctions_H
    00008
    00009 #include "CoinUtilsConfig.h"
    00010
    00011 #if defined(_MSC_VER)
    00012 #  include <direct.h>
    00013 #  include <cctype>
    00014 #  define getcwd _getcwd
    00015 #  include <cctype>
    00016 #else
    00017 #  include <unistd.h>
    00018 #endif
    00019 //#define USE_MEMCPY
    00020
    00021 #include <cstdlib>
    00022 #include <cstdio>
    00023 #include <algorithm>
    00024 #include "CoinTypes.hpp"
    00025 #include "CoinError.hpp"
    00026
    00027 // Compilers can produce better code if they know about __restrict
    00028 #ifndef COIN_RESTRICT
    00029 #ifdef COIN_USE_RESTRICT
    00030 #define COIN_RESTRICT __restrict
    00031 #else
    00032 #define COIN_RESTRICT
    00033 #endif
    00034 #endif
    00035
    00036 //#############################################################################
    00037
    00043 template <class T> inline void
    00044 CoinCopyN(register const T* from, const int size, register T* to)
    00045 {
    00046     if (size == 0 || from == to)
    00047         return;
    00048
    00049 #ifndef NDEBUG
    00050     if (size < 0)
    00051         throw CoinError("trying to copy negative number of entries",
    00052                         "CoinCopyN", "");
    00053 #endif
    00054
    00055     register int n = (size + 7) / 8;
    00056     if (to > from) {
    00057         register const T* downfrom = from + size;
    00058         register T* downto = to + size;
    00059         // Use Duff's device to copy
    00060         switch (size % 8) {
    00061         case 0: do{     *--downto = *--downfrom;
    00062         case 7:         *--downto = *--downfrom;
    00063         case 6:         *--downto = *--downfrom;
    00064         case 5:         *--downto = *--downfrom;
    00065         case 4:         *--downto = *--downfrom;
    00066         case 3:         *--downto = *--downfrom;
    00067         case 2:         *--downto = *--downfrom;
    00068         case 1:         *--downto = *--downfrom;
    00069         }while(--n>0);
    00070         }
    00071     } else {
    00072         // Use Duff's device to copy
    00073         --from;
    00074         --to;
    00075         switch (size % 8) {
    00076         case 0: do{     *++to = *++from;
    00077         case 7:         *++to = *++from;
    00078         case 6:         *++to = *++from;
    00079         case 5:         *++to = *++from;
    00080         case 4:         *++to = *++from;
    00081         case 3:         *++to = *++from;
    00082         case 2:         *++to = *++from;
    00083         case 1:         *++to = *++from;
    00084         }while(--n>0);
    00085         }
    00086     }
    00087 }
    00088
    00089 //-----------------------------------------------------------------------------
    00090
    00101 template <class T> inline void
    00102 CoinCopy(register const T* first, register const T* last, register T* to)
    00103 {
    00104     CoinCopyN(first, static_cast<int>(last-first), to);
    00105 }
    00106
    00107 //-----------------------------------------------------------------------------
    00108
    00116 template <class T> inline void
    00117 CoinDisjointCopyN(register const T* from, const int size, register T* to)
    00118 {
    00119 #ifndef _MSC_VER
    00120     if (size == 0 || from == to)
    00121         return;
    00122
    00123 #ifndef NDEBUG
    00124     if (size < 0)
    00125         throw CoinError("trying to copy negative number of entries",
    00126                         "CoinDisjointCopyN", "");
    00127 #endif
    00128
    00129 #if 0
    00130     /* There is no point to do this test. If to and from are from different
    00131        blocks then dist is undefined, so this can crash correct code. It's
    00132        better to trust the user that the arrays are really disjoint. */
    00133     const long dist = to - from;
    00134     if (-size < dist && dist < size)
    00135         throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
    00136 #endif
    00137
    00138     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
    00139         to[0] = from[0];
    00140         to[1] = from[1];
    00141         to[2] = from[2];
    00142         to[3] = from[3];
    00143         to[4] = from[4];
    00144         to[5] = from[5];
    00145         to[6] = from[6];
    00146         to[7] = from[7];
    00147     }
    00148     switch (size % 8) {
    00149     case 7: to[6] = from[6];
    00150     case 6: to[5] = from[5];
    00151     case 5: to[4] = from[4];
    00152     case 4: to[3] = from[3];
    00153     case 3: to[2] = from[2];
    00154     case 2: to[1] = from[1];
    00155     case 1: to[0] = from[0];
    00156     case 0: break;
    00157     }
    00158 #else
    00159     CoinCopyN(from, size, to);
    00160 #endif
    00161 }
    00162
    00163 //-----------------------------------------------------------------------------
    00164
    00169 template <class T> inline void
    00170 CoinDisjointCopy(register const T* first, register const T* last,
    00171                  register T* to)
    00172 {
    00173     CoinDisjointCopyN(first, static_cast<int>(last - first), to);
    00174 }
    00175
    00176 //-----------------------------------------------------------------------------
    00177
    00182 template <class T> inline T*
    00183 CoinCopyOfArray( const T * array, const int size)
    00184 {
    00185     if (array) {
    00186         T * arrayNew = new T[size];
    00187         std::memcpy(arrayNew,array,size*sizeof(T));
    00188         return arrayNew;
    00189     } else {
    00190         return NULL;
    00191     }
    00192 }
    00193
    00194
    00199 template <class T> inline T*
    00200 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
    00201 {
    00202     if (array||size) {
    00203         T * arrayNew = new T[size];
    00204         assert (copySize<=size);
    00205         std::memcpy(arrayNew,array,copySize*sizeof(T));
    00206         return arrayNew;
    00207     } else {
    00208         return NULL;
    00209     }
    00210 }
    00211
    00216 template <class T> inline T*
    00217 CoinCopyOfArray( const T * array, const int size, T value)
    00218 {
    00219     T * arrayNew = new T[size];
    00220     if (array) {
    00221         std::memcpy(arrayNew,array,size*sizeof(T));
    00222     } else {
    00223         int i;
    00224         for (i=0;i<size;i++)
    00225             arrayNew[i] = value;
    00226     }
    00227     return arrayNew;
    00228 }
    00229
    00230
    00235 template <class T> inline T*
    00236 CoinCopyOfArrayOrZero( const T * array , const int size)
    00237 {
    00238     T * arrayNew = new T[size];
    00239     if (array) {
    00240       std::memcpy(arrayNew,array,size*sizeof(T));
    00241     } else {
    00242       std::memset(arrayNew,0,size*sizeof(T));
    00243     }
    00244     return arrayNew;
    00245 }
    00246
    00247
    00248 //-----------------------------------------------------------------------------
    00249
    00257 #ifndef COIN_USE_RESTRICT
    00258 template <class T> inline void
    00259 CoinMemcpyN(register const T* from, const int size, register T* to)
    00260 {
    00261 #ifndef _MSC_VER
    00262 #ifdef USE_MEMCPY
    00263     // Use memcpy - seems a lot faster on Intel with gcc
    00264 #ifndef NDEBUG
    00265     // Some debug so check
    00266     if (size < 0)
    00267         throw CoinError("trying to copy negative number of entries",
    00268                         "CoinMemcpyN", "");
    00269
    00270 #if 0
    00271     /* There is no point to do this test. If to and from are from different
    00272        blocks then dist is undefined, so this can crash correct code. It's
    00273        better to trust the user that the arrays are really disjoint. */
    00274     const long dist = to - from;
    00275     if (-size < dist && dist < size)
    00276         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
    00277 #endif
    00278 #endif
    00279     std::memcpy(to,from,size*sizeof(T));
    00280 #else
    00281     if (size == 0 || from == to)
    00282         return;
    00283
    00284 #ifndef NDEBUG
    00285     if (size < 0)
    00286         throw CoinError("trying to copy negative number of entries",
    00287                         "CoinMemcpyN", "");
    00288 #endif
    00289
    00290 #if 0
    00291     /* There is no point to do this test. If to and from are from different
    00292        blocks then dist is undefined, so this can crash correct code. It's
    00293        better to trust the user that the arrays are really disjoint. */
    00294     const long dist = to - from;
    00295     if (-size < dist && dist < size)
    00296         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
    00297 #endif
    00298
    00299     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
    00300         to[0] = from[0];
    00301         to[1] = from[1];
    00302         to[2] = from[2];
    00303         to[3] = from[3];
    00304         to[4] = from[4];
    00305         to[5] = from[5];
    00306         to[6] = from[6];
    00307         to[7] = from[7];
    00308     }
    00309     switch (size % 8) {
    00310     case 7: to[6] = from[6];
    00311     case 6: to[5] = from[5];
    00312     case 5: to[4] = from[4];
    00313     case 4: to[3] = from[3];
    00314     case 3: to[2] = from[2];
    00315     case 2: to[1] = from[1];
    00316     case 1: to[0] = from[0];
    00317     case 0: break;
    00318     }
    00319 #endif
    00320 #else
    00321     CoinCopyN(from, size, to);
    00322 #endif
    00323 }
    00324 #else
    00325 template <class T> inline void
    00326 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
    00327 {
    00328 #ifdef USE_MEMCPY
    00329   std::memcpy(to,from,size*sizeof(T));
    00330 #else
    00331   T * COIN_RESTRICT put =  to;
    00332   const T * COIN_RESTRICT get = from;
    00333   for ( ; 0<size ; --size)
    00334     *put++ = *get++;
    00335 #endif
    00336 }
    00337 #endif
    00338
    00339 //-----------------------------------------------------------------------------
    00340
    00345 template <class T> inline void
    00346 CoinMemcpy(register const T* first, register const T* last,
    00347            register T* to)
    00348 {
    00349     CoinMemcpyN(first, static_cast<int>(last - first), to);
    00350 }
    00351
    00352 //#############################################################################
    00353
    00360 template <class T> inline void
    00361 CoinFillN(register T* to, const int size, register const T value)
    00362 {
    00363     if (size == 0)
    00364         return;
    00365
    00366 #ifndef NDEBUG
    00367     if (size < 0)
    00368         throw CoinError("trying to fill negative number of entries",
    00369                         "CoinFillN", "");
    00370 #endif
    00371 #if 1
    00372     for (register int n = size / 8; n > 0; --n, to += 8) {
    00373         to[0] = value;
    00374         to[1] = value;
    00375         to[2] = value;
    00376         to[3] = value;
    00377         to[4] = value;
    00378         to[5] = value;
    00379         to[6] = value;
    00380         to[7] = value;
    00381     }
    00382     switch (size % 8) {
    00383     case 7: to[6] = value;
    00384     case 6: to[5] = value;
    00385     case 5: to[4] = value;
    00386     case 4: to[3] = value;
    00387     case 3: to[2] = value;
    00388     case 2: to[1] = value;
    00389     case 1: to[0] = value;
    00390     case 0: break;
    00391     }
    00392 #else
    00393     // Use Duff's device to fill
    00394     register int n = (size + 7) / 8;
    00395     --to;
    00396     switch (size % 8) {
    00397     case 0: do{     *++to = value;
    00398     case 7:         *++to = value;
    00399     case 6:         *++to = value;
    00400     case 5:         *++to = value;
    00401     case 4:         *++to = value;
    00402     case 3:         *++to = value;
    00403     case 2:         *++to = value;
    00404     case 1:         *++to = value;
    00405     }while(--n>0);
    00406     }
    00407 #endif
    00408 }
    00409
    00410 //-----------------------------------------------------------------------------
    00411
    00415 template <class T> inline void
    00416 CoinFill(register T* first, register T* last, const T value)
    00417 {
    00418     CoinFillN(first, last - first, value);
    00419 }
    00420
    00421 //#############################################################################
    00422
    00429 template <class T> inline void
    00430 CoinZeroN(register T* to, const int size)
    00431 {
    00432 #ifdef USE_MEMCPY
    00433     // Use memset - seems faster on Intel with gcc
    00434 #ifndef NDEBUG
    00435     // Some debug so check
    00436     if (size < 0)
    00437         throw CoinError("trying to fill negative number of entries",
    00438                         "CoinZeroN", "");
    00439 #endif
    00440     memset(to,0,size*sizeof(T));
    00441 #else
    00442     if (size == 0)
    00443         return;
    00444
    00445 #ifndef NDEBUG
    00446     if (size < 0)
    00447         throw CoinError("trying to fill negative number of entries",
    00448                         "CoinZeroN", "");
    00449 #endif
    00450 #if 1
    00451     for (register int n = size / 8; n > 0; --n, to += 8) {
    00452         to[0] = 0;
    00453         to[1] = 0;
    00454         to[2] = 0;
    00455         to[3] = 0;
    00456         to[4] = 0;
    00457         to[5] = 0;
    00458         to[6] = 0;
    00459         to[7] = 0;
    00460     }
    00461     switch (size % 8) {
    00462     case 7: to[6] = 0;
    00463     case 6: to[5] = 0;
    00464     case 5: to[4] = 0;
    00465     case 4: to[3] = 0;
    00466     case 3: to[2] = 0;
    00467     case 2: to[1] = 0;
    00468     case 1: to[0] = 0;
    00469     case 0: break;
    00470     }
    00471 #else
    00472     // Use Duff's device to fill
    00473     register int n = (size + 7) / 8;
    00474     --to;
    00475     switch (size % 8) {
    00476     case 0: do{     *++to = 0;
    00477     case 7:         *++to = 0;
    00478     case 6:         *++to = 0;
    00479     case 5:         *++to = 0;
    00480     case 4:         *++to = 0;
    00481     case 3:         *++to = 0;
    00482     case 2:         *++to = 0;
    00483     case 1:         *++to = 0;
    00484     }while(--n>0);
    00485     }
    00486 #endif
    00487 #endif
    00488 }
    00490 inline void
    00491 CoinCheckDoubleZero(double * to, const int size)
    00492 {
    00493     int n=0;
    00494     for (int j=0;j<size;j++) {
    00495         if (to[j])
    00496             n++;
    00497     }
    00498     if (n) {
    00499         printf("array of length %d should be zero has %d nonzero\n",size,n);
    00500     }
    00501 }
    00503 inline void
    00504 CoinCheckIntZero(int * to, const int size)
    00505 {
    00506     int n=0;
    00507     for (int j=0;j<size;j++) {
    00508         if (to[j])
    00509             n++;
    00510     }
    00511     if (n) {
    00512         printf("array of length %d should be zero has %d nonzero\n",size,n);
    00513     }
    00514 }
    00515
    00516 //-----------------------------------------------------------------------------
    00517
    00521 template <class T> inline void
    00522 CoinZero(register T* first, register T* last)
    00523 {
    00524     CoinZeroN(first, last - first);
    00525 }
    00526
    00527 //#############################################################################
    00528
    00530 inline char * CoinStrdup(const char * name)
    00531 {
    00532   char* dup = NULL;
    00533   if (name) {
    00534     const int len = static_cast<int>(strlen(name));
    00535     dup = static_cast<char*>(malloc(len+1));
    00536     CoinMemcpyN(name, len, dup);
    00537     dup[len] = 0;
    00538   }
    00539   return dup;
    00540 }
    00541
    00542 //#############################################################################
    00543
    00547 template <class T> inline T
    00548 CoinMax(register const T x1, register const T x2)
    00549 {
    00550     return (x1 > x2) ? x1 : x2;
    00551 }
    00552
    00553 //-----------------------------------------------------------------------------
    00554
    00558 template <class T> inline T
    00559 CoinMin(register const T x1, register const T x2)
    00560 {
    00561     return (x1 < x2) ? x1 : x2;
    00562 }
    00563
    00564 //-----------------------------------------------------------------------------
    00565
    00569 template <class T> inline T
    00570 CoinAbs(const T value)
    00571 {
    00572     return value<0 ? -value : value;
    00573 }
    00574
    00575 //#############################################################################
    00576
    00580 template <class T> inline bool
    00581 CoinIsSorted(register const T* first, const int size)
    00582 {
    00583     if (size == 0)
    00584         return true;
    00585
    00586 #ifndef NDEBUG
    00587     if (size < 0)
    00588         throw CoinError("negative number of entries", "CoinIsSorted", "");
    00589 #endif
    00590 #if 1
    00591     // size1 is the number of comparisons to be made
    00592     const int size1 = size  - 1;
    00593     for (register int n = size1 / 8; n > 0; --n, first += 8) {
    00594         if (first[8] < first[7]) return false;
    00595         if (first[7] < first[6]) return false;
    00596         if (first[6] < first[5]) return false;
    00597         if (first[5] < first[4]) return false;
    00598         if (first[4] < first[3]) return false;
    00599         if (first[3] < first[2]) return false;
    00600         if (first[2] < first[1]) return false;
    00601         if (first[1] < first[0]) return false;
    00602     }
    00603
    00604     switch (size1 % 8) {
    00605     case 7: if (first[7] < first[6]) return false;
    00606     case 6: if (first[6] < first[5]) return false;
    00607     case 5: if (first[5] < first[4]) return false;
    00608     case 4: if (first[4] < first[3]) return false;
    00609     case 3: if (first[3] < first[2]) return false;
    00610     case 2: if (first[2] < first[1]) return false;
    00611     case 1: if (first[1] < first[0]) return false;
    00612     case 0: break;
    00613     }
    00614 #else
    00615     register const T* next = first;
    00616     register const T* last = first + size;
    00617     for (++next; next != last; first = next, ++next)
    00618         if (*next < *first)
    00619             return false;
    00620 #endif
    00621     return true;
    00622 }
    00623
    00624 //-----------------------------------------------------------------------------
    00625
    00629 template <class T> inline bool
    00630 CoinIsSorted(register const T* first, register const T* last)
    00631 {
    00632     return CoinIsSorted(first, static_cast<int>(last - first));
    00633 }
    00634
    00635 //#############################################################################
    00636
    00640 template <class T> inline void
    00641 CoinIotaN(register T* first, const int size, register T init)
    00642 {
    00643     if (size == 0)
    00644         return;
    00645
    00646 #ifndef NDEBUG
    00647     if (size < 0)
    00648         throw CoinError("negative number of entries", "CoinIotaN", "");
    00649 #endif
    00650 #if 1
    00651     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
    00652         first[0] = init;
    00653         first[1] = init + 1;
    00654         first[2] = init + 2;
    00655         first[3] = init + 3;
    00656         first[4] = init + 4;
    00657         first[5] = init + 5;
    00658         first[6] = init + 6;
    00659         first[7] = init + 7;
    00660     }
    00661     switch (size % 8) {
    00662     case 7: first[6] = init + 6;
    00663     case 6: first[5] = init + 5;
    00664     case 5: first[4] = init + 4;
    00665     case 4: first[3] = init + 3;
    00666     case 3: first[2] = init + 2;
    00667     case 2: first[1] = init + 1;
    00668     case 1: first[0] = init;
    00669     case 0: break;
    00670     }
    00671 #else
    00672     // Use Duff's device to fill
    00673     register int n = (size + 7) / 8;
    00674     --first;
    00675     --init;
    00676     switch (size % 8) {
    00677     case 0: do{     *++first = ++init;
    00678     case 7:         *++first = ++init;
    00679     case 6:         *++first = ++init;
    00680     case 5:         *++first = ++init;
    00681     case 4:         *++first = ++init;
    00682     case 3:         *++first = ++init;
    00683     case 2:         *++first = ++init;
    00684     case 1:         *++first = ++init;
    00685     }while(--n>0);
    00686     }
    00687 #endif
    00688 }
    00689
    00690 //-----------------------------------------------------------------------------
    00691
    00695 template <class T> inline void
    00696 CoinIota(T* first, const T* last, T init)
    00697 {
    00698     CoinIotaN(first, last-first, init);
    00699 }
    00700
    00701 //#############################################################################
    00702
    00708 template <class T> inline T *
    00709 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
    00710                            const int * firstDelPos, const int * lastDelPos)
    00711 {
    00712     int delNum = static_cast<int>(lastDelPos - firstDelPos);
    00713     if (delNum == 0)
    00714         return arrayLast;
    00715
    00716     if (delNum < 0)
    00717         throw CoinError("trying to delete negative number of entries",
    00718                         "CoinDeleteEntriesFromArray", "");
    00719
    00720     int * delSortedPos = NULL;
    00721     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
    00722            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
    00723         // the positions of the to be deleted is either not sorted or not unique
    00724         delSortedPos = new int[delNum];
    00725         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
    00726         std::sort(delSortedPos, delSortedPos + delNum);
    00727         delNum = static_cast<int>(std::unique(delSortedPos,
    00728                                   delSortedPos+delNum) - delSortedPos);
    00729     }
    00730     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
    00731
    00732     const int last = delNum - 1;
    00733     int size = delSorted[0];
    00734     for (int i = 0; i < last; ++i) {
    00735         const int copyFirst = delSorted[i] + 1;
    00736         const int copyLast = delSorted[i+1];
    00737         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
    00738                  arrayFirst + size);
    00739         size += copyLast - copyFirst;
    00740     }
    00741     const int copyFirst = delSorted[last] + 1;
    00742     const int copyLast = static_cast<int>(arrayLast - arrayFirst);
    00743     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
    00744              arrayFirst + size);
    00745     size += copyLast - copyFirst;
    00746
    00747     if (delSortedPos)
    00748         delete[] delSortedPos;
    00749
    00750     return arrayFirst + size;
    00751 }
    00752
    00753 //#############################################################################
    00754
    00755 #define COIN_OWN_RANDOM_32
    00756
    00757 #if defined COIN_OWN_RANDOM_32
    00758 /* Thanks to Stefano Gliozzi for providing an operating system
    00759    independent random number generator.  */
    00760
    00773 inline double CoinDrand48 (bool isSeed = false, unsigned int seed = 1)
    00774 {
    00775   static unsigned int last = 123456;
    00776   if (isSeed) {
    00777     last = seed;
    00778   } else {
    00779     last = 1664525*last+1013904223;
    00780     return ((static_cast<double> (last))/4294967296.0);
    00781   }
    00782   return (0.0);
    00783 }
    00784
    00786 inline void CoinSeedRandom(int iseed)
    00787 {
    00788   CoinDrand48(true, iseed);
    00789 }
    00790
    00791 #else // COIN_OWN_RANDOM_32
    00792
    00793 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
    00794
    00796 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
    00798 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
    00799
    00800 #else
    00801
    00803 inline double CoinDrand48() { return drand48(); }
    00805 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
    00806
    00807 #endif
    00808
    00809 #endif // COIN_OWN_RANDOM_32
    00810
    00811 //#############################################################################
    00812
    00815 inline char CoinFindDirSeparator()
    00816 {
    00817     int size = 1000;
    00818     char* buf = 0;
    00819     while (true) {
    00820         buf = new char[size];
    00821         if (getcwd(buf, size))
    00822             break;
    00823         delete[] buf;
    00824         buf = 0;
    00825         size = 2*size;
    00826     }
    00827     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we
    00828     // assume it's dos and the dirsep is '\'
    00829     char dirsep = buf[0] == '/' ? '/' : '\\';
    00830     delete[] buf;
    00831     return dirsep;
    00832 }
    00833 //#############################################################################
    00834
    00835 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
    00836                            const size_t len)
    00837 {
    00838     for (size_t i = 0; i < len; ++i) {
    00839         if (s0[i] == 0) {
    00840             return s1[i] == 0 ? 0 : -1;
    00841         }
    00842         if (s1[i] == 0) {
    00843             return 1;
    00844         }
    00845         const int c0 = std::tolower(s0[i]);
    00846         const int c1 = std::tolower(s1[i]);
    00847         if (c0 < c1)
    00848             return -1;
    00849         if (c0 > c1)
    00850             return 1;
    00851     }
    00852     return 0;
    00853 }
    00854
    00855 //#############################################################################
    00856
    00858 template <class T> inline void CoinSwap (T &x, T &y)
    00859 {
    00860     T t = x;
    00861     x = y;
    00862     y = t;
    00863 }
    00864
    00865 //#############################################################################
    00866
    00871 template <class T> inline int
    00872 CoinToFile( const T* array, CoinBigIndex size, FILE * fp)
    00873 {
    00874     CoinBigIndex numberWritten;
    00875     if (array&&size) {
    00876         numberWritten =
    00877             static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp));
    00878         if (numberWritten!=1)
    00879             return 1;
    00880         numberWritten =
    00881             static_cast<CoinBigIndex>(fwrite(array,sizeof(T),size_t(size),fp));
    00882         if (numberWritten!=size)
    00883             return 1;
    00884     } else {
    00885         size = 0;
    00886         numberWritten =
    00887             static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp));
    00888         if (numberWritten!=1)
    00889             return 1;
    00890     }
    00891     return 0;
    00892 }
    00893
    00894 //#############################################################################
    00895
    00902 template <class T> inline int
    00903 CoinFromFile( T* &array, CoinBigIndex size, FILE * fp, CoinBigIndex & newSize)
    00904 {
    00905     CoinBigIndex numberRead;
    00906     numberRead =
    00907         static_cast<CoinBigIndex>(fread(&newSize,sizeof(int),1,fp));
    00908     if (numberRead!=1)
    00909         return 1;
    00910     int returnCode=0;
    00911     if (size!=newSize&&(newSize||array))
    00912         returnCode=2;
    00913     if (newSize) {
    00914         array = new T [newSize];
    00915         numberRead =
    00916             static_cast<CoinBigIndex>(fread(array,sizeof(T),newSize,fp));
    00917         if (numberRead!=newSize)
    00918             returnCode=1;
    00919     } else {
    00920         array = NULL;
    00921     }
    00922     return returnCode;
    00923 }
    00924
    00925 //#############################################################################
    00926
    00928 #if 0
    00929 inline double CoinCbrt(double x)
    00930 {
    00931 #if defined(_MSC_VER)
    00932     return pow(x,(1./3.));
    00933 #else
    00934     return cbrt(x);
    00935 #endif
    00936 }
    00937 #endif
    00938
    00939 //-----------------------------------------------------------------------------
    00940
    00942 #define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type)))
    00944 inline int
    00945 CoinStrlenAsInt(const char * string)
    00946 {
    00947     return static_cast<int>(strlen(string));
    00948 }
    00949
    00952 #if defined COIN_OWN_RANDOM_32
    00953 class CoinThreadRandom  {
    00954 public:
    00959   CoinThreadRandom()
    00960   { seed_=12345678;}
    00962   CoinThreadRandom(int seed)
    00963   {
    00964     seed_ = seed;
    00965   }
    00967   ~CoinThreadRandom() {}
    00968   // Copy
    00969   CoinThreadRandom(const CoinThreadRandom & rhs)
    00970   { seed_ = rhs.seed_;}
    00971   // Assignment
    00972   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
    00973   {
    00974     if (this != &rhs) {
    00975       seed_ = rhs.seed_;
    00976     }
    00977     return *this;
    00978   }
    00979
    00981
    00986   inline void setSeed(int seed)
    00987   {
    00988     seed_ = seed;
    00989   }
    00991   inline unsigned int getSeed() const
    00992   {
    00993     return seed_;
    00994   }
    00996   inline double randomDouble() const
    00997   {
    00998     double retVal;
    00999     seed_ = 1664525*(seed_)+1013904223;
    01000     retVal = ((static_cast<double> (seed_))/4294967296.0);
    01001     return retVal;
    01002   }
    01004   inline void randomize(int n=0)
    01005   {
    01006     if (!n)
    01007       n=seed_ & 255;
    01008     for (int i=0;i<n;i++)
    01009       randomDouble();
    01010   }
    01012
    01013
    01014 protected:
    01018
    01019   mutable unsigned int seed_;
    01021 };
    01022 #else
    01023 class CoinThreadRandom  {
    01024 public:
    01029   CoinThreadRandom()
    01030   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
    01032   CoinThreadRandom(const unsigned short seed[3])
    01033   { memcpy(seed_,seed,3*sizeof(unsigned short));}
    01035   CoinThreadRandom(int seed)
    01036   {
    01037     union { int i[2]; unsigned short int s[4];} put;
    01038     put.i[0]=seed;
    01039     put.i[1]=seed;
    01040     memcpy(seed_,put.s,3*sizeof(unsigned short));
    01041   }
    01043   ~CoinThreadRandom() {}
    01044   // Copy
    01045   CoinThreadRandom(const CoinThreadRandom & rhs)
    01046   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
    01047   // Assignment
    01048   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
    01049   {
    01050     if (this != &rhs) {
    01051       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
    01052     }
    01053     return *this;
    01054   }
    01055
    01057
    01062   inline void setSeed(const unsigned short seed[3])
    01063   { memcpy(seed_,seed,3*sizeof(unsigned short));}
    01065   inline void setSeed(int seed)
    01066   {
    01067     union { int i[2]; unsigned short int s[4];} put;
    01068     put.i[0]=seed;
    01069     put.i[1]=seed;
    01070     memcpy(seed_,put.s,3*sizeof(unsigned short));
    01071   }
    01073   inline double randomDouble() const
    01074   {
    01075     double retVal;
    01076 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
    01077     retVal=rand();
    01078     retVal=retVal/(double) RAND_MAX;
    01079 #else
    01080     retVal = erand48(seed_);
    01081 #endif
    01082     return retVal;
    01083   }
    01085   inline void randomize(int n=0)
    01086   {
    01087     if (!n) {
    01088       n=seed_[0]+seed_[1]+seed_[2];
    01089       n &= 255;
    01090     }
    01091     for (int i=0;i<n;i++)
    01092       randomDouble();
    01093   }
    01095
    01096
    01097 protected:
    01101
    01102   mutable unsigned short seed_[3];
    01104 };
    01105 #endif
    01106 #ifndef COIN_DETAIL
    01107 #define COIN_DETAIL_PRINT(s) {}
    01108 #else
    01109 #define COIN_DETAIL_PRINT(s) s
    01110 #endif
    01111 #endif