Cgl 0.60.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CoinHelperFunctions.hpp
Go to the documentation of this file.
1 /* $Id: CoinHelperFunctions.hpp 2083 2019-01-06 19:38:09Z unxusr $ */
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
43 template < class T >
44 inline void
45 CoinCopyN(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
120 template < class T >
121 inline void
122 CoinCopy(const T *first, const T *last, T *to)
123 {
124 CoinCopyN(first, static_cast< CoinBigIndex >(last - first), to);
125 }
126
127 //-----------------------------------------------------------------------------
128
136 template < class T >
137 inline void
138 CoinDisjointCopyN(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
198 template < class T >
199 inline void
200 CoinDisjointCopy(const T *first, const T *last,
201 T *to)
202 {
203 CoinDisjointCopyN(first, static_cast< CoinBigIndex >(last - first), to);
204 }
205
206 //-----------------------------------------------------------------------------
207
212 template < class T >
213 inline T *
214 CoinCopyOfArray(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
229 template < class T >
230 inline T *
231 CoinCopyOfArrayPartial(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
247 template < class T >
248 inline T *
249 CoinCopyOfArray(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
266 template < class T >
267 inline T *
268 CoinCopyOfArrayOrZero(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
289 template < class T >
290 inline void
291 CoinMemcpyN(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 = size / 8; 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
365 template < class T >
366 inline void
367 CoinMemcpyN(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
386 template < class T >
387 inline void
388 CoinMemcpy(const T *first, const T *last,
389 T *to)
390 {
391 CoinMemcpyN(first, static_cast< CoinBigIndex >(last - first), to);
392 }
393
394 //#############################################################################
395
402 template < class T >
403 inline void
404 CoinFillN(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 case 6:
429 to[5] = value;
430 case 5:
431 to[4] = value;
432 case 4:
433 to[3] = value;
434 case 3:
435 to[2] = value;
436 case 2:
437 to[1] = value;
438 case 1:
439 to[0] = value;
440 case 0:
441 break;
442 }
443 #else
444 // Use Duff's device to fill
445 CoinBigIndex n = (size + 7) / 8;
446 --to;
447 switch (size % 8) {
448 case 0:
449 do {
450 *++to = value;
451 case 7:
452 *++to = value;
453 case 6:
454 *++to = value;
455 case 5:
456 *++to = value;
457 case 4:
458 *++to = value;
459 case 3:
460 *++to = value;
461 case 2:
462 *++to = value;
463 case 1:
464 *++to = value;
465 } while (--n > 0);
466 }
467 #endif
468 }
469
470 //-----------------------------------------------------------------------------
471
475 template < class T >
476 inline void
477 CoinFill(T *first, T *last, const T value)
478 {
479 CoinFillN(first, last - first, value);
480 }
481
482 //#############################################################################
483
490 template < class T >
491 inline void
492 CoinZeroN(T *to, const CoinBigIndex size)
493 {
494 #ifdef USE_MEMCPY
495 // Use memset - seems faster on Intel with gcc
496 #ifndef NDEBUG
497 // Some debug so check
498 if (size < 0)
499 throw CoinError("trying to fill negative number of entries",
500 "CoinZeroN", "");
501 #endif
502 memset(to, 0, size * sizeof(T));
503 #else
504 if (size == 0)
505 return;
506
507 #ifndef NDEBUG
508 if (size < 0)
509 throw CoinError("trying to fill negative number of entries",
510 "CoinZeroN", "");
511 #endif
512 #if 1
513 for (CoinBigIndex n = size / 8; n > 0; --n, to += 8) {
514 to[0] = 0;
515 to[1] = 0;
516 to[2] = 0;
517 to[3] = 0;
518 to[4] = 0;
519 to[5] = 0;
520 to[6] = 0;
521 to[7] = 0;
522 }
523 switch (size % 8) {
524 case 7:
525 to[6] = 0;
526 case 6:
527 to[5] = 0;
528 case 5:
529 to[4] = 0;
530 case 4:
531 to[3] = 0;
532 case 3:
533 to[2] = 0;
534 case 2:
535 to[1] = 0;
536 case 1:
537 to[0] = 0;
538 case 0:
539 break;
540 }
541 #else
542 // Use Duff's device to fill
543 CoinBigIndex n = (size + 7) / 8;
544 --to;
545 switch (size % 8) {
546 case 0:
547 do {
548 *++to = 0;
549 case 7:
550 *++to = 0;
551 case 6:
552 *++to = 0;
553 case 5:
554 *++to = 0;
555 case 4:
556 *++to = 0;
557 case 3:
558 *++to = 0;
559 case 2:
560 *++to = 0;
561 case 1:
562 *++to = 0;
563 } while (--n > 0);
564 }
565 #endif
566 #endif
567 }
569 inline void
570 CoinCheckDoubleZero(double *to, const CoinBigIndex size)
571 {
572 CoinBigIndex n = 0;
573 for (CoinBigIndex j = 0; j < size; j++) {
574 if (to[j])
575 n++;
576 }
577 if (n) {
578 printf("array of length %d should be zero has %d nonzero\n",
579 static_cast< int >(size), static_cast< int >(n));
580 }
581 }
583 inline void
584 CoinCheckIntZero(int *to, const CoinBigIndex size)
585 {
586 CoinBigIndex n = 0;
587 for (CoinBigIndex j = 0; j < size; j++) {
588 if (to[j])
589 n++;
590 }
591 if (n) {
592 printf("array of length %d should be zero has %d nonzero\n",
593 static_cast< int >(size),
594 static_cast< int >(n));
595 }
596 }
597
598 //-----------------------------------------------------------------------------
599
603 template < class T >
604 inline void
605 CoinZero(T *first, T *last)
606 {
607 CoinZeroN(first, last - first);
608 }
609
610 //#############################################################################
611
613 inline char *CoinStrdup(const char *name)
614 {
615 char *dup = NULL;
616 if (name) {
617 const int len = static_cast< int >(strlen(name));
618 dup = static_cast< char * >(malloc(len + 1));
619 CoinMemcpyN(name, len, dup);
620 dup[len] = 0;
621 }
622 return dup;
623 }
624
625 //#############################################################################
626
630 template < class T >
631 inline T
632 CoinMax(const T x1, const T x2)
633 {
634 return (x1 > x2) ? x1 : x2;
635 }
636
637 //-----------------------------------------------------------------------------
638
642 template < class T >
643 inline T
644 CoinMin(const T x1, const T x2)
645 {
646 return (x1 < x2) ? x1 : x2;
647 }
648
649 //-----------------------------------------------------------------------------
650
654 template < class T >
655 inline T
656 CoinAbs(const T value)
657 {
658 return value < 0 ? -value : value;
659 }
660
661 //#############################################################################
662
666 template < class T >
667 inline bool
668 CoinIsSorted(const T *first, const CoinBigIndex size)
669 {
670 if (size == 0)
671 return true;
672
673 #ifndef NDEBUG
674 if (size < 0)
675 throw CoinError("negative number of entries", "CoinIsSorted", "");
676 #endif
677 #if 1
678 // size1 is the number of comparisons to be made
679 const CoinBigIndex size1 = size - 1;
680 for (CoinBigIndex n = size1 / 8; n > 0; --n, first += 8) {
681 if (first[8] < first[7])
682 return false;
683 if (first[7] < first[6])
684 return false;
685 if (first[6] < first[5])
686 return false;
687 if (first[5] < first[4])
688 return false;
689 if (first[4] < first[3])
690 return false;
691 if (first[3] < first[2])
692 return false;
693 if (first[2] < first[1])
694 return false;
695 if (first[1] < first[0])
696 return false;
697 }
698
699 switch (size1 % 8) {
700 case 7:
701 if (first[7] < first[6])
702 return false;
703 case 6:
704 if (first[6] < first[5])
705 return false;
706 case 5:
707 if (first[5] < first[4])
708 return false;
709 case 4:
710 if (first[4] < first[3])
711 return false;
712 case 3:
713 if (first[3] < first[2])
714 return false;
715 case 2:
716 if (first[2] < first[1])
717 return false;
718 case 1:
719 if (first[1] < first[0])
720 return false;
721 case 0:
722 break;
723 }
724 #else
725 const T *next = first;
726 const T *last = first + size;
727 for (++next; next != last; first = next, ++next)
728 if (*next < *first)
729 return false;
730 #endif
731 return true;
732 }
733
734 //-----------------------------------------------------------------------------
735
739 template < class T >
740 inline bool
741 CoinIsSorted(const T *first, const T *last)
742 {
743 return CoinIsSorted(first, static_cast< CoinBigIndex >(last - first));
744 }
745
746 //#############################################################################
747
751 template < class T >
752 inline void
753 CoinIotaN(T *first, const CoinBigIndex size, T init)
754 {
755 if (size == 0)
756 return;
757
758 #ifndef NDEBUG
759 if (size < 0)
760 throw CoinError("negative number of entries", "CoinIotaN", "");
761 #endif
762 #if 1
763 for (CoinBigIndex n = size / 8; n > 0; --n, first += 8, init += 8) {
764 first[0] = init;
765 first[1] = init + 1;
766 first[2] = init + 2;
767 first[3] = init + 3;
768 first[4] = init + 4;
769 first[5] = init + 5;
770 first[6] = init + 6;
771 first[7] = init + 7;
772 }
773 switch (size % 8) {
774 case 7:
775 first[6] = init + 6;
776 case 6:
777 first[5] = init + 5;
778 case 5:
779 first[4] = init + 4;
780 case 4:
781 first[3] = init + 3;
782 case 3:
783 first[2] = init + 2;
784 case 2:
785 first[1] = init + 1;
786 case 1:
787 first[0] = init;
788 case 0:
789 break;
790 }
791 #else
792 // Use Duff's device to fill
793 CoinBigIndex n = (size + 7) / 8;
794 --first;
795 --init;
796 switch (size % 8) {
797 case 0:
798 do {
799 *++first = ++init;
800 case 7:
801 *++first = ++init;
802 case 6:
803 *++first = ++init;
804 case 5:
805 *++first = ++init;
806 case 4:
807 *++first = ++init;
808 case 3:
809 *++first = ++init;
810 case 2:
811 *++first = ++init;
812 case 1:
813 *++first = ++init;
814 } while (--n > 0);
815 }
816 #endif
817 }
818
819 //-----------------------------------------------------------------------------
820
824 template < class T >
825 inline void
826 CoinIota(T *first, const T *last, T init)
827 {
828 CoinIotaN(first, last - first, init);
829 }
830
831 //#############################################################################
832
838 template < class T >
839 inline T *
840 CoinDeleteEntriesFromArray(T *arrayFirst, T *arrayLast,
841 const int *firstDelPos, const int *lastDelPos)
842 {
843 CoinBigIndex delNum = static_cast< CoinBigIndex >(lastDelPos - firstDelPos);
844 if (delNum == 0)
845 return arrayLast;
846
847 if (delNum < 0)
848 throw CoinError("trying to delete negative number of entries",
849 "CoinDeleteEntriesFromArray", "");
850
851 int *delSortedPos = NULL;
852 if (!(CoinIsSorted(firstDelPos, lastDelPos) && std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
853 // the positions of the to be deleted is either not sorted or not unique
854 delSortedPos = new int[delNum];
855 CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
856 std::sort(delSortedPos, delSortedPos + delNum);
857 delNum = static_cast< CoinBigIndex >(std::unique(delSortedPos,
858 delSortedPos + delNum)
859 - delSortedPos);
860 }
861 const int *delSorted = delSortedPos ? delSortedPos : firstDelPos;
862
863 const CoinBigIndex last = delNum - 1;
864 int size = delSorted[0];
865 for (CoinBigIndex i = 0; i < last; ++i) {
866 const int copyFirst = delSorted[i] + 1;
867 const int copyLast = delSorted[i + 1];
868 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
869 arrayFirst + size);
870 size += copyLast - copyFirst;
871 }
872 const int copyFirst = delSorted[last] + 1;
873 const int copyLast = static_cast< int >(arrayLast - arrayFirst);
874 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
875 arrayFirst + size);
876 size += copyLast - copyFirst;
877
878 if (delSortedPos)
879 delete[] delSortedPos;
880
881 return arrayFirst + size;
882 }
883
884 //#############################################################################
885
886 #define COIN_OWN_RANDOM_32
887
888 #if defined COIN_OWN_RANDOM_32
889 /* Thanks to Stefano Gliozzi for providing an operating system
890 independent random number generator. */
891
904 inline double CoinDrand48(bool isSeed = false, unsigned int seed = 1)
905 {
906 static unsigned int last = 123456;
907 if (isSeed) {
908 last = seed;
909 } else {
910 last = 1664525 * last + 1013904223;
911 return ((static_cast< double >(last)) / 4294967296.0);
912 }
913 return (0.0);
914 }
915
917 inline void CoinSeedRandom(int iseed)
918 {
919 CoinDrand48(true, iseed);
920 }
921
922 #else // COIN_OWN_RANDOM_32
923
924 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
925
927 inline double CoinDrand48() { return rand() / (double)RAND_MAX; }
929 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
930
931 #else
932
934 inline double CoinDrand48() { return drand48(); }
936 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
937
938 #endif
939
940 #endif // COIN_OWN_RANDOM_32
941
942 //#############################################################################
943
946 inline char CoinFindDirSeparator()
947 {
948 int size = 1000;
949 char *buf = 0;
950 while (true) {
951 buf = new char[size];
952 if (getcwd(buf, size))
953 break;
954 delete[] buf;
955 buf = 0;
956 size = 2 * size;
957 }
958 // if first char is '/' then it's unix and the dirsep is '/'. otherwise we
959 // assume it's dos and the dirsep is '\'
960 char dirsep = buf[0] == '/' ? '/' : '\\';
961 delete[] buf;
962 return dirsep;
963 }
964 //#############################################################################
965
966 inline int CoinStrNCaseCmp(const char *s0, const char *s1,
967 const size_t len)
968 {
969 for (size_t i = 0; i < len; ++i) {
970 if (s0[i] == 0) {
971 return s1[i] == 0 ? 0 : -1;
972 }
973 if (s1[i] == 0) {
974 return 1;
975 }
976 const int c0 = std::tolower(s0[i]);
977 const int c1 = std::tolower(s1[i]);
978 if (c0 < c1)
979 return -1;
980 if (c0 > c1)
981 return 1;
982 }
983 return 0;
984 }
985
986 //#############################################################################
987
989 template < class T >
990 inline void CoinSwap(T &x, T &y)
991 {
992 T t = x;
993 x = y;
994 y = t;
995 }
996
997 //#############################################################################
998
1003 template < class T >
1004 inline int
1005 CoinToFile(const T *array, CoinBigIndex size, FILE *fp)
1006 {
1007 CoinBigIndex numberWritten;
1008 if (array && size) {
1009 numberWritten = static_cast< CoinBigIndex >(fwrite(&size, sizeof(int), 1, fp));
1010 if (numberWritten != 1)
1011 return 1;
1012 numberWritten = static_cast< CoinBigIndex >(fwrite(array, sizeof(T), size_t(size), fp));
1013 if (numberWritten != size)
1014 return 1;
1015 } else {
1016 size = 0;
1017 numberWritten = static_cast< CoinBigIndex >(fwrite(&size, sizeof(int), 1, fp));
1018 if (numberWritten != 1)
1019 return 1;
1020 }
1021 return 0;
1022 }
1023
1024 //#############################################################################
1025
1032 template < class T >
1033 inline int
1034 CoinFromFile(T *&array, CoinBigIndex size, FILE *fp, CoinBigIndex &newSize)
1035 {
1036 CoinBigIndex numberRead;
1037 numberRead = static_cast< CoinBigIndex >(fread(&newSize, sizeof(int), 1, fp));
1038 if (numberRead != 1)
1039 return 1;
1040 int returnCode = 0;
1041 if (size != newSize && (newSize || array))
1042 returnCode = 2;
1043 if (newSize) {
1044 array = new T[newSize];
1045 numberRead = static_cast< CoinBigIndex >(fread(array, sizeof(T), newSize, fp));
1046 if (numberRead != newSize)
1047 returnCode = 1;
1048 } else {
1049 array = NULL;
1050 }
1051 return returnCode;
1052 }
1053
1054 //#############################################################################
1055
1057 #if 0
1058 inline double CoinCbrt(double x)
1059 {
1060 #if defined(_MSC_VER)
1061 return pow(x,(1./3.));
1062 #else
1063 return cbrt(x);
1064 #endif
1065 }
1066 #endif
1067
1068 //-----------------------------------------------------------------------------
1069
1071 #define CoinSizeofAsInt(type) (static_cast< int >(sizeof(type)))
1072 inline int
1074 CoinStrlenAsInt(const char *string)
1075 {
1076 return static_cast< int >(strlen(string));
1077 }
1078
1081 #if defined COIN_OWN_RANDOM_32
1082 class CoinThreadRandom {
1083 public:
1088 CoinThreadRandom()
1089 {
1090 seed_ = 12345678;
1091 }
1093 CoinThreadRandom(int seed)
1094 {
1095 seed_ = seed;
1096 }
1098 ~CoinThreadRandom() {}
1099 // Copy
1100 CoinThreadRandom(const CoinThreadRandom &rhs)
1101 {
1102 seed_ = rhs.seed_;
1103 }
1104 // Assignment
1105 CoinThreadRandom &operator=(const CoinThreadRandom &rhs)
1106 {
1107 if (this != &rhs) {
1108 seed_ = rhs.seed_;
1109 }
1110 return *this;
1111 }
1112
1114
1119 inline void setSeed(int seed)
1120 {
1121 seed_ = seed;
1122 }
1124 inline unsigned int getSeed() const
1125 {
1126 return seed_;
1127 }
1129 inline double randomDouble() const
1130 {
1131 double retVal;
1132 seed_ = 1664525 * (seed_) + 1013904223;
1133 retVal = ((static_cast< double >(seed_)) / 4294967296.0);
1134 return retVal;
1135 }
1137 inline void randomize(int n = 0)
1138 {
1139 if (!n)
1140 n = seed_ & 255;
1141 for (int i = 0; i < n; i++)
1142 randomDouble();
1143 }
1145
1146 protected:
1150 mutable unsigned int seed_;
1153 };
1154 #else
1155 class CoinThreadRandom {
1156 public:
1161 CoinThreadRandom()
1162 {
1163 seed_[0] = 50000;
1164 seed_[1] = 40000;
1165 seed_[2] = 30000;
1166 }
1168 CoinThreadRandom(const unsigned short seed[3])
1169 {
1170 memcpy(seed_, seed, 3 * sizeof(unsigned short));
1171 }
1173 CoinThreadRandom(int seed)
1174 {
1175 union {
1176 int i[2];
1177 unsigned short int s[4];
1178 } put;
1179 put.i[0] = seed;
1180 put.i[1] = seed;
1181 memcpy(seed_, put.s, 3 * sizeof(unsigned short));
1182 }
1184 ~CoinThreadRandom() {}
1185 // Copy
1186 CoinThreadRandom(const CoinThreadRandom &rhs)
1187 {
1188 memcpy(seed_, rhs.seed_, 3 * sizeof(unsigned short));
1189 }
1190 // Assignment
1191 CoinThreadRandom &operator=(const CoinThreadRandom &rhs)
1192 {
1193 if (this != &rhs) {
1194 memcpy(seed_, rhs.seed_, 3 * sizeof(unsigned short));
1195 }
1196 return *this;
1197 }
1198
1200
1205 inline void setSeed(const unsigned short seed[3])
1206 {
1207 memcpy(seed_, seed, 3 * sizeof(unsigned short));
1208 }
1210 inline void setSeed(int seed)
1211 {
1212 union {
1213 int i[2];
1214 unsigned short int s[4];
1215 } put;
1216 put.i[0] = seed;
1217 put.i[1] = seed;
1218 memcpy(seed_, put.s, 3 * sizeof(unsigned short));
1219 }
1221 inline double randomDouble() const
1222 {
1223 double retVal;
1224 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
1225 retVal = rand();
1226 retVal = retVal / (double)RAND_MAX;
1227 #else
1228 retVal = erand48(seed_);
1229 #endif
1230 return retVal;
1231 }
1233 inline void randomize(int n = 0)
1234 {
1235 if (!n) {
1236 n = seed_[0] + seed_[1] + seed_[2];
1237 n &= 255;
1238 }
1239 for (int i = 0; i < n; i++)
1240 randomDouble();
1241 }
1243
1244 protected:
1248 mutable unsigned short seed_[3];
1251 };
1252 #endif
1253 #ifndef COIN_DETAIL
1254 #define COIN_DETAIL_PRINT(s) \
1255 { \
1256 }
1257 #else
1258 #define COIN_DETAIL_PRINT(s) s
1259 #endif
1260 #endif
1261
1262 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
1263 */
CoinError
Error Class thrown by an exception.
Definition: CoinError.hpp:42
CoinThreadRandom::CoinThreadRandom
CoinThreadRandom(const CoinThreadRandom &rhs)
Definition: CoinHelperFunctions.hpp:1100
CoinDisjointCopyN
void CoinDisjointCopyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location.
Definition: CoinHelperFunctions.hpp:138
CoinThreadRandom::getSeed
unsigned int getSeed() const
Get seed.
Definition: CoinHelperFunctions.hpp:1124
CoinSeedRandom
void CoinSeedRandom(int iseed)
Set the seed for the random number generator.
Definition: CoinHelperFunctions.hpp:917
CoinIota
void CoinIota(T *first, const T *last, T init)
This helper function fills an array with the values init, init+1, init+2, etc.
Definition: CoinHelperFunctions.hpp:826
CoinToFile
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.
Definition: CoinHelperFunctions.hpp:1005
CoinTypes.hpp
CoinCopyOfArrayOrZero
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...
Definition: CoinHelperFunctions.hpp:268
CoinDrand48
double CoinDrand48(bool isSeed=false, unsigned int seed=1)
Return a random number between 0 and 1.
Definition: CoinHelperFunctions.hpp:904
CoinThreadRandom::seed_
unsigned int seed_
Current seed.
Definition: CoinHelperFunctions.hpp:1151
CoinIotaN
void CoinIotaN(T *first, const CoinBigIndex size, T init)
This helper function fills an array with the values init, init+1, init+2, etc.
Definition: CoinHelperFunctions.hpp:753
CoinMemcpyN
void CoinMemcpyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location.
Definition: CoinHelperFunctions.hpp:291
CoinCheckDoubleZero
void CoinCheckDoubleZero(double *to, const CoinBigIndex size)
This Debug helper function checks an array is all zero.
Definition: CoinHelperFunctions.hpp:570
CoinFillN
void CoinFillN(T *to, const CoinBigIndex size, const T value)
This helper function fills an array with a given value.
Definition: CoinHelperFunctions.hpp:404
CoinStrdup
char * CoinStrdup(const char *name)
Returns strdup or NULL if original NULL.
Definition: CoinHelperFunctions.hpp:613
CoinError.hpp
CoinIsSorted
bool CoinIsSorted(const T *first, const CoinBigIndex size)
This helper function tests whether the entries of an array are sorted according to operator&lt;...
Definition: CoinHelperFunctions.hpp:668
CoinDeleteEntriesFromArray
T * CoinDeleteEntriesFromArray(T *arrayFirst, T *arrayLast, const int *firstDelPos, const int *lastDelPos)
This helper function deletes certain entries from an array.
Definition: CoinHelperFunctions.hpp:840
CoinSwap
void CoinSwap(T &x, T &y)
Swap the arguments.
Definition: CoinHelperFunctions.hpp:990
CoinZeroN
void CoinZeroN(T *to, const CoinBigIndex size)
This helper function fills an array with zero.
Definition: CoinHelperFunctions.hpp:492
CoinCopyOfArrayPartial
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...
Definition: CoinHelperFunctions.hpp:231
CoinThreadRandom::randomize
void randomize(int n=0)
make more random (i.e. for startup)
Definition: CoinHelperFunctions.hpp:1137
CoinDisjointCopy
void CoinDisjointCopy(const T *first, const T *last, T *to)
This helper function copies an array to another location.
Definition: CoinHelperFunctions.hpp:200
COIN_RESTRICT
#define COIN_RESTRICT
Definition: CoinHelperFunctions.hpp:32
CoinFill
void CoinFill(T *first, T *last, const T value)
This helper function fills an array with a given value.
Definition: CoinHelperFunctions.hpp:477
CoinMax
T CoinMax(const T x1, const T x2)
Return the larger (according to operator&lt;() of the arguments.
Definition: CoinHelperFunctions.hpp:632
CoinZero
void CoinZero(T *first, T *last)
This helper function fills an array with a given value.
Definition: CoinHelperFunctions.hpp:605
CoinThreadRandom::CoinThreadRandom
CoinThreadRandom()
Default constructor.
Definition: CoinHelperFunctions.hpp:1088
CoinStrNCaseCmp
int CoinStrNCaseCmp(const char *s0, const char *s1, const size_t len)
Definition: CoinHelperFunctions.hpp:966
CoinAbs
T CoinAbs(const T value)
Return the absolute value of the argument.
Definition: CoinHelperFunctions.hpp:656
CoinFindDirSeparator
char CoinFindDirSeparator()
This function figures out whether file names should contain slashes or backslashes as directory separ...
Definition: CoinHelperFunctions.hpp:946
CoinMemcpy
void CoinMemcpy(const T *first, const T *last, T *to)
This helper function copies an array to another location.
Definition: CoinHelperFunctions.hpp:388
CoinThreadRandom::setSeed
void setSeed(int seed)
Set seed.
Definition: CoinHelperFunctions.hpp:1119
CoinStrlenAsInt
int CoinStrlenAsInt(const char *string)
This helper returns &quot;strlen&quot; as an int.
Definition: CoinHelperFunctions.hpp:1074
CoinBigIndex
int CoinBigIndex
Definition: Coin_C_defines.h:136
CoinMin
T CoinMin(const T x1, const T x2)
Return the smaller (according to operator&lt;() of the arguments.
Definition: CoinHelperFunctions.hpp:644
CoinThreadRandom::operator=
CoinThreadRandom & operator=(const CoinThreadRandom &rhs)
Definition: CoinHelperFunctions.hpp:1105
CoinThreadRandom::~CoinThreadRandom
~CoinThreadRandom()
Destructor.
Definition: CoinHelperFunctions.hpp:1098
CoinFromFile
int CoinFromFile(T *&array, CoinBigIndex size, FILE *fp, CoinBigIndex &newSize)
This helper function copies an array from file and creates with new.
Definition: CoinHelperFunctions.hpp:1034
CoinThreadRandom::randomDouble
double randomDouble() const
return a random number
Definition: CoinHelperFunctions.hpp:1129
CoinCopyN
void CoinCopyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location using Duff&#39;s device (for a speedup of ~2)...
Definition: CoinHelperFunctions.hpp:45
CoinCopyOfArray
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.
Definition: CoinHelperFunctions.hpp:214
CoinUtilsConfig.h
CoinThreadRandom::CoinThreadRandom
CoinThreadRandom(int seed)
Constructor wih seed.
Definition: CoinHelperFunctions.hpp:1093
CoinCopy
void CoinCopy(const T *first, const T *last, T *to)
This helper function copies an array to another location using Duff&#39;s device (for a speedup of ~2)...
Definition: CoinHelperFunctions.hpp:122
CoinThreadRandom
Class for thread specific random numbers.
Definition: CoinHelperFunctions.hpp:1082
CoinCheckIntZero
void CoinCheckIntZero(int *to, const CoinBigIndex size)
This Debug helper function checks an array is all zero.
Definition: CoinHelperFunctions.hpp:584