CoinUtils trunk
|
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