6 #ifndef CoinHelperFunctions_H
7 #define CoinHelperFunctions_H
13 # define getcwd _getcwd
27 #ifdef COIN_USE_RESTRICT
28 #define COIN_RESTRICT __restrict
41 template <
class T>
inline void
42 CoinCopyN(
register const T* from,
const int size,
register T* to)
44 if (size == 0 || from == to)
49 throw CoinError(
"trying to copy negative number of entries",
53 register int n = (size + 7) / 8;
55 register const T* downfrom = from + size;
56 register T* downto = to + size;
59 case 0:
do{ *--downto = *--downfrom;
60 case 7: *--downto = *--downfrom;
61 case 6: *--downto = *--downfrom;
62 case 5: *--downto = *--downfrom;
63 case 4: *--downto = *--downfrom;
64 case 3: *--downto = *--downfrom;
65 case 2: *--downto = *--downfrom;
66 case 1: *--downto = *--downfrom;
74 case 0:
do{ *++to = *++from;
75 case 7: *++to = *++from;
76 case 6: *++to = *++from;
77 case 5: *++to = *++from;
78 case 4: *++to = *++from;
79 case 3: *++to = *++from;
80 case 2: *++to = *++from;
81 case 1: *++to = *++from;
99 template <
class T>
inline void
100 CoinCopy(
register const T* first,
register const T* last,
register T* to)
102 CoinCopyN(first, static_cast<int>(last-first), to);
114 template <
class T>
inline void
118 if (size == 0 || from == to)
123 throw CoinError(
"trying to copy negative number of entries",
124 "CoinDisjointCopyN",
"");
131 const long dist = to - from;
132 if (-size < dist && dist < size)
133 throw CoinError(
"overlapping arrays",
"CoinDisjointCopyN",
"");
136 for (
register int n = size / 8; n > 0; --n, from += 8, to += 8) {
147 case 7: to[6] = from[6];
148 case 6: to[5] = from[5];
149 case 5: to[4] = from[4];
150 case 4: to[3] = from[3];
151 case 3: to[2] = from[2];
152 case 2: to[1] = from[1];
153 case 1: to[0] = from[0];
167 template <
class T>
inline void
180 template <
class T>
inline T*
184 T * arrayNew =
new T[size];
185 std::memcpy(arrayNew,array,size*
sizeof(T));
197 template <
class T>
inline T*
201 T * arrayNew =
new T[size];
202 assert (copySize<=size);
203 std::memcpy(arrayNew,array,copySize*
sizeof(T));
214 template <
class T>
inline T*
217 T * arrayNew =
new T[size];
219 std::memcpy(arrayNew,array,size*
sizeof(T));
233 template <
class T>
inline T*
236 T * arrayNew =
new T[size];
238 std::memcpy(arrayNew,array,size*
sizeof(T));
240 std::memset(arrayNew,0,size*
sizeof(T));
255 #ifndef COIN_USE_RESTRICT
256 template <
class T>
inline void
257 CoinMemcpyN(
register const T* from,
const int size,
register T* to)
265 throw CoinError(
"trying to copy negative number of entries",
272 const long dist = to - from;
273 if (-size < dist && dist < size)
274 throw CoinError(
"overlapping arrays",
"CoinMemcpyN",
"");
277 std::memcpy(to,from,size*
sizeof(T));
279 if (size == 0 || from == to)
284 throw CoinError(
"trying to copy negative number of entries",
292 const long dist = to - from;
293 if (-size < dist && dist < size)
294 throw CoinError(
"overlapping arrays",
"CoinMemcpyN",
"");
297 for (
register int n = size / 8; n > 0; --n, from += 8, to += 8) {
308 case 7: to[6] = from[6];
309 case 6: to[5] = from[5];
310 case 5: to[4] = from[4];
311 case 4: to[3] = from[3];
312 case 3: to[2] = from[2];
313 case 2: to[1] = from[1];
314 case 1: to[0] = from[0];
323 template <
class T>
inline void
327 std::memcpy(to,from,size*
sizeof(T));
331 for ( ; 0<size ; --size)
343 template <
class T>
inline void
347 CoinMemcpyN(first, static_cast<int>(last - first), to);
358 template <
class T>
inline void
359 CoinFillN(
register T* to,
const int size,
register const T value)
366 throw CoinError(
"trying to fill negative number of entries",
370 for (
register int n = size / 8; n > 0; --n, to += 8) {
381 case 7: to[6] = value;
382 case 6: to[5] = value;
383 case 5: to[4] = value;
384 case 4: to[3] = value;
385 case 3: to[2] = value;
386 case 2: to[1] = value;
387 case 1: to[0] = value;
392 register int n = (size + 7) / 8;
395 case 0:
do{ *++to = value;
396 case 7: *++to = value;
397 case 6: *++to = value;
398 case 5: *++to = value;
399 case 4: *++to = value;
400 case 3: *++to = value;
401 case 2: *++to = value;
402 case 1: *++to = value;
413 template <
class T>
inline void
414 CoinFill(
register T* first,
register T* last,
const T value)
427 template <
class T>
inline void
435 throw CoinError(
"trying to fill negative number of entries",
438 memset(to,0,size*
sizeof(T));
445 throw CoinError(
"trying to fill negative number of entries",
449 for (
register int n = size / 8; n > 0; --n, to += 8) {
471 register int n = (size + 7) / 8;
474 case 0:
do{ *++to = 0;
492 for (
int j=0;j<size;j++) {
497 printf(
"array of length %d should be zero has %d nonzero\n",size,n);
505 for (
int j=0;j<size;j++) {
510 printf(
"array of length %d should be zero has %d nonzero\n",size,n);
519 template <
class T>
inline void
532 const int len =
static_cast<int>(strlen(name));
533 dup =
static_cast<char*
>(malloc(len+1));
545 template <
class T>
inline T
546 CoinMax(
register const T x1,
register const T x2)
548 return (x1 > x2) ? x1 : x2;
556 template <
class T>
inline T
557 CoinMin(
register const T x1,
register const T x2)
559 return (x1 < x2) ? x1 : x2;
567 template <
class T>
inline T
570 return value<0 ? -value : value;
578 template <
class T>
inline bool
586 throw CoinError(
"negative number of entries",
"CoinIsSorted",
"");
590 const int size1 = size - 1;
591 for (
register int n = size1 / 8; n > 0; --n, first += 8) {
592 if (first[8] < first[7])
return false;
593 if (first[7] < first[6])
return false;
594 if (first[6] < first[5])
return false;
595 if (first[5] < first[4])
return false;
596 if (first[4] < first[3])
return false;
597 if (first[3] < first[2])
return false;
598 if (first[2] < first[1])
return false;
599 if (first[1] < first[0])
return false;
603 case 7:
if (first[7] < first[6])
return false;
604 case 6:
if (first[6] < first[5])
return false;
605 case 5:
if (first[5] < first[4])
return false;
606 case 4:
if (first[4] < first[3])
return false;
607 case 3:
if (first[3] < first[2])
return false;
608 case 2:
if (first[2] < first[1])
return false;
609 case 1:
if (first[1] < first[0])
return false;
613 register const T* next = first;
614 register const T* last = first + size;
615 for (++next; next != last; first = next, ++next)
627 template <
class T>
inline bool
630 return CoinIsSorted(first, static_cast<int>(last - first));
638 template <
class T>
inline void
639 CoinIotaN(
register T* first,
const int size,
register T init)
646 throw CoinError(
"negative number of entries",
"CoinIotaN",
"");
649 for (
register int n = size / 8; n > 0; --n, first += 8, init += 8) {
660 case 7: first[6] = init + 6;
661 case 6: first[5] = init + 5;
662 case 5: first[4] = init + 4;
663 case 4: first[3] = init + 3;
664 case 3: first[2] = init + 2;
665 case 2: first[1] = init + 1;
666 case 1: first[0] = init;
671 register int n = (size + 7) / 8;
675 case 0:
do{ *++first = ++init;
676 case 7: *++first = ++init;
677 case 6: *++first = ++init;
678 case 5: *++first = ++init;
679 case 4: *++first = ++init;
680 case 3: *++first = ++init;
681 case 2: *++first = ++init;
682 case 1: *++first = ++init;
693 template <
class T>
inline void
706 template <
class T>
inline T *
708 const int * firstDelPos,
const int * lastDelPos)
710 int delNum =
static_cast<int>(lastDelPos - firstDelPos);
715 throw CoinError(
"trying to delete negative number of entries",
716 "CoinDeleteEntriesFromArray",
"");
718 int * delSortedPos = NULL;
720 std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
722 delSortedPos =
new int[delNum];
724 std::sort(delSortedPos, delSortedPos + delNum);
725 delNum =
static_cast<int>(std::unique(delSortedPos,
726 delSortedPos+delNum) - delSortedPos);
728 const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
730 const int last = delNum - 1;
731 int size = delSorted[0];
732 for (
int i = 0; i < last; ++i) {
733 const int copyFirst = delSorted[i] + 1;
734 const int copyLast = delSorted[i+1];
735 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
737 size += copyLast - copyFirst;
739 const int copyFirst = delSorted[last] + 1;
740 const int copyLast =
static_cast<int>(arrayLast - arrayFirst);
741 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
743 size += copyLast - copyFirst;
746 delete[] delSortedPos;
748 return arrayFirst + size;
753 #define COIN_OWN_RANDOM_32
755 #if defined COIN_OWN_RANDOM_32
771 inline double CoinDrand48 (
bool isSeed =
false,
unsigned int seed = 1)
773 static unsigned int last = 123456;
777 last = 1664525*last+1013904223;
778 return ((static_cast<double> (last))/4294967296.0);
789 #else // COIN_OWN_RANDOM_32
791 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
794 inline double CoinDrand48() {
return rand() / (double) RAND_MAX; }
807 #endif // COIN_OWN_RANDOM_32
818 buf =
new char[size];
819 if (getcwd(buf, size))
827 char dirsep = buf[0] ==
'/' ?
'/' :
'\\';
836 for (
size_t i = 0; i < len; ++i) {
838 return s1[i] == 0 ? 0 : -1;
843 const int c0 = tolower(s0[i]);
844 const int c1 = tolower(s1[i]);
856 template <
class T>
inline void CoinSwap (T &x, T &y)
869 template <
class T>
inline int
875 static_cast<CoinBigIndex>(fwrite(&size,
sizeof(
int),1,fp));
876 if (numberWritten!=1)
879 static_cast<CoinBigIndex>(fwrite(array,
sizeof(T),
size_t(size),fp));
880 if (numberWritten!=size)
885 static_cast<CoinBigIndex>(fwrite(&size,
sizeof(
int),1,fp));
886 if (numberWritten!=1)
900 template <
class T>
inline int
905 static_cast<CoinBigIndex>(fread(&newSize,
sizeof(
int),1,fp));
909 if (size!=newSize&&(newSize||array))
912 array =
new T [newSize];
914 static_cast<CoinBigIndex>(fread(array,
sizeof(T),newSize,fp));
915 if (numberRead!=newSize)
927 inline double CoinCbrt(
double x)
929 #if defined(_MSC_VER)
930 return pow(x,(1./3.));
940 #define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type)))
945 return static_cast<int>(strlen(
string));
950 #if defined COIN_OWN_RANDOM_32
998 retVal = ((
static_cast<double> (
seed_))/4294967296.0);
1006 for (
int i=0;i<n;i++)
1016 mutable unsigned int seed_;
1031 { memcpy(
seed_,seed,3*
sizeof(
unsigned short));}
1035 union {
int i[2];
unsigned short int s[4];} put;
1038 memcpy(
seed_,put.s,3*
sizeof(
unsigned short));
1044 { memcpy(
seed_,rhs.
seed_,3*
sizeof(
unsigned short));}
1049 memcpy(
seed_,rhs.
seed_,3*
sizeof(
unsigned short));
1060 inline void setSeed(
const unsigned short seed[3])
1061 { memcpy(
seed_,seed,3*
sizeof(
unsigned short));}
1065 union {
int i[2];
unsigned short int s[4];} put;
1068 memcpy(
seed_,put.s,3*
sizeof(
unsigned short));
1074 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
1076 retVal=retVal/(double) RAND_MAX;
1078 retVal = erand48(
seed_);
1089 for (
int i=0;i<n;i++)
1099 mutable unsigned short seed_[3];
1105 #define COIN_DETAIL_PRINT(s) {}
1107 #define COIN_DETAIL_PRINT(s) s