5 #ifndef CoinHelperFunctions_H
6 #define CoinHelperFunctions_H
9 # define getcwd _getcwd
26 template <
class T>
inline void
27 CoinCopyN(
register const T* from,
const int size,
register T* to)
29 if (size == 0 || from == to)
34 throw CoinError(
"trying to copy negative number of entries",
38 register int n = (size + 7) / 8;
40 register const T* downfrom = from + size;
41 register T* downto = to + size;
44 case 0:
do{ *--downto = *--downfrom;
45 case 7: *--downto = *--downfrom;
46 case 6: *--downto = *--downfrom;
47 case 5: *--downto = *--downfrom;
48 case 4: *--downto = *--downfrom;
49 case 3: *--downto = *--downfrom;
50 case 2: *--downto = *--downfrom;
51 case 1: *--downto = *--downfrom;
59 case 0:
do{ *++to = *++from;
60 case 7: *++to = *++from;
61 case 6: *++to = *++from;
62 case 5: *++to = *++from;
63 case 4: *++to = *++from;
64 case 3: *++to = *++from;
65 case 2: *++to = *++from;
66 case 1: *++to = *++from;
78 template <
class T>
inline void
79 CoinCopy(
register const T* first,
register const T* last,
register T* to)
93 template <
class T>
inline void
97 if (size == 0 || from == to)
102 throw CoinError(
"trying to copy negative number of entries",
103 "CoinDisjointCopyN",
"");
110 const long dist = to - from;
111 if (-size < dist && dist < size)
112 throw CoinError(
"overlapping arrays",
"CoinDisjointCopyN",
"");
115 for (
register int n = size / 8; n > 0; --n, from += 8, to += 8) {
126 case 7: to[6] = from[6];
127 case 6: to[5] = from[5];
128 case 5: to[4] = from[4];
129 case 4: to[3] = from[3];
130 case 3: to[2] = from[2];
131 case 2: to[1] = from[1];
132 case 1: to[0] = from[0];
146 template <
class T>
inline void
159 template <
class T>
inline T*
163 T * arrayNew =
new T[size];
164 std::memcpy(arrayNew,array,size*
sizeof(T));
176 template <
class T>
inline T*
180 T * arrayNew =
new T[size];
181 assert (copySize<=size);
182 std::memcpy(arrayNew,array,copySize*
sizeof(T));
193 template <
class T>
inline T*
196 T * arrayNew =
new T[size];
198 std::memcpy(arrayNew,array,size*
sizeof(T));
212 template <
class T>
inline T*
215 T * arrayNew =
new T[size];
217 std::memcpy(arrayNew,array,size*
sizeof(T));
219 std::memset(arrayNew,0,size*
sizeof(T));
234 #ifndef COIN_USE_RESTRICT
235 template <
class T>
inline void
236 CoinMemcpyN(
register const T* from,
const int size,
register T* to)
244 throw CoinError(
"trying to copy negative number of entries",
251 const long dist = to - from;
252 if (-size < dist && dist < size)
253 throw CoinError(
"overlapping arrays",
"CoinMemcpyN",
"");
256 std::memcpy(to,from,size*
sizeof(T));
258 if (size == 0 || from == to)
263 throw CoinError(
"trying to copy negative number of entries",
271 const long dist = to - from;
272 if (-size < dist && dist < size)
273 throw CoinError(
"overlapping arrays",
"CoinMemcpyN",
"");
276 for (
register int n = size / 8; n > 0; --n, from += 8, to += 8) {
287 case 7: to[6] = from[6];
288 case 6: to[5] = from[5];
289 case 5: to[4] = from[4];
290 case 4: to[3] = from[3];
291 case 3: to[2] = from[2];
292 case 2: to[1] = from[1];
293 case 1: to[0] = from[0];
302 template <
class T>
inline void
306 std::memcpy(to,from,size*
sizeof(T));
310 for ( ; 0<size ; --size)
322 template <
class T>
inline void
326 CoinMemcpyN(first, static_cast<int>(last - first), to);
337 template <
class T>
inline void
338 CoinFillN(
register T* to,
const int size,
register const T value)
345 throw CoinError(
"trying to fill negative number of entries",
349 for (
register int n = size / 8; n > 0; --n, to += 8) {
360 case 7: to[6] = value;
361 case 6: to[5] = value;
362 case 5: to[4] = value;
363 case 4: to[3] = value;
364 case 3: to[2] = value;
365 case 2: to[1] = value;
366 case 1: to[0] = value;
371 register int n = (size + 7) / 8;
374 case 0:
do{ *++to = value;
375 case 7: *++to = value;
376 case 6: *++to = value;
377 case 5: *++to = value;
378 case 4: *++to = value;
379 case 3: *++to = value;
380 case 2: *++to = value;
381 case 1: *++to = value;
392 template <
class T>
inline void
393 CoinFill(
register T* first,
register T* last,
const T value)
406 template <
class T>
inline void
414 throw CoinError(
"trying to fill negative number of entries",
417 memset(to,0,size*
sizeof(T));
424 throw CoinError(
"trying to fill negative number of entries",
428 for (
register int n = size / 8; n > 0; --n, to += 8) {
450 register int n = (size + 7) / 8;
453 case 0:
do{ *++to = 0;
471 for (
int j=0;j<size;j++) {
476 printf(
"array of length %d should be zero has %d nonzero\n",size,n);
484 for (
int j=0;j<size;j++) {
489 printf(
"array of length %d should be zero has %d nonzero\n",size,n);
498 template <
class T>
inline void
511 const int len =
static_cast<int>(strlen(name));
512 dup =
static_cast<char*
>(malloc(len+1));
524 template <
class T>
inline T
525 CoinMax(
register const T x1,
register const T x2)
527 return (x1 > x2) ? x1 : x2;
535 template <
class T>
inline T
536 CoinMin(
register const T x1,
register const T x2)
538 return (x1 < x2) ? x1 : x2;
546 template <
class T>
inline T
549 return value<0 ? -value : value;
557 template <
class T>
inline bool
565 throw CoinError(
"negative number of entries",
"CoinIsSorted",
"");
569 const int size1 = size - 1;
570 for (
register int n = size1 / 8; n > 0; --n, first += 8) {
571 if (first[8] < first[7])
return false;
572 if (first[7] < first[6])
return false;
573 if (first[6] < first[5])
return false;
574 if (first[5] < first[4])
return false;
575 if (first[4] < first[3])
return false;
576 if (first[3] < first[2])
return false;
577 if (first[2] < first[1])
return false;
578 if (first[1] < first[0])
return false;
582 case 7:
if (first[7] < first[6])
return false;
583 case 6:
if (first[6] < first[5])
return false;
584 case 5:
if (first[5] < first[4])
return false;
585 case 4:
if (first[4] < first[3])
return false;
586 case 3:
if (first[3] < first[2])
return false;
587 case 2:
if (first[2] < first[1])
return false;
588 case 1:
if (first[1] < first[0])
return false;
592 register const T* next = first;
593 register const T* last = first + size;
594 for (++next; next != last; first = next, ++next)
606 template <
class T>
inline bool
609 return CoinIsSorted(first, static_cast<int>(last - first));
617 template <
class T>
inline void
618 CoinIotaN(
register T* first,
const int size,
register T init)
625 throw CoinError(
"negative number of entries",
"CoinIotaN",
"");
628 for (
register int n = size / 8; n > 0; --n, first += 8, init += 8) {
639 case 7: first[6] = init + 6;
640 case 6: first[5] = init + 5;
641 case 5: first[4] = init + 4;
642 case 4: first[3] = init + 3;
643 case 3: first[2] = init + 2;
644 case 2: first[1] = init + 1;
645 case 1: first[0] = init;
650 register int n = (size + 7) / 8;
654 case 0:
do{ *++first = ++init;
655 case 7: *++first = ++init;
656 case 6: *++first = ++init;
657 case 5: *++first = ++init;
658 case 4: *++first = ++init;
659 case 3: *++first = ++init;
660 case 2: *++first = ++init;
661 case 1: *++first = ++init;
672 template <
class T>
inline void
685 template <
class T>
inline T *
687 const int * firstDelPos,
const int * lastDelPos)
689 int delNum = lastDelPos - firstDelPos;
694 throw CoinError(
"trying to delete negative number of entries",
695 "CoinDeleteEntriesFromArray",
"");
697 int * delSortedPos = NULL;
699 std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
701 delSortedPos =
new int[delNum];
703 std::sort(delSortedPos, delSortedPos + delNum);
704 delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
706 const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
708 const int last = delNum - 1;
709 int size = delSorted[0];
710 for (
int i = 0; i < last; ++i) {
711 const int copyFirst = delSorted[i] + 1;
712 const int copyLast = delSorted[i+1];
713 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
715 size += copyLast - copyFirst;
717 const int copyFirst = delSorted[last] + 1;
718 const int copyLast = arrayLast - arrayFirst;
719 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
721 size += copyLast - copyFirst;
724 delete[] delSortedPos;
726 return arrayFirst + size;
731 #define COIN_OWN_RANDOM_32
733 #if defined COIN_OWN_RANDOM_32
742 inline double CoinDrand48(
bool isSeed =
false,
unsigned int seed=1)
744 static unsigned int last = 123456;
748 last = 1664525*last+1013904223;
749 return ((static_cast<double> (last))/4294967296.0);
759 #else // COIN_OWN_RANDOM_32
761 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
763 inline double CoinDrand48() {
return rand() / (double) RAND_MAX; }
773 #endif // COIN_OWN_RANDOM_32
784 buf =
new char[size];
785 if (getcwd(buf, size))
793 char dirsep = buf[0] ==
'/' ?
'/' :
'\\';
802 for (
size_t i = 0; i < len; ++i) {
804 return s1[i] == 0 ? 0 : -1;
809 const int c0 = tolower(s0[i]);
810 const int c1 = tolower(s1[i]);
822 template <
class T>
inline void CoinSwap (T &x, T &y)
837 template <
class T>
inline int
840 size_t numberWritten;
842 numberWritten = fwrite(&size,
sizeof(
int),1,fp);
843 if (numberWritten!=1)
845 numberWritten = fwrite(array,
sizeof(T),
size_t(size),fp);
846 if (numberWritten!=size)
850 numberWritten = fwrite(&size,
sizeof(
int),1,fp);
851 if (numberWritten!=1)
867 template <
class T>
inline int
871 numberRead = fread(&newSize,
sizeof(
int),1,fp);
875 if (size!=newSize&&(newSize||array))
878 array =
new T [newSize];
879 numberRead = fread(array,
sizeof(T),
size_t(newSize),fp);
880 if (numberRead!=newSize)
893 #if defined(_MSC_VER)
894 return pow(x,(1./3.));
902 #define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type)))
907 return static_cast<int>(strlen(
string));
912 #if defined COIN_OWN_RANDOM_32
960 retVal = ((
static_cast<double> (
seed_))/4294967296.0);
985 { memcpy(
seed_,seed,3*
sizeof(
unsigned short));}
989 union {
int i[2];
unsigned short int s[4];} put;
992 memcpy(
seed_,put.s,3*
sizeof(
unsigned short));
998 { memcpy(
seed_,rhs.
seed_,3*
sizeof(
unsigned short));}
1003 memcpy(
seed_,rhs.
seed_,3*
sizeof(
unsigned short));
1014 inline void setSeed(
const unsigned short seed[3])
1015 { memcpy(
seed_,seed,3*
sizeof(
unsigned short));}
1019 union {
int i[2];
unsigned short int s[4];} put;
1022 memcpy(
seed_,put.s,3*
sizeof(
unsigned short));
1028 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
1030 retVal=retVal/(double) RAND_MAX;
1032 retVal = erand48(
seed_);
1044 mutable unsigned short seed_[3];