Cgl  0.60.3
 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 2213 2019-12-19 08:44:16Z stefan $ */
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 = 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
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  // 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 
482 template < class T >
483 inline void
484 CoinFill(T *first, T *last, const T value)
485 {
486  CoinFillN(first, last - first, value);
487 }
488 
489 //#############################################################################
490 
497 template < class T >
498 inline void
499 CoinZeroN(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 }
576 inline void
577 CoinCheckDoubleZero(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 }
590 inline void
591 CoinCheckIntZero(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 
610 template < class T >
611 inline void
612 CoinZero(T *first, T *last)
613 {
614  CoinZeroN(first, last - first);
615 }
616 
617 //#############################################################################
618 
620 inline 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 
637 template < class T >
638 inline T
639 CoinMax(const T x1, const T x2)
640 {
641  return (x1 > x2) ? x1 : x2;
642 }
643 
644 //-----------------------------------------------------------------------------
645 
649 template < class T >
650 inline T
651 CoinMin(const T x1, const T x2)
652 {
653  return (x1 < x2) ? x1 : x2;
654 }
655 
656 //-----------------------------------------------------------------------------
657 
661 template < class T >
662 inline T
663 CoinAbs(const T value)
664 {
665  return value < 0 ? -value : value;
666 }
667 
668 //#############################################################################
669 
673 template < class T >
674 inline bool
675 CoinIsSorted(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 
746 template < class T >
747 inline bool
748 CoinIsSorted(const T *first, const T *last)
749 {
750  return CoinIsSorted(first, static_cast< CoinBigIndex >(last - first));
751 }
752 
753 //#############################################################################
754 
758 template < class T >
759 inline void
760 CoinIotaN(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 
831 template < class T >
832 inline void
833 CoinIota(T *first, const T *last, T init)
834 {
835  CoinIotaN(first, last - first, init);
836 }
837 
838 //#############################################################################
839 
845 template < class T >
846 inline T *
847 CoinDeleteEntriesFromArray(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 
911 inline 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 
924 inline 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 
934 inline double CoinDrand48() { return rand() / (double)RAND_MAX; }
936 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
937 
938 #else
939 
941 inline double CoinDrand48() { return drand48(); }
943 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
944 
945 #endif
946 
947 #endif // COIN_OWN_RANDOM_32
948 
949 //#############################################################################
950 
953 inline char CoinFindDirSeparator()
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 
973 inline 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 
996 template < class T >
997 inline void CoinSwap(T &x, T &y)
998 {
999  T t = x;
1000  x = y;
1001  y = t;
1002 }
1003 
1004 //#############################################################################
1005 
1010 template < class T >
1011 inline int
1012 CoinToFile(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 
1039 template < class T >
1040 inline int
1041 CoinFromFile(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
1065 inline 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)))
1079 inline int
1081 CoinStrlenAsInt(const char *string)
1082 {
1083  return static_cast< int >(strlen(string));
1084 }
1085 
1088 #if defined COIN_OWN_RANDOM_32
1090 public:
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 
1153 protected:
1157  mutable unsigned int seed_;
1160 };
1161 #else
1162 class CoinThreadRandom {
1163 public:
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  }
1191  ~CoinThreadRandom() {}
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 
1251 protected:
1255  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 */
Error Class thrown by an exception.
Definition: CoinError.hpp:42
CoinThreadRandom(const CoinThreadRandom &rhs)
void CoinDisjointCopyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location.
unsigned int getSeed() const
Get seed.
void CoinSeedRandom(int iseed)
Set the seed for the random number generator.
void CoinIota(T *first, const T *last, T init)
This helper function fills an array with the values init, init+1, init+2, etc.
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.
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...
double CoinDrand48(bool isSeed=false, unsigned int seed=1)
Return a random number between 0 and 1.
unsigned int seed_
Current seed.
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 CoinMemcpyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location.
void CoinCheckDoubleZero(double *to, const CoinBigIndex size)
This Debug helper function checks an array is all zero.
void CoinFillN(T *to, const CoinBigIndex size, const T value)
This helper function fills an array with a given value.
char * CoinStrdup(const char *name)
Returns strdup or NULL if original NULL.
bool CoinIsSorted(const T *first, const CoinBigIndex size)
This helper function tests whether the entries of an array are sorted according to operator&lt;...
T * CoinDeleteEntriesFromArray(T *arrayFirst, T *arrayLast, const int *firstDelPos, const int *lastDelPos)
This helper function deletes certain entries from an array.
void CoinSwap(T &x, T &y)
Swap the arguments.
void CoinZeroN(T *to, const CoinBigIndex size)
This helper function fills an array with zero.
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 randomize(int n=0)
make more random (i.e. for startup)
void CoinDisjointCopy(const T *first, const T *last, T *to)
This helper function copies an array to another location.
#define COIN_RESTRICT
void CoinFill(T *first, T *last, const T value)
This helper function fills an array with a given value.
T CoinMax(const T x1, const T x2)
Return the larger (according to operator&lt;() of the arguments.
void CoinZero(T *first, T *last)
This helper function fills an array with a given value.
CoinThreadRandom()
Default constructor.
int CoinStrNCaseCmp(const char *s0, const char *s1, const size_t len)
T CoinAbs(const T value)
Return the absolute value of the argument.
char CoinFindDirSeparator()
This function figures out whether file names should contain slashes or backslashes as directory separ...
void CoinMemcpy(const T *first, const T *last, T *to)
This helper function copies an array to another location.
void setSeed(int seed)
Set seed.
int CoinStrlenAsInt(const char *string)
This helper returns &quot;strlen&quot; as an int.
int CoinBigIndex
T CoinMin(const T x1, const T x2)
Return the smaller (according to operator&lt;() of the arguments.
CoinThreadRandom & operator=(const CoinThreadRandom &rhs)
~CoinThreadRandom()
Destructor.
int CoinFromFile(T *&array, CoinBigIndex size, FILE *fp, CoinBigIndex &newSize)
This helper function copies an array from file and creates with new.
double randomDouble() const
return a random number
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)...
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.
CoinThreadRandom(int seed)
Constructor wih seed.
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)...
Class for thread specific random numbers.
void CoinCheckIntZero(int *to, const CoinBigIndex size)
This Debug helper function checks an array is all zero.