CoinHelperFunctions.hpp

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

Generated on 25 Nov 2013 for CoinUtils by  doxygen 1.6.1