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

- File List
- File Members

# /home/coin/svn-release/Alps-1.4.6/CoinUtils/src/CoinHelperFunctions.hpp

Go to the documentation of this file.

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