CoinUtils  trunk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
CoinHelperFunctions.hpp
Go to the documentation of this file.
00001 /* $Id$ */
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)))
00943 
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines