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 # 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