coin-Bcp
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
1083 public:
1089  {
1090  seed_ = 12345678;
1091  }
1094  {
1095  seed_ = seed;
1096  }
1099  // Copy
1101  {
1102  seed_ = rhs.seed_;
1103  }
1104  // Assignment
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:
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
1187  {
1188  memcpy(seed_, rhs.seed_, 3 * sizeof(unsigned short));
1189  }
1190  // Assignment
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 */
double randomDouble() const
return a random number
int CoinBigIndex
void CoinSwap(T &x, T &y)
Swap the arguments.
bool CoinIsSorted(const T *first, const CoinBigIndex size)
This helper function tests whether the entries of an array are sorted according to operator&lt;...
void CoinMemcpyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location.
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)...
char * CoinStrdup(const char *name)
Returns strdup or NULL if original NULL.
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...
T * CoinDeleteEntriesFromArray(T *arrayFirst, T *arrayLast, const int *firstDelPos, const int *lastDelPos)
This helper function deletes certain entries from an array.
void CoinCheckDoubleZero(double *to, const CoinBigIndex size)
This Debug helper function checks an array is all zero.
CoinThreadRandom()
Default constructor.
void CoinIota(T *first, const T *last, T init)
This helper function fills an array with the values init, init+1, init+2, etc.
T CoinMin(const T x1, const T x2)
Return the smaller (according to operator&lt;() of the arguments.
void setSeed(int seed)
Set seed.
T CoinAbs(const T value)
Return the absolute value of the argument.
unsigned int getSeed() const
Get seed.
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)...
char CoinFindDirSeparator()
This function figures out whether file names should contain slashes or backslashes as directory separ...
~CoinThreadRandom()
Destructor.
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.
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...
unsigned int seed_
Current seed.
void CoinZero(T *first, T *last)
This helper function fills an array with a given value.
#define COIN_RESTRICT
T CoinMax(const T x1, const T x2)
Return the larger (according to operator&lt;() of the arguments.
void CoinSeedRandom(int iseed)
Set the seed for the random number generator.
int CoinFromFile(T *&array, CoinBigIndex size, FILE *fp, CoinBigIndex &newSize)
This helper function copies an array from file and creates with new.
int CoinStrNCaseCmp(const char *s0, const char *s1, const size_t len)
void randomize(int n=0)
make more random (i.e. for startup)
void CoinFillN(T *to, const CoinBigIndex size, const T value)
This helper function fills an array with a given value.
CoinThreadRandom(int seed)
Constructor wih seed.
Error Class thrown by an exception.
Definition: CoinError.hpp:42
void CoinCheckIntZero(int *to, const CoinBigIndex size)
This Debug helper function checks an array is all zero.
Class for thread specific random numbers.
int CoinStrlenAsInt(const char *string)
This helper returns &quot;strlen&quot; as an int.
void CoinZeroN(T *to, const CoinBigIndex size)
This helper function fills an array with zero.
CoinThreadRandom(const CoinThreadRandom &rhs)
Default constructor.
void CoinDisjointCopy(const T *first, const T *last, T *to)
This helper function copies an array to another location.
void CoinDisjointCopyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location.
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 CoinFill(T *first, T *last, const T value)
This helper function fills an array with a given value.
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.
double CoinDrand48(bool isSeed=false, unsigned int seed=1)
Return a random number between 0 and 1.
void CoinMemcpy(const T *first, const T *last, T *to)
This helper function copies an array to another location.
CoinThreadRandom & operator=(const CoinThreadRandom &rhs)
Default constructor.