CoinUtils 2.11.4
CoinHelperFunctions.hpp
Go to the documentation of this file.
1/* $Id$ */
2// Copyright (C) 2000, International Business Machines
3// Corporation and others. All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#ifndef CoinHelperFunctions_H
7#define CoinHelperFunctions_H
8
9#include "CoinUtilsConfig.h"
10
11#if defined(_MSC_VER)
12#include <direct.h>
13#include <cctype>
14#define getcwd _getcwd
15#include <cctype>
16#else
17#include <unistd.h>
18#endif
19//#define USE_MEMCPY
20
21#include <cstdlib>
22#include <cstdio>
23#include <algorithm>
24#include "CoinTypes.hpp"
25#include "CoinError.hpp"
26
27// Compilers can produce better code if they know about __restrict
28#ifndef COIN_RESTRICT
29#ifdef COIN_USE_RESTRICT
30#define COIN_RESTRICT __restrict
31#else
32#define COIN_RESTRICT
33#endif
34#endif
35
36//#############################################################################
37
43template < class T >
44inline void
45CoinCopyN(const T *from, const CoinBigIndex size, T *to)
46{
47 if (size == 0 || from == to)
48 return;
49
50#ifndef NDEBUG
51 if (size < 0)
52 throw CoinError("trying to copy negative number of entries",
53 "CoinCopyN", "");
54#endif
55
56 CoinBigIndex n = (size + 7) / 8;
57 if (to > from) {
58 const T *downfrom = from + size;
59 T *downto = to + size;
60 // Use Duff's device to copy
61 switch (size % 8) {
62 case 0:
63 do {
64 *--downto = *--downfrom;
65 case 7:
66 *--downto = *--downfrom;
67 case 6:
68 *--downto = *--downfrom;
69 case 5:
70 *--downto = *--downfrom;
71 case 4:
72 *--downto = *--downfrom;
73 case 3:
74 *--downto = *--downfrom;
75 case 2:
76 *--downto = *--downfrom;
77 case 1:
78 *--downto = *--downfrom;
79 } while (--n > 0);
80 }
81 } else {
82 // Use Duff's device to copy
83 --from;
84 --to;
85 switch (size % 8) {
86 case 0:
87 do {
88 *++to = *++from;
89 case 7:
90 *++to = *++from;
91 case 6:
92 *++to = *++from;
93 case 5:
94 *++to = *++from;
95 case 4:
96 *++to = *++from;
97 case 3:
98 *++to = *++from;
99 case 2:
100 *++to = *++from;
101 case 1:
102 *++to = *++from;
103 } while (--n > 0);
104 }
105 }
106}
107
108//-----------------------------------------------------------------------------
109
120template < class T >
121inline void
122CoinCopy(const T *first, const T *last, T *to)
123{
124 CoinCopyN(first, static_cast< CoinBigIndex >(last - first), to);
125}
126
127//-----------------------------------------------------------------------------
128
136template < class T >
137inline void
138CoinDisjointCopyN(const T *from, const CoinBigIndex size, T *to)
139{
140#ifndef _MSC_VER
141 if (size == 0 || from == to)
142 return;
143
144#ifndef NDEBUG
145 if (size < 0)
146 throw CoinError("trying to copy negative number of entries",
147 "CoinDisjointCopyN", "");
148#endif
149
150#if 0
151 /* There is no point to do this test. If to and from are from different
152 blocks then dist is undefined, so this can crash correct code. It's
153 better to trust the user that the arrays are really disjoint. */
154 const long dist = to - from;
155 if (-size < dist && dist < size)
156 throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
157#endif
158
159 for (CoinBigIndex n = size / 8; n > 0; --n, from += 8, to += 8) {
160 to[0] = from[0];
161 to[1] = from[1];
162 to[2] = from[2];
163 to[3] = from[3];
164 to[4] = from[4];
165 to[5] = from[5];
166 to[6] = from[6];
167 to[7] = from[7];
168 }
169 switch (size % 8) {
170 case 7:
171 to[6] = from[6];
172 case 6:
173 to[5] = from[5];
174 case 5:
175 to[4] = from[4];
176 case 4:
177 to[3] = from[3];
178 case 3:
179 to[2] = from[2];
180 case 2:
181 to[1] = from[1];
182 case 1:
183 to[0] = from[0];
184 case 0:
185 break;
186 }
187#else
188 CoinCopyN(from, size, to);
189#endif
190}
191
192//-----------------------------------------------------------------------------
193
198template < class T >
199inline void
200CoinDisjointCopy(const T *first, const T *last,
201 T *to)
202{
203 CoinDisjointCopyN(first, static_cast< CoinBigIndex >(last - first), to);
204}
205
206//-----------------------------------------------------------------------------
207
212template < class T >
213inline T *
214CoinCopyOfArray(const T *array, const CoinBigIndex size)
215{
216 if (array) {
217 T *arrayNew = new T[size];
218 std::memcpy(arrayNew, array, size * sizeof(T));
219 return arrayNew;
220 } else {
221 return NULL;
222 }
223}
224
229template < class T >
230inline T *
231CoinCopyOfArrayPartial(const T *array, const CoinBigIndex size, const CoinBigIndex copySize)
232{
233 if (array || size) {
234 T *arrayNew = new T[size];
235 assert(copySize <= size);
236 std::memcpy(arrayNew, array, copySize * sizeof(T));
237 return arrayNew;
238 } else {
239 return NULL;
240 }
241}
242
247template < class T >
248inline T *
249CoinCopyOfArray(const T *array, const CoinBigIndex size, T value)
250{
251 T *arrayNew = new T[size];
252 if (array) {
253 std::memcpy(arrayNew, array, size * sizeof(T));
254 } else {
255 CoinBigIndex i;
256 for (i = 0; i < size; i++)
257 arrayNew[i] = value;
258 }
259 return arrayNew;
260}
261
266template < class T >
267inline T *
268CoinCopyOfArrayOrZero(const T *array, const CoinBigIndex size)
269{
270 T *arrayNew = new T[size];
271 if (array) {
272 std::memcpy(arrayNew, array, size * sizeof(T));
273 } else {
274 std::memset(arrayNew, 0, size * sizeof(T));
275 }
276 return arrayNew;
277}
278
279//-----------------------------------------------------------------------------
280
288#ifndef COIN_USE_RESTRICT
289template < class T >
290inline void
291CoinMemcpyN(const T *from, const CoinBigIndex size, T *to)
292{
293#ifndef _MSC_VER
294#ifdef USE_MEMCPY
295 // Use memcpy - seems a lot faster on Intel with gcc
296#ifndef NDEBUG
297 // Some debug so check
298 if (size < 0)
299 throw CoinError("trying to copy negative number of entries",
300 "CoinMemcpyN", "");
301
302#if 0
303 /* There is no point to do this test. If to and from are from different
304 blocks then dist is undefined, so this can crash correct code. It's
305 better to trust the user that the arrays are really disjoint. */
306 const long dist = to - from;
307 if (-size < dist && dist < size)
308 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
309#endif
310#endif
311 std::memcpy(to, from, size * sizeof(T));
312#else
313 if (size == 0 || from == to)
314 return;
315
316#ifndef NDEBUG
317 if (size < 0)
318 throw CoinError("trying to copy negative number of entries",
319 "CoinMemcpyN", "");
320#endif
321
322#if 0
323 /* There is no point to do this test. If to and from are from different
324 blocks then dist is undefined, so this can crash correct code. It's
325 better to trust the user that the arrays are really disjoint. */
326 const long dist = to - from;
327 if (-size < dist && dist < size)
328 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
329#endif
330
331 for (CoinBigIndex n = static_cast<CoinBigIndex>(size>>3); n > 0; --n, from += 8, to += 8) {
332 to[0] = from[0];
333 to[1] = from[1];
334 to[2] = from[2];
335 to[3] = from[3];
336 to[4] = from[4];
337 to[5] = from[5];
338 to[6] = from[6];
339 to[7] = from[7];
340 }
341 switch (size % 8) {
342 case 7:
343 to[6] = from[6];
344 case 6:
345 to[5] = from[5];
346 case 5:
347 to[4] = from[4];
348 case 4:
349 to[3] = from[3];
350 case 3:
351 to[2] = from[2];
352 case 2:
353 to[1] = from[1];
354 case 1:
355 to[0] = from[0];
356 case 0:
357 break;
358 }
359#endif
360#else
361 CoinCopyN(from, size, to);
362#endif
363}
364#else
365template < class T >
366inline void
367CoinMemcpyN(const T *COIN_RESTRICT from, CoinBigIndex size, T *COIN_RESTRICT to)
368{
369#ifdef USE_MEMCPY
370 std::memcpy(to, from, size * sizeof(T));
371#else
372 T *COIN_RESTRICT put = to;
373 const T *COIN_RESTRICT get = from;
374 for (; 0 < size; --size)
375 *put++ = *get++;
376#endif
377}
378#endif
379
380//-----------------------------------------------------------------------------
381
386template < class T >
387inline void
388CoinMemcpy(const T *first, const T *last,
389 T *to)
390{
391 CoinMemcpyN(first, static_cast< CoinBigIndex >(last - first), to);
392}
393
394//#############################################################################
395
402template < class T >
403inline void
404CoinFillN(T *to, const CoinBigIndex size, const T value)
405{
406 if (size == 0)
407 return;
408
409#ifndef NDEBUG
410 if (size < 0)
411 throw CoinError("trying to fill negative number of entries",
412 "CoinFillN", "");
413#endif
414#if 1
415 for (CoinBigIndex n = size / 8; n > 0; --n, to += 8) {
416 to[0] = value;
417 to[1] = value;
418 to[2] = value;
419 to[3] = value;
420 to[4] = value;
421 to[5] = value;
422 to[6] = value;
423 to[7] = value;
424 }
425 switch (size % 8) {
426 case 7:
427 to[6] = value;
428 // fall through
429 case 6:
430 to[5] = value;
431 // fall through
432 case 5:
433 to[4] = value;
434 // fall through
435 case 4:
436 to[3] = value;
437 // fall through
438 case 3:
439 to[2] = value;
440 // fall through
441 case 2:
442 to[1] = value;
443 // fall through
444 case 1:
445 to[0] = value;
446 // fall through
447 case 0:
448 break;
449 }
450#else
451 // Use Duff's device to fill
452 CoinBigIndex n = (size + 7) / 8;
453 --to;
454 switch (size % 8) {
455 case 0:
456 do {
457 *++to = value;
458 case 7:
459 *++to = value;
460 case 6:
461 *++to = value;
462 case 5:
463 *++to = value;
464 case 4:
465 *++to = value;
466 case 3:
467 *++to = value;
468 case 2:
469 *++to = value;
470 case 1:
471 *++to = value;
472 } while (--n > 0);
473 }
474#endif
475}
476
477//-----------------------------------------------------------------------------
478
482template < class T >
483inline void
484CoinFill(T *first, T *last, const T value)
485{
486 CoinFillN(first, last - first, value);
487}
488
489//#############################################################################
490
497template < class T >
498inline void
499CoinZeroN(T *to, const CoinBigIndex size)
500{
501#ifdef USE_MEMCPY
502 // Use memset - seems faster on Intel with gcc
503#ifndef NDEBUG
504 // Some debug so check
505 if (size < 0)
506 throw CoinError("trying to fill negative number of entries",
507 "CoinZeroN", "");
508#endif
509 memset(to, 0, size * sizeof(T));
510#else
511 if (size == 0)
512 return;
513
514#ifndef NDEBUG
515 if (size < 0)
516 throw CoinError("trying to fill negative number of entries",
517 "CoinZeroN", "");
518#endif
519#if 1
520 for (CoinBigIndex n = size / 8; n > 0; --n, to += 8) {
521 to[0] = 0;
522 to[1] = 0;
523 to[2] = 0;
524 to[3] = 0;
525 to[4] = 0;
526 to[5] = 0;
527 to[6] = 0;
528 to[7] = 0;
529 }
530 switch (size % 8) {
531 case 7:
532 to[6] = 0;
533 case 6:
534 to[5] = 0;
535 case 5:
536 to[4] = 0;
537 case 4:
538 to[3] = 0;
539 case 3:
540 to[2] = 0;
541 case 2:
542 to[1] = 0;
543 case 1:
544 to[0] = 0;
545 case 0:
546 break;
547 }
548#else
549 // Use Duff's device to fill
550 CoinBigIndex n = (size + 7) / 8;
551 --to;
552 switch (size % 8) {
553 case 0:
554 do {
555 *++to = 0;
556 case 7:
557 *++to = 0;
558 case 6:
559 *++to = 0;
560 case 5:
561 *++to = 0;
562 case 4:
563 *++to = 0;
564 case 3:
565 *++to = 0;
566 case 2:
567 *++to = 0;
568 case 1:
569 *++to = 0;
570 } while (--n > 0);
571 }
572#endif
573#endif
574}
576inline void
577CoinCheckDoubleZero(double *to, const CoinBigIndex size)
578{
579 CoinBigIndex n = 0;
580 for (CoinBigIndex j = 0; j < size; j++) {
581 if (to[j])
582 n++;
583 }
584 if (n) {
585 printf("array of length %d should be zero has %d nonzero\n",
586 static_cast< int >(size), static_cast< int >(n));
587 }
588}
590inline void
591CoinCheckIntZero(int *to, const CoinBigIndex size)
592{
593 CoinBigIndex n = 0;
594 for (CoinBigIndex j = 0; j < size; j++) {
595 if (to[j])
596 n++;
597 }
598 if (n) {
599 printf("array of length %d should be zero has %d nonzero\n",
600 static_cast< int >(size),
601 static_cast< int >(n));
602 }
603}
604
605//-----------------------------------------------------------------------------
606
610template < class T >
611inline void
612CoinZero(T *first, T *last)
613{
614 CoinZeroN(first, last - first);
615}
616
617//#############################################################################
618
620inline char *CoinStrdup(const char *name)
621{
622 char *dup = NULL;
623 if (name) {
624 const int len = static_cast< int >(strlen(name));
625 dup = static_cast< char * >(malloc(len + 1));
626 CoinMemcpyN(name, len, dup);
627 dup[len] = 0;
628 }
629 return dup;
630}
631
632//#############################################################################
633
637template < class T >
638inline T
639CoinMax(const T x1, const T x2)
640{
641 return (x1 > x2) ? x1 : x2;
642}
643
644//-----------------------------------------------------------------------------
645
649template < class T >
650inline T
651CoinMin(const T x1, const T x2)
652{
653 return (x1 < x2) ? x1 : x2;
654}
655
656//-----------------------------------------------------------------------------
657
661template < class T >
662inline T
663CoinAbs(const T value)
664{
665 return value < 0 ? -value : value;
666}
667
668//#############################################################################
669
673template < class T >
674inline bool
675CoinIsSorted(const T *first, const CoinBigIndex size)
676{
677 if (size == 0)
678 return true;
679
680#ifndef NDEBUG
681 if (size < 0)
682 throw CoinError("negative number of entries", "CoinIsSorted", "");
683#endif
684#if 1
685 // size1 is the number of comparisons to be made
686 const CoinBigIndex size1 = size - 1;
687 for (CoinBigIndex n = size1 / 8; n > 0; --n, first += 8) {
688 if (first[8] < first[7])
689 return false;
690 if (first[7] < first[6])
691 return false;
692 if (first[6] < first[5])
693 return false;
694 if (first[5] < first[4])
695 return false;
696 if (first[4] < first[3])
697 return false;
698 if (first[3] < first[2])
699 return false;
700 if (first[2] < first[1])
701 return false;
702 if (first[1] < first[0])
703 return false;
704 }
705
706 switch (size1 % 8) {
707 case 7:
708 if (first[7] < first[6])
709 return false;
710 case 6:
711 if (first[6] < first[5])
712 return false;
713 case 5:
714 if (first[5] < first[4])
715 return false;
716 case 4:
717 if (first[4] < first[3])
718 return false;
719 case 3:
720 if (first[3] < first[2])
721 return false;
722 case 2:
723 if (first[2] < first[1])
724 return false;
725 case 1:
726 if (first[1] < first[0])
727 return false;
728 case 0:
729 break;
730 }
731#else
732 const T *next = first;
733 const T *last = first + size;
734 for (++next; next != last; first = next, ++next)
735 if (*next < *first)
736 return false;
737#endif
738 return true;
739}
740
741//-----------------------------------------------------------------------------
742
746template < class T >
747inline bool
748CoinIsSorted(const T *first, const T *last)
749{
750 return CoinIsSorted(first, static_cast< CoinBigIndex >(last - first));
751}
752
753//#############################################################################
754
758template < class T >
759inline void
760CoinIotaN(T *first, const CoinBigIndex size, T init)
761{
762 if (size == 0)
763 return;
764
765#ifndef NDEBUG
766 if (size < 0)
767 throw CoinError("negative number of entries", "CoinIotaN", "");
768#endif
769#if 1
770 for (CoinBigIndex n = size / 8; n > 0; --n, first += 8, init += 8) {
771 first[0] = init;
772 first[1] = init + 1;
773 first[2] = init + 2;
774 first[3] = init + 3;
775 first[4] = init + 4;
776 first[5] = init + 5;
777 first[6] = init + 6;
778 first[7] = init + 7;
779 }
780 switch (size % 8) {
781 case 7:
782 first[6] = init + 6;
783 case 6:
784 first[5] = init + 5;
785 case 5:
786 first[4] = init + 4;
787 case 4:
788 first[3] = init + 3;
789 case 3:
790 first[2] = init + 2;
791 case 2:
792 first[1] = init + 1;
793 case 1:
794 first[0] = init;
795 case 0:
796 break;
797 }
798#else
799 // Use Duff's device to fill
800 CoinBigIndex n = (size + 7) / 8;
801 --first;
802 --init;
803 switch (size % 8) {
804 case 0:
805 do {
806 *++first = ++init;
807 case 7:
808 *++first = ++init;
809 case 6:
810 *++first = ++init;
811 case 5:
812 *++first = ++init;
813 case 4:
814 *++first = ++init;
815 case 3:
816 *++first = ++init;
817 case 2:
818 *++first = ++init;
819 case 1:
820 *++first = ++init;
821 } while (--n > 0);
822 }
823#endif
824}
825
826//-----------------------------------------------------------------------------
827
831template < class T >
832inline void
833CoinIota(T *first, const T *last, T init)
834{
835 CoinIotaN(first, last - first, init);
836}
837
838//#############################################################################
839
845template < class T >
846inline T *
847CoinDeleteEntriesFromArray(T *arrayFirst, T *arrayLast,
848 const int *firstDelPos, const int *lastDelPos)
849{
850 CoinBigIndex delNum = static_cast< CoinBigIndex >(lastDelPos - firstDelPos);
851 if (delNum == 0)
852 return arrayLast;
853
854 if (delNum < 0)
855 throw CoinError("trying to delete negative number of entries",
856 "CoinDeleteEntriesFromArray", "");
857
858 int *delSortedPos = NULL;
859 if (!(CoinIsSorted(firstDelPos, lastDelPos) && std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
860 // the positions of the to be deleted is either not sorted or not unique
861 delSortedPos = new int[delNum];
862 CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
863 std::sort(delSortedPos, delSortedPos + delNum);
864 delNum = static_cast< CoinBigIndex >(std::unique(delSortedPos,
865 delSortedPos + delNum)
866 - delSortedPos);
867 }
868 const int *delSorted = delSortedPos ? delSortedPos : firstDelPos;
869
870 const CoinBigIndex last = delNum - 1;
871 int size = delSorted[0];
872 for (CoinBigIndex i = 0; i < last; ++i) {
873 const int copyFirst = delSorted[i] + 1;
874 const int copyLast = delSorted[i + 1];
875 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
876 arrayFirst + size);
877 size += copyLast - copyFirst;
878 }
879 const int copyFirst = delSorted[last] + 1;
880 const int copyLast = static_cast< int >(arrayLast - arrayFirst);
881 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
882 arrayFirst + size);
883 size += copyLast - copyFirst;
884
885 if (delSortedPos)
886 delete[] delSortedPos;
887
888 return arrayFirst + size;
889}
890
891//#############################################################################
892
893#define COIN_OWN_RANDOM_32
894
895#if defined COIN_OWN_RANDOM_32
896/* Thanks to Stefano Gliozzi for providing an operating system
897 independent random number generator. */
898
911inline double CoinDrand48(bool isSeed = false, unsigned int seed = 1)
912{
913 static unsigned int last = 123456;
914 if (isSeed) {
915 last = seed;
916 } else {
917 last = 1664525 * last + 1013904223;
918 return ((static_cast< double >(last)) / 4294967296.0);
919 }
920 return (0.0);
921}
922
924inline void CoinSeedRandom(int iseed)
925{
926 CoinDrand48(true, iseed);
927}
928
929#else // COIN_OWN_RANDOM_32
930
931#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
932
934inline double CoinDrand48() { return rand() / (double)RAND_MAX; }
936inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
937
938#else
939
941inline double CoinDrand48() { return drand48(); }
943inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
944
945#endif
946
947#endif // COIN_OWN_RANDOM_32
948
949//#############################################################################
950
954{
955 int size = 1000;
956 char *buf = 0;
957 while (true) {
958 buf = new char[size];
959 if (getcwd(buf, size))
960 break;
961 delete[] buf;
962 buf = 0;
963 size = 2 * size;
964 }
965 // if first char is '/' then it's unix and the dirsep is '/'. otherwise we
966 // assume it's dos and the dirsep is '\'
967 char dirsep = buf[0] == '/' ? '/' : '\\';
968 delete[] buf;
969 return dirsep;
970}
971//#############################################################################
972
973inline int CoinStrNCaseCmp(const char *s0, const char *s1,
974 const size_t len)
975{
976 for (size_t i = 0; i < len; ++i) {
977 if (s0[i] == 0) {
978 return s1[i] == 0 ? 0 : -1;
979 }
980 if (s1[i] == 0) {
981 return 1;
982 }
983 const int c0 = std::tolower(s0[i]);
984 const int c1 = std::tolower(s1[i]);
985 if (c0 < c1)
986 return -1;
987 if (c0 > c1)
988 return 1;
989 }
990 return 0;
991}
992
993//#############################################################################
994
996template < class T >
997inline void CoinSwap(T &x, T &y)
998{
999 T t = x;
1000 x = y;
1001 y = t;
1002}
1003
1004//#############################################################################
1005
1010template < class T >
1011inline int
1012CoinToFile(const T *array, CoinBigIndex size, FILE *fp)
1013{
1014 CoinBigIndex numberWritten;
1015 if (array && size) {
1016 numberWritten = static_cast< CoinBigIndex >(fwrite(&size, sizeof(int), 1, fp));
1017 if (numberWritten != 1)
1018 return 1;
1019 numberWritten = static_cast< CoinBigIndex >(fwrite(array, sizeof(T), size_t(size), fp));
1020 if (numberWritten != size)
1021 return 1;
1022 } else {
1023 size = 0;
1024 numberWritten = static_cast< CoinBigIndex >(fwrite(&size, sizeof(int), 1, fp));
1025 if (numberWritten != 1)
1026 return 1;
1027 }
1028 return 0;
1029}
1030
1031//#############################################################################
1032
1039template < class T >
1040inline int
1041CoinFromFile(T *&array, CoinBigIndex size, FILE *fp, CoinBigIndex &newSize)
1042{
1043 CoinBigIndex numberRead;
1044 numberRead = static_cast< CoinBigIndex >(fread(&newSize, sizeof(int), 1, fp));
1045 if (numberRead != 1)
1046 return 1;
1047 int returnCode = 0;
1048 if (size != newSize && (newSize || array))
1049 returnCode = 2;
1050 if (newSize) {
1051 array = new T[newSize];
1052 numberRead = static_cast< CoinBigIndex >(fread(array, sizeof(T), newSize, fp));
1053 if (numberRead != newSize)
1054 returnCode = 1;
1055 } else {
1056 array = NULL;
1057 }
1058 return returnCode;
1059}
1060
1061//#############################################################################
1062
1064#if 0
1065inline double CoinCbrt(double x)
1066{
1067#if defined(_MSC_VER)
1068 return pow(x,(1./3.));
1069#else
1070 return cbrt(x);
1071#endif
1072}
1073#endif
1074
1075//-----------------------------------------------------------------------------
1076
1078#define CoinSizeofAsInt(type) (static_cast< int >(sizeof(type)))
1080inline int
1081CoinStrlenAsInt(const char *string)
1082{
1083 return static_cast< int >(strlen(string));
1084}
1085
1088#if defined COIN_OWN_RANDOM_32
1090public:
1096 {
1097 seed_ = 12345678;
1098 }
1101 {
1102 seed_ = seed;
1103 }
1106 // Copy
1108 {
1109 seed_ = rhs.seed_;
1110 }
1111 // Assignment
1113 {
1114 if (this != &rhs) {
1115 seed_ = rhs.seed_;
1116 }
1117 return *this;
1118 }
1119
1121
1126 inline void setSeed(int seed)
1127 {
1128 seed_ = seed;
1129 }
1131 inline unsigned int getSeed() const
1132 {
1133 return seed_;
1134 }
1136 inline double randomDouble() const
1137 {
1138 double retVal;
1139 seed_ = 1664525 * (seed_) + 1013904223;
1140 retVal = ((static_cast< double >(seed_)) / 4294967296.0);
1141 return retVal;
1142 }
1144 inline void randomize(int n = 0)
1145 {
1146 if (!n)
1147 n = seed_ & 255;
1148 for (int i = 0; i < n; i++)
1149 randomDouble();
1150 }
1152
1153protected:
1158 mutable unsigned int seed_;
1160};
1161#else
1162class CoinThreadRandom {
1163public:
1169 {
1170 seed_[0] = 50000;
1171 seed_[1] = 40000;
1172 seed_[2] = 30000;
1173 }
1175 CoinThreadRandom(const unsigned short seed[3])
1176 {
1177 memcpy(seed_, seed, 3 * sizeof(unsigned short));
1178 }
1180 CoinThreadRandom(int seed)
1181 {
1182 union {
1183 int i[2];
1184 unsigned short int s[4];
1185 } put;
1186 put.i[0] = seed;
1187 put.i[1] = seed;
1188 memcpy(seed_, put.s, 3 * sizeof(unsigned short));
1189 }
1192 // Copy
1194 {
1195 memcpy(seed_, rhs.seed_, 3 * sizeof(unsigned short));
1196 }
1197 // Assignment
1199 {
1200 if (this != &rhs) {
1201 memcpy(seed_, rhs.seed_, 3 * sizeof(unsigned short));
1202 }
1203 return *this;
1204 }
1205
1207
1212 inline void setSeed(const unsigned short seed[3])
1213 {
1214 memcpy(seed_, seed, 3 * sizeof(unsigned short));
1215 }
1217 inline void setSeed(int seed)
1218 {
1219 union {
1220 int i[2];
1221 unsigned short int s[4];
1222 } put;
1223 put.i[0] = seed;
1224 put.i[1] = seed;
1225 memcpy(seed_, put.s, 3 * sizeof(unsigned short));
1226 }
1228 inline double randomDouble() const
1229 {
1230 double retVal;
1231#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
1232 retVal = rand();
1233 retVal = retVal / (double)RAND_MAX;
1234#else
1235 retVal = erand48(seed_);
1236#endif
1237 return retVal;
1238 }
1240 inline void randomize(int n = 0)
1241 {
1242 if (!n) {
1243 n = seed_[0] + seed_[1] + seed_[2];
1244 n &= 255;
1245 }
1246 for (int i = 0; i < n; i++)
1247 randomDouble();
1248 }
1250
1251protected:
1256 mutable unsigned short seed_[3];
1258};
1259#endif
1260#ifndef COIN_DETAIL
1261#define COIN_DETAIL_PRINT(s) \
1262 { \
1263 }
1264#else
1265#define COIN_DETAIL_PRINT(s) s
1266#endif
1267#endif
1268
1269/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
1270*/
T * CoinCopyOfArray(const T *array, const CoinBigIndex size)
Return an array of length size filled with input from array, or null if array is null.
int CoinStrNCaseCmp(const char *s0, const char *s1, const size_t len)
void CoinCheckIntZero(int *to, const CoinBigIndex size)
This Debug helper function checks an array is all zero.
void CoinZeroN(T *to, const CoinBigIndex size)
This helper function fills an array with zero.
T * CoinDeleteEntriesFromArray(T *arrayFirst, T *arrayLast, const int *firstDelPos, const int *lastDelPos)
This helper function deletes certain entries from an array.
void CoinFillN(T *to, const CoinBigIndex size, const T value)
This helper function fills an array with a given value.
int CoinStrlenAsInt(const char *string)
This helper returns "strlen" as an int.
char * CoinStrdup(const char *name)
Returns strdup or NULL if original NULL.
T * CoinCopyOfArrayOrZero(const T *array, const CoinBigIndex size)
Return an array of length size filled with input from array, or filled with zero if array is null.
T CoinMin(const T x1, const T x2)
Return the smaller (according to operator<() of the arguments.
char CoinFindDirSeparator()
This function figures out whether file names should contain slashes or backslashes as directory separ...
int CoinFromFile(T *&array, CoinBigIndex size, FILE *fp, CoinBigIndex &newSize)
This helper function copies an array from file and creates with new.
T * CoinCopyOfArrayPartial(const T *array, const CoinBigIndex size, const CoinBigIndex copySize)
Return an array of length size filled with first copySize from array, or null if array is null.
void CoinFill(T *first, T *last, const T value)
This helper function fills an array with a given value.
void CoinDisjointCopy(const T *first, const T *last, T *to)
This helper function copies an array to another location.
bool CoinIsSorted(const T *first, const CoinBigIndex size)
This helper function tests whether the entries of an array are sorted according to operator<.
double CoinDrand48(bool isSeed=false, unsigned int seed=1)
Return a random number between 0 and 1.
void CoinSeedRandom(int iseed)
Set the seed for the random number generator.
void CoinCheckDoubleZero(double *to, const CoinBigIndex size)
This Debug helper function checks an array is all zero.
void CoinCopyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location using Duff's device (for a speedup of ~2).
void CoinZero(T *first, T *last)
This helper function fills an array with a given value.
void CoinCopy(const T *first, const T *last, T *to)
This helper function copies an array to another location using Duff's device (for a speedup of ~2).
void CoinIota(T *first, const T *last, T init)
This helper function fills an array with the values init, init+1, init+2, etc.
void CoinMemcpyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location.
T CoinMax(const T x1, const T x2)
Return the larger (according to operator<() of the arguments.
void CoinIotaN(T *first, const CoinBigIndex size, T init)
This helper function fills an array with the values init, init+1, init+2, etc.
void CoinDisjointCopyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location.
void CoinSwap(T &x, T &y)
Swap the arguments.
#define COIN_RESTRICT
T CoinAbs(const T value)
Return the absolute value of the argument.
void CoinMemcpy(const T *first, const T *last, T *to)
This helper function copies an array to another location.
int CoinToFile(const T *array, CoinBigIndex size, FILE *fp)
This helper function copies an array to file Returns 0 if OK, 1 if bad write.
int CoinBigIndex
Error Class thrown by an exception.
Definition: CoinError.hpp:42
Class for thread specific random numbers.
CoinThreadRandom()
Default constructor.
void randomize(int n=0)
make more random (i.e. for startup)
CoinThreadRandom(int seed)
Constructor wih seed.
CoinThreadRandom & operator=(const CoinThreadRandom &rhs)
~CoinThreadRandom()
Destructor.
double randomDouble() const
return a random number
void setSeed(int seed)
Set seed.
CoinThreadRandom(const CoinThreadRandom &rhs)
unsigned int getSeed() const
Get seed.
unsigned int seed_
Current seed.