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 #  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)))
00941 
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   
01003   
01004 protected:
01008 
01009   mutable unsigned int seed_;
01011 };
01012 #else
01013 class CoinThreadRandom  {
01014 public:
01019   CoinThreadRandom()
01020   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
01022   CoinThreadRandom(const unsigned short seed[3])
01023   { memcpy(seed_,seed,3*sizeof(unsigned short));}
01025   CoinThreadRandom(int seed)
01026   { 
01027     union { int i[2]; unsigned short int s[4];} put;
01028     put.i[0]=seed;
01029     put.i[1]=seed;
01030     memcpy(seed_,put.s,3*sizeof(unsigned short));
01031   }
01033   ~CoinThreadRandom() {}
01034   // Copy
01035   CoinThreadRandom(const CoinThreadRandom & rhs)
01036   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
01037   // Assignment
01038   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
01039   {
01040     if (this != &rhs) {
01041       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
01042     }
01043     return *this;
01044   }
01045 
01047   
01052   inline void setSeed(const unsigned short seed[3])
01053   { memcpy(seed_,seed,3*sizeof(unsigned short));}
01055   inline void setSeed(int seed)
01056   { 
01057     union { int i[2]; unsigned short int s[4];} put;
01058     put.i[0]=seed;
01059     put.i[1]=seed;
01060     memcpy(seed_,put.s,3*sizeof(unsigned short));
01061   }
01063   inline double randomDouble() const
01064   {
01065     double retVal;
01066 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
01067     retVal=rand();
01068     retVal=retVal/(double) RAND_MAX;
01069 #else
01070     retVal = erand48(seed_);
01071 #endif
01072     return retVal;
01073   }
01075   
01076   
01077 protected:
01081 
01082   mutable unsigned short seed_[3];
01084 };
01085 #endif
01086 #ifndef COIN_DETAIL
01087 #define COIN_DETAIL_PRINT(s) {}
01088 #else
01089 #define COIN_DETAIL_PRINT(s) s
01090 #endif
01091 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines