LTP GCOV extension - code coverage report
Current view: directory - include/coin - CoinHelperFunctions.hpp
Test: Acro
Date: 2008-10-21 Instrumented lines: 53
Code covered: 92.5 % Executed lines: 49

       1                 : // Copyright (C) 2000, International Business Machines
       2                 : // Corporation and others.  All Rights Reserved.
       3                 : 
       4                 : #ifndef CoinHelperFunctions_H
       5                 : #define CoinHelperFunctions_H
       6                 : #if defined(_MSC_VER)
       7                 : #  include <direct.h>
       8                 : #  define getcwd _getcwd
       9                 : #else
      10                 : #  include <unistd.h>
      11                 : #endif
      12                 : 
      13                 : #include <cstdio>
      14                 : #include "CoinError.hpp"
      15                 : #include "CoinFinite.hpp"
      16                 : //#############################################################################
      17                 : 
      18                 : /** This helper function copies an array to another location using Duff's
      19                 :     device (for a speedup of ~2). The arrays are given by pointers to their
      20                 :     first entries and by the size of the source array. Overlapping arrays are
      21                 :     handled correctly. */
      22                 : 
      23                 : template <class T> inline void
      24           78103 : CoinCopyN(register const T* from, const int size, register T* to)
      25                 : {
      26           78103 :     if (size == 0 || from == to)
      27               0 :         return;
      28                 : 
      29           78103 :     if (size < 0)
      30               0 :         throw CoinError("trying to copy negative number of entries",
      31                 :                         "CoinCopyN", "");
      32                 : 
      33           78103 :     register int n = (size + 7) / 8;
      34           78103 :     if (to > from) {
      35             402 :         register const T* downfrom = from + size;
      36             402 :         register T* downto = to + size;
      37                 :         // Use Duff's device to copy
      38             402 :         switch (size % 8) {
      39            9306 :         case 0: do{     *--downto = *--downfrom;
      40            4623 :         case 7:         *--downto = *--downfrom;
      41            4623 :         case 6:         *--downto = *--downfrom;
      42            4623 :         case 5:         *--downto = *--downfrom;
      43            4623 :         case 4:         *--downto = *--downfrom;
      44            4682 :         case 3:         *--downto = *--downfrom;
      45            4683 :         case 2:         *--downto = *--downfrom;
      46            4683 :         case 1:         *--downto = *--downfrom;
      47                 :         }while(--n>0);
      48                 :         }
      49                 :     } else {
      50                 :         // Use Duff's device to copy
      51           77701 :         --from;
      52           77701 :         --to;
      53           77701 :         switch (size % 8) {
      54          160163 :         case 0: do{     *++to = *++from;
      55           44630 :         case 7:         *++to = *++from;
      56           48375 :         case 6:         *++to = *++from;
      57           54099 :         case 5:         *++to = *++from;
      58           61201 :         case 4:         *++to = *++from;
      59           87726 :         case 3:         *++to = *++from;
      60          114720 :         case 2:         *++to = *++from;
      61          117652 :         case 1:         *++to = *++from;
      62                 :         }while(--n>0);
      63                 :         }
      64                 :     }
      65                 : }
      66                 : 
      67                 : //-----------------------------------------------------------------------------
      68                 : 
      69                 : /** This helper function copies an array to another location using Duff's
      70                 :     device (for a speedup of ~2). The source array is given by its first and
      71                 :     "after last" entry; the target array is given by its first entry.
      72                 :     Overlapping arrays are handled correctly. */
      73                 : template <class T> inline void
      74                 : CoinCopy(register const T* first, register const T* last, register T* to)
      75                 : {
      76                 :     CoinCopyN(first, last - first, to);
      77                 : }
      78                 : 
      79                 : //-----------------------------------------------------------------------------
      80                 : 
      81                 : /** This helper function copies an array to another location. The two arrays
      82                 :     must not overlap (otherwise an exception is thrown). For speed 8 entries
      83                 :     are copied at a time. The arrays are given by pointers to their first
      84                 :     entries and by the size of the source array. 
      85                 : 
      86                 :     Note JJF - the speed claim seems to be false on IA32 so I have added 
      87                 :     CoinMemcpyN which can be used for atomic data */
      88                 : template <class T> inline void
      89                 : CoinDisjointCopyN(register const T* from, const int size, register T* to)
      90                 : {
      91                 : #ifndef _MSC_VER
      92                 :     if (size == 0 || from == to)
      93                 :         return;
      94                 : 
      95                 :     if (size < 0)
      96                 :         throw CoinError("trying to copy negative number of entries",
      97                 :                         "CoinDisjointCopyN", "");
      98                 : 
      99                 : #if 0
     100                 :     /* There is no point to do this test. If to and from are from different
     101                 :        blocks then dist is undefined, so this can crash correct code. It's
     102                 :        better to trust the user that the arrays are really disjoint. */
     103                 :     const long dist = to - from;
     104                 :     if (-size < dist && dist < size)
     105                 :         throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
     106                 : #endif
     107                 : 
     108                 :     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
     109                 :         to[0] = from[0];
     110                 :         to[1] = from[1];
     111                 :         to[2] = from[2];
     112                 :         to[3] = from[3];
     113                 :         to[4] = from[4];
     114                 :         to[5] = from[5];
     115                 :         to[6] = from[6];
     116                 :         to[7] = from[7];
     117                 :     }
     118                 :     switch (size % 8) {
     119                 :     case 7: to[6] = from[6];
     120                 :     case 6: to[5] = from[5];
     121                 :     case 5: to[4] = from[4];
     122                 :     case 4: to[3] = from[3];
     123                 :     case 3: to[2] = from[2];
     124                 :     case 2: to[1] = from[1];
     125                 :     case 1: to[0] = from[0];
     126                 :     case 0: break;
     127                 :     }
     128                 : #else
     129                 :     CoinCopyN(from, size, to);
     130                 : #endif
     131                 : }
     132                 : 
     133                 : //-----------------------------------------------------------------------------
     134                 : 
     135                 : /** This helper function copies an array to another location. The two arrays
     136                 :     must not overlap (otherwise an exception is thrown). For speed 8 entries
     137                 :     are copied at a time. The source array is given by its first and "after
     138                 :     last" entry; the target array is given by its first entry. */
     139                 : template <class T> inline void
     140                 : CoinDisjointCopy(register const T* first, register const T* last,
     141                 :                  register T* to)
     142                 : {
     143                 :     CoinDisjointCopyN(first, static_cast<int>(last - first), to);
     144                 : }
     145                 : 
     146                 : //-----------------------------------------------------------------------------
     147                 : 
     148                 : /*! \brief Return an array of length \p size filled with input from \p array,
     149                 :   or null if \p array is null.
     150                 : */
     151                 : 
     152                 : template <class T> inline T*
     153                 : CoinCopyOfArray( const T * array, const int size)
     154                 : {
     155                 :     if (array) {
     156                 :         T * arrayNew = new T[size];
     157                 :         memcpy(arrayNew,array,size*sizeof(T));
     158                 :         return arrayNew;
     159                 :     } else {
     160                 :         return NULL;
     161                 :     }
     162                 : }
     163                 : 
     164                 : /*! \brief Return an array of length \p size filled with input from \p array,
     165                 :   or filled with (scalar) \p value if \p array is null
     166                 : */
     167                 : 
     168                 : template <class T> inline T*
     169                 : CoinCopyOfArray( const T * array, const int size, T value)
     170                 : {
     171                 :     T * arrayNew = new T[size];
     172                 :     if (array) {
     173                 :         memcpy(arrayNew,array,size*sizeof(T));
     174                 :     } else {
     175                 :         int i;
     176                 :         for (i=0;i<size;i++) 
     177                 :             arrayNew[i] = value;
     178                 :     }
     179                 :     return arrayNew;
     180                 : }
     181                 : 
     182                 : 
     183                 : /*! \brief Return an array of length \p size filled with input from \p array,
     184                 :   or filled with zero if \p array is null
     185                 : */
     186                 : 
     187                 : template <class T> inline T*
     188                 : CoinCopyOfArrayOrZero( const T * array , const int size)
     189                 : {
     190                 :     T * arrayNew = new T[size];
     191                 :     if (array) {
     192                 :         memcpy(arrayNew,array,size*sizeof(T));
     193                 :     } else {
     194                 :         memset(arrayNew,0,size*sizeof(T));
     195                 :     }
     196                 :     return arrayNew;
     197                 : }
     198                 : 
     199                 : 
     200                 : //-----------------------------------------------------------------------------
     201                 : 
     202                 : /** This helper function copies an array to another location. The two arrays
     203                 :     must not overlap (otherwise an exception is thrown). For speed 8 entries
     204                 :     are copied at a time. The arrays are given by pointers to their first
     205                 :     entries and by the size of the source array. 
     206                 : 
     207                 :     Note JJF - the speed claim seems to be false on IA32 so I have added 
     208                 :     alternative coding if USE_MEMCPY defined*/
     209                 : template <class T> inline void
     210                 : CoinMemcpyN(register const T* from, const int size, register T* to)
     211                 : {
     212                 : #ifndef _MSC_VER
     213                 : #ifdef USE_MEMCPY
     214                 :     // Use memcpy - seems a lot faster on Intel with gcc
     215                 : #ifndef NDEBUG
     216                 :     // Some debug so check
     217                 :     if (size < 0)
     218                 :         throw CoinError("trying to copy negative number of entries",
     219                 :                         "CoinMemcpyN", "");
     220                 :   
     221                 : #if 0
     222                 :     /* There is no point to do this test. If to and from are from different
     223                 :        blocks then dist is undefined, so this can crash correct code. It's
     224                 :        better to trust the user that the arrays are really disjoint. */
     225                 :     const long dist = to - from;
     226                 :     if (-size < dist && dist < size)
     227                 :         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
     228                 : #endif
     229                 : #endif
     230                 :     memcpy(to,from,size*sizeof(T));
     231                 : #else
     232                 :     if (size == 0 || from == to)
     233                 :         return;
     234                 : 
     235                 :     if (size < 0)
     236                 :         throw CoinError("trying to copy negative number of entries",
     237                 :                         "CoinMemcpyN", "");
     238                 : 
     239                 : #if 0
     240                 :     /* There is no point to do this test. If to and from are from different
     241                 :        blocks then dist is undefined, so this can crash correct code. It's
     242                 :        better to trust the user that the arrays are really disjoint. */
     243                 :     const long dist = to - from;
     244                 :     if (-size < dist && dist < size)
     245                 :         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
     246                 : #endif
     247                 : 
     248                 :     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
     249                 :         to[0] = from[0];
     250                 :         to[1] = from[1];
     251                 :         to[2] = from[2];
     252                 :         to[3] = from[3];
     253                 :         to[4] = from[4];
     254                 :         to[5] = from[5];
     255                 :         to[6] = from[6];
     256                 :         to[7] = from[7];
     257                 :     }
     258                 :     switch (size % 8) {
     259                 :     case 7: to[6] = from[6];
     260                 :     case 6: to[5] = from[5];
     261                 :     case 5: to[4] = from[4];
     262                 :     case 4: to[3] = from[3];
     263                 :     case 3: to[2] = from[2];
     264                 :     case 2: to[1] = from[1];
     265                 :     case 1: to[0] = from[0];
     266                 :     case 0: break;
     267                 :     }
     268                 : #endif
     269                 : #else
     270                 :     CoinCopyN(from, size, to);
     271                 : #endif
     272                 : }
     273                 : 
     274                 : //-----------------------------------------------------------------------------
     275                 : 
     276                 : /** This helper function copies an array to another location. The two arrays
     277                 :     must not overlap (otherwise an exception is thrown). For speed 8 entries
     278                 :     are copied at a time. The source array is given by its first and "after
     279                 :     last" entry; the target array is given by its first entry. */
     280                 : template <class T> inline void
     281                 : CoinMemcpy(register const T* first, register const T* last,
     282                 :            register T* to)
     283                 : {
     284                 :     CoinMemcpyN(first, static_cast<int>(last - first), to);
     285                 : }
     286                 : 
     287                 : //#############################################################################
     288                 : 
     289                 : /** This helper function fills an array with a given value. For speed 8 entries
     290                 :     are filled at a time. The array is given by a pointer to its first entry
     291                 :     and its size. 
     292                 : 
     293                 :     Note JJF - the speed claim seems to be false on IA32 so I have added 
     294                 :     CoinZero to allow for memset. */
     295                 : template <class T> inline void
     296             709 : CoinFillN(register T* to, const int size, register const T value)
     297                 : {
     298             709 :     if (size == 0)
     299               0 :         return;
     300                 : 
     301             709 :     if (size < 0)
     302               0 :         throw CoinError("trying to fill negative number of entries",
     303                 :                         "CoinFillN", "");
     304                 : 
     305                 : #if 1
     306            8977 :     for (register int n = size / 8; n > 0; --n, to += 8) {
     307            8268 :         to[0] = value;
     308            8268 :         to[1] = value;
     309            8268 :         to[2] = value;
     310            8268 :         to[3] = value;
     311            8268 :         to[4] = value;
     312            8268 :         to[5] = value;
     313            8268 :         to[6] = value;
     314            8268 :         to[7] = value;
     315                 :     }
     316             709 :     switch (size % 8) {
     317             171 :     case 7: to[6] = value;
     318             259 :     case 6: to[5] = value;
     319             337 :     case 5: to[4] = value;
     320             378 :     case 4: to[3] = value;
     321             421 :     case 3: to[2] = value;
     322             463 :     case 2: to[1] = value;
     323             548 :     case 1: to[0] = value;
     324                 :     case 0: break;
     325                 :     }
     326                 : #else
     327                 :     // Use Duff's device to fill
     328                 :     register int n = (size + 7) / 8;
     329                 :     --to;
     330                 :     switch (size % 8) {
     331                 :     case 0: do{     *++to = value;
     332                 :     case 7:         *++to = value;
     333                 :     case 6:         *++to = value;
     334                 :     case 5:         *++to = value;
     335                 :     case 4:         *++to = value;
     336                 :     case 3:         *++to = value;
     337                 :     case 2:         *++to = value;
     338                 :     case 1:         *++to = value;
     339                 :     }while(--n>0);
     340                 :     }
     341                 : #endif
     342                 : }
     343                 : 
     344                 : //-----------------------------------------------------------------------------
     345                 : 
     346                 : /** This helper function fills an array with a given value. For speed 8
     347                 :     entries are filled at a time. The array is given by its first and "after
     348                 :     last" entry. */
     349                 : template <class T> inline void
     350                 : CoinFill(register T* first, register T* last, const T value)
     351                 : {
     352                 :     CoinFillN(first, last - first, value);
     353                 : }
     354                 : 
     355                 : //#############################################################################
     356                 : 
     357                 : /** This helper function fills an array with zero. For speed 8 entries
     358                 :     are filled at a time. The array is given by a pointer to its first entry
     359                 :     and its size.
     360                 : 
     361                 :     Note JJF - the speed claim seems to be false on IA32 so I have allowed 
     362                 :     for memset as an alternative */
     363                 : template <class T> inline void
     364                 : CoinZeroN(register T* to, const int size)
     365                 : {
     366                 : #ifdef USE_MEMCPY
     367                 :     // Use memset - seems faster on Intel with gcc
     368                 : #ifndef NDEBUG
     369                 :     // Some debug so check
     370                 :     if (size < 0)
     371                 :         throw CoinError("trying to fill negative number of entries",
     372                 :                         "CoinZeroN", "");
     373                 : #endif
     374                 :     memset(to,0,size*sizeof(T));
     375                 : #else
     376                 :     if (size == 0)
     377                 :         return;
     378                 : 
     379                 :     if (size < 0)
     380                 :         throw CoinError("trying to fill negative number of entries",
     381                 :                         "CoinZeroN", "");
     382                 : #if 1
     383                 :     for (register int n = size / 8; n > 0; --n, to += 8) {
     384                 :         to[0] = 0;
     385                 :         to[1] = 0;
     386                 :         to[2] = 0;
     387                 :         to[3] = 0;
     388                 :         to[4] = 0;
     389                 :         to[5] = 0;
     390                 :         to[6] = 0;
     391                 :         to[7] = 0;
     392                 :     }
     393                 :     switch (size % 8) {
     394                 :     case 7: to[6] = 0;
     395                 :     case 6: to[5] = 0;
     396                 :     case 5: to[4] = 0;
     397                 :     case 4: to[3] = 0;
     398                 :     case 3: to[2] = 0;
     399                 :     case 2: to[1] = 0;
     400                 :     case 1: to[0] = 0;
     401                 :     case 0: break;
     402                 :     }
     403                 : #else
     404                 :     // Use Duff's device to fill
     405                 :     register int n = (size + 7) / 8;
     406                 :     --to;
     407                 :     switch (size % 8) {
     408                 :     case 0: do{     *++to = 0;
     409                 :     case 7:         *++to = 0;
     410                 :     case 6:         *++to = 0;
     411                 :     case 5:         *++to = 0;
     412                 :     case 4:         *++to = 0;
     413                 :     case 3:         *++to = 0;
     414                 :     case 2:         *++to = 0;
     415                 :     case 1:         *++to = 0;
     416                 :     }while(--n>0);
     417                 :     }
     418                 : #endif
     419                 : #endif
     420                 : }
     421                 : /// This Debug helper function checks an array is all zero
     422                 : inline void
     423                 : CoinCheckDoubleZero(double * to, const int size)
     424                 : {
     425                 :     int n=0;
     426                 :     for (int j=0;j<size;j++) {
     427                 :         if (to[j]) 
     428                 :             n++;
     429                 :     }
     430                 :     if (n) {
     431                 :         printf("array of length %d should be zero has %d nonzero\n",size,n);
     432                 :     }
     433                 : }
     434                 : /// This Debug helper function checks an array is all zero
     435                 : inline void
     436                 : CoinCheckIntZero(int * to, const int size)
     437                 : {
     438                 :     int n=0;
     439                 :     for (int j=0;j<size;j++) {
     440                 :         if (to[j]) 
     441                 :             n++;
     442                 :     }
     443                 :     if (n) {
     444                 :         printf("array of length %d should be zero has %d nonzero\n",size,n);
     445                 :     }
     446                 : }
     447                 : 
     448                 : //-----------------------------------------------------------------------------
     449                 : 
     450                 : /** This helper function fills an array with a given value. For speed 8
     451                 :     entries are filled at a time. The array is given by its first and "after
     452                 :     last" entry. */
     453                 : template <class T> inline void
     454                 : CoinZero(register T* first, register T* last)
     455                 : {
     456                 :     CoinZeroN(first, last - first);
     457                 : }
     458                 : 
     459                 : //#############################################################################
     460                 : 
     461                 : /** Return the larger (according to <code>operator<()</code> of the arguments.
     462                 :     This function was introduced because for some reason compiler tend to
     463                 :     handle the <code>max()</code> function differently. */
     464                 : template <class T> inline T
     465        68976708 : CoinMax(register const T x1, register const T x2)
     466                 : {
     467        68976708 :     return (x1 > x2) ? x1 : x2;
     468                 : }
     469                 : 
     470                 : //-----------------------------------------------------------------------------
     471                 : 
     472                 : /** Return the smaller (according to <code>operator<()</code> of the arguments.
     473                 :     This function was introduced because for some reason compiler tend to
     474                 :     handle the min() function differently. */
     475                 : template <class T> inline T
     476                 : CoinMin(register const T x1, register const T x2)
     477                 : {
     478                 :     return (x1 < x2) ? x1 : x2;
     479                 : }
     480                 : 
     481                 : //-----------------------------------------------------------------------------
     482                 : 
     483                 : /** Return the absolute value of the argument. This function was introduced
     484                 :     because for some reason compiler tend to handle the abs() function
     485                 :     differently. */
     486                 : template <class T> inline T
     487                 : CoinAbs(const T value)
     488                 : {
     489                 :     return value<0 ? -value : value;
     490                 : }
     491                 : 
     492                 : //#############################################################################
     493                 : 
     494                 : /** This helper function tests whether the entries of an array are sorted
     495                 :     according to operator<. The array is given by a pointer to its first entry
     496                 :     and by its size. */
     497                 : template <class T> inline bool
     498                 : CoinIsSorted(register const T* first, const int size)
     499                 : {
     500                 :     if (size == 0)
     501                 :         return true;
     502                 : 
     503                 :     if (size < 0)
     504                 :         throw CoinError("negative number of entries", "CoinIsSorted", "");
     505                 : 
     506                 : #if 1
     507                 :     // size1 is the number of comparisons to be made
     508                 :     const int size1 = size  - 1;
     509                 :     for (register int n = size1 / 8; n > 0; --n, first += 8) {
     510                 :         if (first[8] < first[7]) return false;
     511                 :         if (first[7] < first[6]) return false;
     512                 :         if (first[6] < first[5]) return false;
     513                 :         if (first[5] < first[4]) return false;
     514                 :         if (first[4] < first[3]) return false;
     515                 :         if (first[3] < first[2]) return false;
     516                 :         if (first[2] < first[1]) return false;
     517                 :         if (first[1] < first[0]) return false;
     518                 :     }
     519                 : 
     520                 :     switch (size1 % 8) {
     521                 :     case 7: if (first[7] < first[6]) return false;
     522                 :     case 6: if (first[6] < first[5]) return false;
     523                 :     case 5: if (first[5] < first[4]) return false;
     524                 :     case 4: if (first[4] < first[3]) return false;
     525                 :     case 3: if (first[3] < first[2]) return false;
     526                 :     case 2: if (first[2] < first[1]) return false;
     527                 :     case 1: if (first[1] < first[0]) return false;
     528                 :     case 0: break;
     529                 :     }
     530                 : #else
     531                 :     register const T* next = first;
     532                 :     register const T* last = first + size;
     533                 :     for (++next; next != last; first = next, ++next)
     534                 :         if (*next < *first)
     535                 :             return false;
     536                 : #endif   
     537                 :     return true;
     538                 : }
     539                 : 
     540                 : //-----------------------------------------------------------------------------
     541                 : 
     542                 : /** This helper function tests whether the entries of an array are sorted
     543                 :     according to operator<. The array is given by its first and "after
     544                 :     last" entry. */
     545                 : template <class T> inline bool
     546                 : CoinIsSorted(register const T* first, register const T* last)
     547                 : {
     548                 :     return CoinIsSorted(first, static_cast<int>(last - first));
     549                 : }
     550                 : 
     551                 : //#############################################################################
     552                 : 
     553                 : /** This helper function fills an array with the values init, init+1, init+2,
     554                 :     etc. For speed 8 entries are filled at a time. The array is given by a
     555                 :     pointer to its first entry and its size. */
     556                 : template <class T> inline void
     557                 : CoinIotaN(register T* first, const int size, register T init)
     558                 : {
     559                 :     if (size == 0)
     560                 :         return;
     561                 : 
     562                 :     if (size < 0)
     563                 :         throw CoinError("negative number of entries", "CoinIotaN", "");
     564                 : 
     565                 : #if 1
     566                 :     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
     567                 :         first[0] = init;
     568                 :         first[1] = init + 1;
     569                 :         first[2] = init + 2;
     570                 :         first[3] = init + 3;
     571                 :         first[4] = init + 4;
     572                 :         first[5] = init + 5;
     573                 :         first[6] = init + 6;
     574                 :         first[7] = init + 7;
     575                 :     }
     576                 :     switch (size % 8) {
     577                 :     case 7: first[6] = init + 6;
     578                 :     case 6: first[5] = init + 5;
     579                 :     case 5: first[4] = init + 4;
     580                 :     case 4: first[3] = init + 3;
     581                 :     case 3: first[2] = init + 2;
     582                 :     case 2: first[1] = init + 1;
     583                 :     case 1: first[0] = init;
     584                 :     case 0: break;
     585                 :     }
     586                 : #else
     587                 :     // Use Duff's device to fill
     588                 :     register int n = (size + 7) / 8;
     589                 :     --first;
     590                 :     --init;
     591                 :     switch (size % 8) {
     592                 :     case 0: do{     *++first = ++init;
     593                 :     case 7:         *++first = ++init;
     594                 :     case 6:         *++first = ++init;
     595                 :     case 5:         *++first = ++init;
     596                 :     case 4:         *++first = ++init;
     597                 :     case 3:         *++first = ++init;
     598                 :     case 2:         *++first = ++init;
     599                 :     case 1:         *++first = ++init;
     600                 :     }while(--n>0);
     601                 :     }
     602                 : #endif
     603                 : }
     604                 : 
     605                 : //-----------------------------------------------------------------------------
     606                 : 
     607                 : /** This helper function fills an array with the values init, init+1, init+2,
     608                 :     etc. For speed 8 entries are filled at a time. The array is given by its
     609                 :     first and "after last" entry. */
     610                 : template <class T> inline void
     611                 : CoinIota(T* first, const T* last, T init)
     612                 : {
     613                 :     CoinIotaN(first, last-first, init);
     614                 : }
     615                 : 
     616                 : //#############################################################################
     617                 : 
     618                 : /** This helper function deletes certain entries from an array. The array is
     619                 :     given by pointers to its first and "after last" entry (first two
     620                 :     arguments). The positions of the entries to be deleted are given in the
     621                 :     integer array specified by the last two arguments (again, first and "after
     622                 :     last" entry). */
     623                 : template <class T> inline T *
     624                 : CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
     625                 :                            const int * firstDelPos, const int * lastDelPos)
     626                 : {
     627                 :     int delNum = lastDelPos - firstDelPos;
     628                 :     if (delNum == 0)
     629                 :         return arrayLast;
     630                 : 
     631                 :     if (delNum < 0)
     632                 :         throw CoinError("trying to delete negative number of entries",
     633                 :                         "CoinDeleteEntriesFromArray", "");
     634                 : 
     635                 :     int * delSortedPos = NULL;
     636                 :     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
     637                 :            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
     638                 :         // the positions of the to be deleted is either not sorted or not unique
     639                 :         delSortedPos = new int[delNum];
     640                 :         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
     641                 :         std::sort(delSortedPos, delSortedPos + delNum);
     642                 :         delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
     643                 :     }
     644                 :     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
     645                 : 
     646                 :     const int last = delNum - 1;
     647                 :     int size = delSorted[0];
     648                 :     for (int i = 0; i < last; ++i) {
     649                 :         const int copyFirst = delSorted[i] + 1;
     650                 :         const int copyLast = delSorted[i+1];
     651                 :         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
     652                 :                  arrayFirst + size);
     653                 :         size += copyLast - copyFirst;
     654                 :     }
     655                 :     const int copyFirst = delSorted[last] + 1;
     656                 :     const int copyLast = arrayLast - arrayFirst;
     657                 :     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
     658                 :              arrayFirst + size);
     659                 :     size += copyLast - copyFirst;
     660                 : 
     661                 :     if (delSortedPos)
     662                 :         delete[] delSortedPos;
     663                 : 
     664                 :     return arrayFirst + size;
     665                 : }
     666                 : 
     667                 : //#############################################################################
     668                 : /* Thanks to Stefano Gliozzi for providing an operating system
     669                 :    independent random number generator.  */
     670                 : /// Seed random number generator
     671                 : inline void CoinSeedRandom(int iseed)
     672                 : {
     673                 : #if defined COIN_OWN_RANDOM_32
     674                 :   double CoinDrand48(bool isSeed = false, unsigned long seed=1);
     675                 :   CoinDrand48(true, iseed);
     676                 : #else
     677                 :   int jseed;
     678                 :   jseed = iseed + 69822;
     679                 : #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
     680                 :   srand(jseed);
     681                 : #else
     682                 :   srand48(jseed);
     683                 : #endif
     684                 : #endif // end else COIN_OWN_RANDOM
     685                 : }
     686                 : 
     687                 : /// Return random number between 0 and 1.
     688                 : #if defined COIN_OWN_RANDOM_32
     689                 : // linear congruential generator. given the seed, the generated numbers are  
     690                 : // always the same regardless the (32 bit) architecture. This allows to 
     691                 : // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
     692                 : // getting in most cases the same optimization path. 
     693                 : inline double CoinDrand48(bool isSeed = false, unsigned long seed=1)
     694                 : {
     695                 :   static unsigned last;
     696                 :   if (isSeed) { 
     697                 :     last = seed;
     698                 :   } else {
     699                 :     last = 1664525*last+1013904223;
     700                 :     return (((double) last)/4294967296.0);
     701                 :   }
     702                 :   return(0.0);
     703                 : }
     704                 : #else 
     705                 : inline double CoinDrand48()
     706                 : {  
     707                 :   double retVal;
     708                 : #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
     709                 :   retVal=rand();
     710                 :   retVal=retVal/(double) RAND_MAX;
     711                 : #else
     712                 :   retVal = drand48();
     713                 : #endif
     714                 :   return retVal;
     715                 : }
     716                 : #endif
     717                 : 
     718                 : //#############################################################################
     719                 : 
     720                 : /** This function figures out whether file names should contain slashes or 
     721                 :     backslashes as directory separator */
     722                 : inline char CoinFindDirSeparator()
     723                 : {
     724                 :     int size = 1000;
     725                 :     char* buf = 0;
     726                 :     while (true) {
     727                 :         buf = new char[size];
     728                 :         if (getcwd(buf, size))
     729                 :             break;
     730                 :         delete[] buf;
     731                 :         buf = 0;
     732                 :         size = 2*size;
     733                 :     }
     734                 :     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we 
     735                 :     // assume it's dos and the dirsep is '\'
     736                 :     char dirsep = buf[0] == '/' ? '/' : '\\';
     737                 :     delete[] buf;
     738                 :     return dirsep;
     739                 : }
     740                 : //#############################################################################
     741                 : 
     742                 : inline int CoinStrNCaseCmp(const char* s0, const char* s1,
     743                 :                            const size_t len)
     744                 : {
     745                 :     for (size_t i = 0; i < len; ++i) {
     746                 :         if (s0[i] == 0) {
     747                 :             return s1[i] == 0 ? 0 : -1;
     748                 :         }
     749                 :         if (s1[i] == 0) {
     750                 :             return 1;
     751                 :         }
     752                 :         const int c0 = tolower(s0[i]);
     753                 :         const int c1 = tolower(s1[i]);
     754                 :         if (c0 < c1)
     755                 :             return -1;
     756                 :         if (c0 > c1)
     757                 :             return 1;
     758                 :     }
     759                 :     return 0;
     760                 : }
     761                 : 
     762                 : //#############################################################################
     763                 : 
     764                 : /// Swap the arguments.
     765                 : template <class T> inline void CoinSwap (T &x, T &y)
     766                 : {
     767                 :     T t = x;
     768                 :     x = y;
     769                 :     y = t;
     770                 : }
     771                 : 
     772                 : //#############################################################################
     773                 : 
     774                 : /** This helper function copies an array to file 
     775                 :     Returns 0 if OK, 1 if bad write.
     776                 : */
     777                 : 
     778                 : template <class T> inline int
     779                 : CoinToFile( const T* array, int size, FILE * fp)
     780                 : {
     781                 :     int numberWritten;
     782                 :     if (array&&size) {
     783                 :         numberWritten = fwrite(&size,sizeof(int),1,fp);
     784                 :         if (numberWritten!=1)
     785                 :             return 1;
     786                 :         numberWritten = fwrite(array,sizeof(T),size,fp);
     787                 :         if (numberWritten!=size)
     788                 :             return 1;
     789                 :     } else {
     790                 :         size = 0;
     791                 :         numberWritten = fwrite(&size,sizeof(int),1,fp);
     792                 :         if (numberWritten!=1)
     793                 :             return 1;
     794                 :     }
     795                 :     return 0;
     796                 : }
     797                 : 
     798                 : //#############################################################################
     799                 : 
     800                 : /** This helper function copies an array from file and creates with new.
     801                 :     Passed in array is ignored i.e. not deleted.
     802                 :     But if NULL and size does not match and newSize 0 then leaves as NULL and 0
     803                 :     Returns 0 if OK, 1 if bad read, 2 if size did not match.
     804                 : */
     805                 : 
     806                 : template <class T> inline int
     807                 : CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
     808                 : {
     809                 :     int numberRead;
     810                 :     numberRead = fread(&newSize,sizeof(int),1,fp);
     811                 :     if (numberRead!=1)
     812                 :         return 1;
     813                 :     int returnCode=0;
     814                 :     if (size!=newSize&&(newSize||array))
     815                 :         returnCode=2;
     816                 :     if (newSize) {
     817                 :         array = new T [newSize];
     818                 :         numberRead = fread(array,sizeof(T),newSize,fp);
     819                 :         if (numberRead!=newSize)
     820                 :             returnCode=1;
     821                 :     } else {
     822                 :         array = NULL;
     823                 :     }
     824                 :     return returnCode;
     825                 : }
     826                 : 
     827                 : //#############################################################################
     828                 : 
     829                 : /// Cube Root
     830                 : inline double CoinCbrt(double x)
     831                 : {
     832                 : #if defined(_MSC_VER) 
     833                 :     return pow(x,(1./3.));
     834                 : #else
     835                 :     return cbrt(x);
     836                 : #endif
     837                 : }
     838                 : 
     839                 : #endif

Generated by: LTP GCOV extension version 1.4