LCOV - code coverage report
Current view: top level - src - MeshSet.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 555 586 94.7 %
Date: 2020-12-16 07:07:30 Functions: 32 33 97.0 %
Branches: 754 1090 69.2 %

           Branch data     Line data    Source code
       1                 :            : #ifdef WIN32
       2                 :            : #ifdef _DEBUG
       3                 :            : // turn off warnings that say they debugging identifier has been truncated
       4                 :            : // this warning comes up when using some STL containers
       5                 :            : #pragma warning( disable : 4786 )
       6                 :            : #endif
       7                 :            : #endif
       8                 :            : 
       9                 :            : #include "MeshSet.hpp"
      10                 :            : #include "AEntityFactory.hpp"
      11                 :            : 
      12                 :            : namespace moab
      13                 :            : {
      14                 :            : 
      15                 :            : /*****************************************************************************************
      16                 :            :  *                          Helper Function Declarations                                 *
      17                 :            :  *****************************************************************************************/
      18                 :            : 
      19                 :            : /**\brief Insert into parent/child list */
      20                 :            : static inline MeshSet::Count insert_in_vector( const MeshSet::Count count, MeshSet::CompactList& list,
      21                 :            :                                                const EntityHandle h, int& result );
      22                 :            : 
      23                 :            : /**\brief Remvoe from parent/child list */
      24                 :            : static inline MeshSet::Count remove_from_vector( const MeshSet::Count count, MeshSet::CompactList& list,
      25                 :            :                                                  const EntityHandle h, int& result );
      26                 :            : 
      27                 :            : /**\brief Resize MeshSet::CompactList.  Returns pointer to storage */
      28                 :            : static EntityHandle* resize_compact_list( MeshSet::Count& count, MeshSet::CompactList& clist, size_t new_list_size );
      29                 :            : /**\brief Methods to insert/remove range-based data from contents list.
      30                 :            :  *        Templatized to operate on both Range and set-based MeshSets.
      31                 :            :  */
      32                 :            : template < typename pair_iter_t >
      33                 :            : class range_tool
      34                 :            : {
      35                 :            :   public:
      36                 :            :     /** Insert range-based data into range-based MeshSet */
      37                 :            :     inline static ErrorCode ranged_insert_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
      38                 :            :                                                     pair_iter_t begin, pair_iter_t end, EntityHandle my_handle,
      39                 :            :                                                     AEntityFactory* adj );
      40                 :            : 
      41                 :            :     /** Remove range-based data from range-based MeshSet */
      42                 :            :     inline static ErrorCode ranged_remove_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
      43                 :            :                                                     pair_iter_t begin, pair_iter_t end, EntityHandle my_handle,
      44                 :            :                                                     AEntityFactory* adj );
      45                 :            : 
      46                 :            :     /** Insert range-based data into list-based MeshSet */
      47                 :            :     inline static ErrorCode vector_insert_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
      48                 :            :                                                     pair_iter_t begin, pair_iter_t end, EntityHandle my_handle,
      49                 :            :                                                     AEntityFactory* adj );
      50                 :            : };
      51                 :            : 
      52                 :            : /** Remove Range of handles fromr vector-based MeshSet */
      53                 :            : static ErrorCode vector_remove_range( MeshSet::Count& count, MeshSet::CompactList& clist, const Range& range,
      54                 :            :                                       EntityHandle my_handle, AEntityFactory* adj );
      55                 :            : 
      56                 :            : /** Remove range-based MeshSet contents from vector-based MeshSet */
      57                 :            : static ErrorCode vector_remove_ranges( MeshSet::Count& count, MeshSet::CompactList& clist,
      58                 :            :                                        const EntityHandle* pair_list, size_t num_pairs, EntityHandle my_handle,
      59                 :            :                                        AEntityFactory* adj );
      60                 :            : 
      61                 :            : /** Remove unsorted array of handles from vector-based MeshSet */
      62                 :            : static ErrorCode vector_remove_vector( MeshSet::Count& count, MeshSet::CompactList& clist, const EntityHandle* vect,
      63                 :            :                                        size_t vect_size, EntityHandle my_handle, AEntityFactory* adj );
      64                 :            : 
      65                 :            : /** Insert unsorted array of handles into vector-based MeshSet */
      66                 :            : static ErrorCode vector_insert_vector( MeshSet::Count& count, MeshSet::CompactList& clist, const EntityHandle* vect,
      67                 :            :                                        size_t vect_size, EntityHandle my_handle, AEntityFactory* adj );
      68                 :            : 
      69                 :            : /** Convert unsorted array of handles into array of ranged [begin,end] pairs */
      70                 :            : static void convert_to_ranges( const EntityHandle* vect_in, size_t vect_in_len, std::vector< EntityHandle >& vect_out );
      71                 :            : 
      72                 :            : /*****************************************************************************************
      73                 :            :  *                             Parent/Child Operations                                   *
      74                 :            :  *****************************************************************************************/
      75                 :            : 
      76                 :      34896 : static inline MeshSet::Count insert_in_vector( const MeshSet::Count count, MeshSet::CompactList& list,
      77                 :            :                                                const EntityHandle h, int& result )
      78                 :            : {
      79   [ +  +  +  +  :      34896 :     switch( count )
                      - ]
      80                 :            :     {
      81                 :            :         case MeshSet::ZERO:
      82                 :      17191 :             list.hnd[0] = h;
      83                 :      17191 :             result      = true;
      84                 :      17191 :             return MeshSet::ONE;
      85                 :            :         case MeshSet::ONE:
      86         [ +  + ]:      16714 :             if( list.hnd[0] == h )
      87                 :            :             {
      88                 :          2 :                 result = false;
      89                 :          2 :                 return MeshSet::ONE;
      90                 :            :             }
      91                 :            :             else
      92                 :            :             {
      93                 :      16712 :                 result      = true;
      94                 :      16712 :                 list.hnd[1] = h;
      95                 :      16712 :                 return MeshSet::TWO;
      96                 :            :             }
      97                 :            :         case MeshSet::TWO:
      98 [ +  + ][ +  + ]:        616 :             if( list.hnd[0] == h || list.hnd[1] == h )
      99                 :            :             {
     100                 :         86 :                 result = false;
     101                 :         86 :                 return MeshSet::TWO;
     102                 :            :             }
     103                 :            :             else
     104                 :            :             {
     105                 :        530 :                 EntityHandle* ptr = (EntityHandle*)malloc( 3 * sizeof( EntityHandle ) );
     106                 :        530 :                 ptr[0]            = list.hnd[0];
     107                 :        530 :                 ptr[1]            = list.hnd[1];
     108                 :        530 :                 ptr[2]            = h;
     109                 :        530 :                 list.ptr[0]       = ptr;
     110                 :        530 :                 list.ptr[1]       = ptr + 3;
     111                 :        530 :                 result            = true;
     112                 :        530 :                 return MeshSet::MANY;
     113                 :            :             }
     114                 :            :         case MeshSet::MANY:
     115         [ +  + ]:        375 :             if( std::find( list.ptr[0], list.ptr[1], h ) != list.ptr[1] ) { result = false; }
     116                 :            :             else
     117                 :            :             {
     118                 :        373 :                 int size          = list.ptr[1] - list.ptr[0];
     119                 :        373 :                 list.ptr[0]       = (EntityHandle*)realloc( list.ptr[0], ( size + 1 ) * sizeof( EntityHandle ) );
     120                 :        373 :                 list.ptr[0][size] = h;
     121                 :        373 :                 list.ptr[1]       = list.ptr[0] + size + 1;
     122                 :        373 :                 result            = true;
     123                 :            :             }
     124                 :        375 :             return MeshSet::MANY;
     125                 :            :     }
     126                 :            : 
     127                 :          0 :     return MeshSet::ZERO;
     128                 :            : }
     129                 :            : 
     130                 :      29610 : static inline MeshSet::Count remove_from_vector( const MeshSet::Count count, MeshSet::CompactList& list,
     131                 :            :                                                  const EntityHandle h, int& result )
     132                 :            : {
     133   [ +  +  +  +  :      29610 :     switch( count )
                      - ]
     134                 :            :     {
     135                 :            :         case MeshSet::ZERO:
     136                 :      29198 :             result = false;
     137                 :      29198 :             return MeshSet::ZERO;
     138                 :            :         case MeshSet::ONE:
     139         [ +  - ]:        232 :             if( h == list.hnd[0] )
     140                 :            :             {
     141                 :        232 :                 result = true;
     142                 :        232 :                 return MeshSet::ZERO;
     143                 :            :             }
     144                 :            :             else
     145                 :            :             {
     146                 :          0 :                 result = false;
     147                 :          0 :                 return MeshSet::ONE;
     148                 :            :             }
     149                 :            :         case MeshSet::TWO:
     150         [ +  + ]:         80 :             if( h == list.hnd[0] )
     151                 :            :             {
     152                 :         52 :                 list.hnd[0] = list.hnd[1];
     153                 :         52 :                 result      = true;
     154                 :         52 :                 return MeshSet::ONE;
     155                 :            :             }
     156         [ +  + ]:         28 :             else if( h == list.hnd[1] )
     157                 :            :             {
     158                 :         26 :                 result = true;
     159                 :         26 :                 return MeshSet::ONE;
     160                 :            :             }
     161                 :            :             else
     162                 :            :             {
     163                 :          2 :                 result = false;
     164                 :          2 :                 return MeshSet::TWO;
     165                 :            :             }
     166                 :            :         case MeshSet::MANY: {
     167                 :            :             EntityHandle *i, *j, *p;
     168                 :        100 :             i = std::find( list.ptr[0], list.ptr[1], h );
     169         [ +  + ]:        100 :             if( i == list.ptr[1] )
     170                 :            :             {
     171                 :          2 :                 result = false;
     172                 :          2 :                 return MeshSet::MANY;
     173                 :            :             }
     174                 :            : 
     175                 :         98 :             result = true;
     176                 :         98 :             p      = list.ptr[1] - 1;
     177         [ +  + ]:        206 :             while( i != p )
     178                 :            :             {
     179                 :        108 :                 j  = i + 1;
     180                 :        108 :                 *i = *j;
     181                 :        108 :                 i  = j;
     182                 :            :             }
     183                 :         98 :             int size = p - list.ptr[0];
     184         [ +  + ]:         98 :             if( size == 2 )
     185                 :            :             {
     186                 :         90 :                 p           = list.ptr[0];
     187                 :         90 :                 list.hnd[0] = p[0];
     188                 :         90 :                 list.hnd[1] = p[1];
     189                 :         90 :                 free( p );
     190                 :         90 :                 return MeshSet::TWO;
     191                 :            :             }
     192                 :            :             else
     193                 :            :             {
     194                 :          8 :                 list.ptr[0] = (EntityHandle*)realloc( list.ptr[0], size * sizeof( EntityHandle ) );
     195                 :          8 :                 list.ptr[1] = list.ptr[0] + size;
     196                 :          8 :                 return MeshSet::MANY;
     197                 :            :             }
     198                 :            :         }
     199                 :            :     }
     200                 :            : 
     201                 :          0 :     return MeshSet::ZERO;
     202                 :            : }
     203                 :            : 
     204                 :       2207 : int MeshSet::add_parent( EntityHandle parent )
     205                 :            : {
     206                 :       2207 :     int result   = 0;
     207         [ +  - ]:       2207 :     mParentCount = insert_in_vector( (Count)mParentCount, parentMeshSets, parent, result );
     208                 :       2207 :     return result;
     209                 :            : }
     210                 :      32689 : int MeshSet::add_child( EntityHandle child )
     211                 :            : {
     212                 :      32689 :     int result  = 0;
     213         [ +  - ]:      32689 :     mChildCount = insert_in_vector( (Count)mChildCount, childMeshSets, child, result );
     214                 :      32689 :     return result;
     215                 :            : }
     216                 :            : 
     217                 :      29367 : int MeshSet::remove_parent( EntityHandle parent )
     218                 :            : {
     219                 :      29367 :     int result   = 0;
     220         [ +  - ]:      29367 :     mParentCount = remove_from_vector( (Count)mParentCount, parentMeshSets, parent, result );
     221                 :      29367 :     return result;
     222                 :            : }
     223                 :        243 : int MeshSet::remove_child( EntityHandle child )
     224                 :            : {
     225                 :        243 :     int result  = 0;
     226         [ +  - ]:        243 :     mChildCount = remove_from_vector( (Count)mChildCount, childMeshSets, child, result );
     227                 :        243 :     return result;
     228                 :            : }
     229                 :            : 
     230                 :            : /*****************************************************************************************
     231                 :            :  *                          Flag Conversion Operations                                   *
     232                 :            :  *****************************************************************************************/
     233                 :            : 
     234                 :          4 : ErrorCode MeshSet::convert( unsigned flg, EntityHandle my_handle, AEntityFactory* adj )
     235                 :            : {
     236                 :          4 :     ErrorCode rval = MB_SUCCESS;
     237 [ +  + ][ +  - ]:          4 :     if( ( mFlags & MESHSET_TRACK_OWNER ) && !( flg & MESHSET_TRACK_OWNER ) )
     238                 :          1 :         rval = remove_adjacencies( my_handle, adj );
     239 [ +  - ][ +  + ]:          3 :     else if( !( mFlags & MESHSET_TRACK_OWNER ) && ( flg & MESHSET_TRACK_OWNER ) )
     240                 :          1 :         rval = create_adjacencies( my_handle, adj );
     241         [ -  + ]:          4 :     if( MB_SUCCESS != rval ) return rval;
     242                 :            : 
     243 [ +  + ][ +  + ]:          4 :     if( !( mFlags & MESHSET_ORDERED ) && ( flg & MESHSET_ORDERED ) )
     244                 :            :     {
     245                 :            :         size_t datalen;
     246         [ +  - ]:          1 :         EntityHandle* data = get_contents( datalen );
     247         [ +  - ]:          1 :         if( datalen )
     248                 :            :         {
     249         [ +  - ]:          1 :             std::vector< EntityHandle > list( datalen );
     250         [ +  - ]:          1 :             memcpy( &list[0], data, datalen * sizeof( EntityHandle ) );
     251         [ +  - ]:          1 :             int num_ents  = num_entities();
     252                 :          1 :             Count count   = (Count)mContentCount;
     253                 :          1 :             data          = resize_compact_list( count, contentList, num_ents );
     254                 :          1 :             mContentCount = count;
     255         [ -  + ]:          1 :             assert( list.size() % 2 == 0 );
     256                 :          1 :             std::vector< EntityHandle >::iterator i = list.begin();
     257 [ +  - ][ +  + ]:          2 :             while( i != list.end() )
     258                 :            :             {
     259         [ +  - ]:          1 :                 EntityHandle h = *i;
     260         [ +  - ]:          1 :                 ++i;
     261         [ +  - ]:          1 :                 EntityHandle e = *i;
     262         [ +  - ]:          1 :                 ++i;
     263         [ +  + ]:         11 :                 for( ; h <= e; ++h )
     264                 :            :                 {
     265                 :         10 :                     *data = h;
     266                 :         10 :                     ++data;
     267                 :            :                 }
     268                 :          1 :             }
     269                 :          1 :         }
     270                 :            :     }
     271 [ +  + ][ +  - ]:          3 :     else if( ( mFlags & MESHSET_ORDERED ) && !( flg & MESHSET_ORDERED ) )
     272                 :            :     {
     273                 :            :         size_t datalen;
     274         [ +  - ]:          1 :         EntityHandle* data = get_contents( datalen );
     275         [ +  - ]:          1 :         if( datalen )
     276                 :            :         {
     277         [ +  - ]:          1 :             std::vector< EntityHandle > ranges;
     278         [ +  - ]:          1 :             convert_to_ranges( data, datalen, ranges );
     279                 :          1 :             Count count   = (Count)mContentCount;
     280                 :          1 :             data          = resize_compact_list( count, contentList, ranges.size() );
     281                 :          1 :             mContentCount = count;
     282         [ +  - ]:          1 :             memcpy( data, &ranges[0], ranges.size() * sizeof( EntityHandle ) );
     283                 :            :         }
     284                 :            :     }
     285                 :            : 
     286                 :          4 :     return MB_SUCCESS;
     287                 :            : }
     288                 :            : 
     289                 :          1 : ErrorCode MeshSet::create_adjacencies( EntityHandle my_handle, AEntityFactory* adj )
     290                 :            : {
     291                 :          1 :     ErrorCode rval = MB_SUCCESS;
     292                 :            :     ;
     293                 :            :     size_t count;
     294         [ +  - ]:          1 :     const EntityHandle* const ptr = get_contents( count );
     295                 :          1 :     const EntityHandle* const end = ptr + count;
     296 [ +  - ][ -  + ]:          1 :     if( vector_based() )
     297                 :            :     {
     298         [ #  # ]:          0 :         for( const EntityHandle* i = ptr; i != end; ++i )
     299                 :            :         {
     300         [ #  # ]:          0 :             rval = adj->add_adjacency( *i, my_handle, false );
     301         [ #  # ]:          0 :             if( MB_SUCCESS != rval )
     302                 :            :             {
     303         [ #  # ]:          0 :                 for( const EntityHandle* j = ptr; j != i; ++j )
     304         [ #  # ]:          0 :                     adj->remove_adjacency( *j, my_handle );
     305                 :          0 :                 return rval;
     306                 :            :             }
     307                 :            :         }
     308                 :            :     }
     309                 :            :     else
     310                 :            :     {
     311         [ -  + ]:          1 :         assert( 0 == count % 2 );
     312         [ +  + ]:          2 :         for( const EntityHandle* i = ptr; i != end; i += 2 )
     313                 :            :         {
     314         [ +  + ]:         11 :             for( EntityHandle h = i[0]; h <= i[1]; ++h )
     315                 :            :             {
     316         [ +  - ]:         10 :                 rval = adj->add_adjacency( h, my_handle, false );
     317         [ -  + ]:         10 :                 if( MB_SUCCESS != rval )
     318                 :            :                 {
     319         [ #  # ]:          0 :                     for( EntityHandle j = i[0]; j < h; ++j )
     320         [ #  # ]:          0 :                         adj->remove_adjacency( j, my_handle );
     321         [ #  # ]:          0 :                     for( const EntityHandle* j = ptr; j != i; j += 2 )
     322         [ #  # ]:          0 :                         for( EntityHandle k = j[0]; k <= j[1]; ++k )
     323         [ #  # ]:          0 :                             adj->remove_adjacency( k, my_handle );
     324                 :          0 :                     return rval;
     325                 :            :                 }
     326                 :            :             }
     327                 :            :         }
     328                 :            :     }
     329                 :          1 :     return MB_SUCCESS;
     330                 :            : }
     331                 :            : 
     332                 :          8 : ErrorCode MeshSet::remove_adjacencies( EntityHandle my_handle, AEntityFactory* adj )
     333                 :            : {
     334                 :            :     size_t count;
     335         [ +  - ]:          8 :     const EntityHandle* const ptr = get_contents( count );
     336                 :          8 :     const EntityHandle* const end = ptr + count;
     337 [ +  - ][ +  + ]:          8 :     if( vector_based() )
     338                 :            :     {
     339         [ +  + ]:         61 :         for( const EntityHandle* i = ptr; i != end; ++i )
     340         [ +  - ]:         57 :             adj->remove_adjacency( *i, my_handle );
     341                 :            :     }
     342                 :            :     else
     343                 :            :     {
     344         [ -  + ]:          4 :         assert( 0 == count % 2 );
     345         [ +  + ]:         12 :         for( const EntityHandle* i = ptr; i != end; i += 2 )
     346         [ +  + ]:        234 :             for( EntityHandle h = i[0]; h <= i[1]; ++h )
     347         [ +  - ]:        226 :                 adj->remove_adjacency( h, my_handle );
     348                 :            :     }
     349                 :          8 :     return MB_SUCCESS;
     350                 :            : }
     351                 :            : 
     352                 :            : /*****************************************************************************************
     353                 :            :  *                          Contents Modifiction Methods                                 *
     354                 :            :  *****************************************************************************************/
     355                 :            : 
     356                 :      31109 : static EntityHandle* resize_compact_list( MeshSet::Count& count, MeshSet::CompactList& clist, size_t new_list_size )
     357                 :            : {
     358         [ +  + ]:      31109 :     if( count <= 2 )
     359                 :            :     {
     360         [ +  + ]:      22334 :         if( new_list_size <= 2 )
     361                 :            :         {
     362                 :       3883 :             count = (MeshSet::Count)new_list_size;
     363                 :       3883 :             return clist.hnd;
     364                 :            :         }
     365                 :            :         else
     366                 :            :         {
     367                 :      18451 :             EntityHandle* list = (EntityHandle*)malloc( new_list_size * sizeof( EntityHandle ) );
     368                 :      18451 :             list[0]            = clist.hnd[0];
     369                 :      18451 :             list[1]            = clist.hnd[1];
     370                 :      18451 :             clist.ptr[0]       = list;
     371                 :      18451 :             clist.ptr[1]       = list + new_list_size;
     372                 :      18451 :             count              = MeshSet::MANY;
     373                 :      18451 :             return list;
     374                 :            :         }
     375                 :            :     }
     376         [ +  + ]:       8775 :     else if( new_list_size > 2 )
     377                 :            :     {
     378         [ +  + ]:       8752 :         if( new_list_size > ( size_t )( clist.ptr[1] - clist.ptr[0] ) )
     379                 :        514 :             clist.ptr[0] = (EntityHandle*)realloc( clist.ptr[0], new_list_size * sizeof( EntityHandle ) );
     380                 :       8752 :         clist.ptr[1] = clist.ptr[0] + new_list_size;
     381                 :       8752 :         count        = MeshSet::MANY;
     382                 :       8752 :         return clist.ptr[0];
     383                 :            :     }
     384                 :            :     else
     385                 :            :     {
     386                 :         23 :         EntityHandle* list = clist.ptr[0];
     387                 :         23 :         clist.hnd[0]       = list[0];
     388                 :         23 :         clist.hnd[1]       = list[1];
     389                 :         23 :         free( list );
     390                 :         23 :         count = (MeshSet::Count)new_list_size;
     391                 :         23 :         return clist.hnd;
     392                 :            :     }
     393                 :            : }
     394                 :            : 
     395                 :            : typedef std::pair< EntityHandle, EntityHandle > MeshSetRange;
     396                 :            : 
     397                 :            : class MeshSetRComp
     398                 :            : {
     399                 :            :   public:
     400                 :      26863 :     bool operator()( const MeshSetRange& r, const MeshSetRange& h )
     401                 :            :     {
     402                 :      26863 :         return r.second < h.first;
     403                 :            :     }
     404                 :            : };
     405                 :            : 
     406                 :            : template < typename pair_iter_t >
     407                 :      29893 : inline ErrorCode range_tool< pair_iter_t >::ranged_insert_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
     408                 :            :                                                                     pair_iter_t begin, pair_iter_t end,
     409                 :            :                                                                     EntityHandle my_handle, AEntityFactory* adj )
     410                 :            : {
     411                 :            :     // first pass:
     412                 :            :     // 1) merge existing ranges
     413                 :            :     // 2) count number of new ranges that must be inserted
     414                 :            :     EntityHandle* list_ptr;
     415                 :            :     size_t list_size;
     416 [ +  + ][ +  + ]:      29893 :     if( count < MeshSet::MANY )
     417                 :            :     {
     418                 :      21520 :         list_ptr  = clist.hnd;
     419                 :      21520 :         list_size = count;
     420                 :            :     }
     421                 :            :     else
     422                 :            :     {
     423                 :       8373 :         list_ptr  = clist.ptr[0];
     424                 :       8373 :         list_size = clist.ptr[1] - clist.ptr[0];
     425                 :            :     }
     426                 :            : 
     427                 :      29893 :     MeshSetRange* list = reinterpret_cast< MeshSetRange* >( list_ptr );
     428 [ -  + ][ -  + ]:      29893 :     assert( 0 == list_size % 2 );
     429 [ -  + ][ -  + ]:      29893 :     assert( 2 * sizeof( EntityHandle ) == sizeof( MeshSetRange ) );
     430                 :      29893 :     list_size /= 2;
     431                 :      29893 :     MeshSetRange* const list_end = list + list_size;
     432                 :      29893 :     MeshSetRange *list_read = list, *list_write = list;
     433                 :      29893 :     pair_iter_t i = begin;
     434                 :            : 
     435                 :            :     // count number of range pairs that are straight insertions
     436                 :            :     // (don't overlap any range pair in the current set) that
     437                 :            :     // could not be inserted during the first pass.
     438                 :      29893 :     size_t insert_count = 0;
     439                 :            : 
     440                 :            :     // merge lists
     441 [ +  - ][ +  + ]:      59621 :     while( i != end )
                 [ +  + ]
     442                 :            :     {
     443                 :            :         // find first range that intersects the current input range
     444                 :            : 
     445                 :            :         // do binary search if no holes in current set contents
     446 [ +  + ][ +  + ]:      29728 :         if( list_read == list_write )
     447                 :            :         {
     448                 :            :             // subtract one from i->first because if it is one greater
     449                 :            :             // then the the last value of some block, then we want that
     450                 :            :             // block to append to.
     451                 :      29714 :             MeshSetRange tmp;
     452         [ +  - ]:      18691 :             tmp.first  = i->first - 1;
     453         [ +  - ]:      18691 :             tmp.second = i->second;
     454 [ +  - ][ +  - ]:      29714 :             list_write = std::lower_bound( list_read, list_end, tmp, MeshSetRComp() );
     455                 :      29714 :             list_read  = list_write;
     456                 :            :         }
     457                 :            :         // otherwise shift down until we find where we find a range block
     458                 :            :         // that intersects
     459                 :            :         else
     460 [ +  + ][ +  - ]:         15 :             while( list_read != list_end && list_read->second + 1 < i->first )
         [ -  + ][ -  + ]
         [ +  + ][ +  + ]
     461                 :            :             {
     462         [ #  # ]:          1 :                 *list_write = *list_read;
     463                 :          1 :                 ++list_write;
     464                 :          1 :                 ++list_read;
     465                 :            :             }
     466                 :            : 
     467                 :            :         // handle any straight insertions of range blocks
     468 [ +  - ][ +  - ]:     121486 :         for( ; i != end && ( list_read == list_end || i->second + 1 < list_read->first ); ++i )
         [ +  + ][ +  + ]
         [ +  - ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     469                 :            :         {
     470                 :            :             // If we haven't removed any range pairs, we don't have space to
     471                 :            :             // insert here.  Defer the insertion until later.
     472 [ +  + ][ +  + ]:      91758 :             if( list_read == list_write ) { ++insert_count; }
     473                 :            :             else
     474                 :            :             {
     475 [ -  + ][ +  + ]:          9 :                 if( adj )
     476 [ #  # ][ #  # ]:          4 :                     for( EntityHandle j = i->first; j <= i->second; ++j )
         [ #  # ][ +  + ]
     477         [ #  # ]:          2 :                         adj->add_adjacency( j, my_handle, false );
     478                 :            : 
     479         [ +  - ]:          4 :                 list_write->first  = i->first;
     480         [ +  - ]:          4 :                 list_write->second = i->second;
     481                 :          9 :                 ++list_write;
     482                 :            :             }
     483                 :            :         }
     484                 :            : 
     485                 :            :         // merge all the stuff that gets merged into a single range pair
     486                 :            :         // from both the input list and the existing set data
     487 [ +  + ][ +  + ]:      29728 :         if( list_read != list_end )
     488                 :            :         {
     489                 :       9661 :             MeshSetRange working = *list_read;  // copy because might be the same as list_write
     490                 :       9661 :             ++list_read;
     491                 :            : 
     492                 :            :             // Check if we need to prepend to the existing block.
     493                 :            :             // We only need to check this for the first input range because
     494                 :            :             // after this working.first will always be the first possible handle
     495                 :            :             // in the merged set of ranges.
     496 [ +  - ][ +  + ]:       9661 :             if( i != end && i->first < working.first && i->second + 1 >= working.first )
         [ +  - ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  + ][ +  - ]
     497                 :            :             {
     498 [ +  + ][ +  + ]:         34 :                 if( adj )
     499 [ +  - ][ +  + ]:        119 :                     for( EntityHandle h = i->first; h < working.first; ++h )
                 [ +  + ]
     500 [ +  - ][ +  - ]:        111 :                         adj->add_adjacency( h, my_handle, false );
     501         [ +  - ]:         34 :                 working.first = i->first;
     502                 :            :             }
     503                 :            : 
     504                 :            :             // Now append from the input list and the remaining set contents
     505                 :            :             // until we've consolidated all overlapping/touching ranges.
     506                 :       9661 :             bool done = false;
     507 [ +  + ][ +  + ]:      29073 :             while( !done )
     508                 :            :             {
     509                 :            :                 // does next set contents range touch working range?
     510 [ +  + ][ +  + ]:      19412 :                 bool set_overlap = list_read != list_end && list_read->first <= working.second + 1;
         [ +  + ][ +  + ]
     511                 :            :                 // does next input range touch working range?
     512 [ +  - ][ +  + ]:      19412 :                 bool inp_overlap = i != end && i->first <= working.second + 1;
         [ +  - ][ +  + ]
         [ +  + ][ +  + ]
     513                 :            : 
     514                 :            :                 // if both ranges touch...
     515 [ +  + ][ +  + ]:      19412 :                 if( inp_overlap && set_overlap )
         [ +  + ][ +  + ]
     516                 :            :                 {
     517                 :            :                     // if next set range is contained in working, skip it
     518 [ -  + ][ -  + ]:         40 :                     if( list_read->second <= working.second ) ++list_read;
     519                 :            :                     // if next input range is contained in working, skip it
     520 [ +  - ][ -  + ]:         20 :                     else if( i->second <= working.second )
                 [ -  + ]
     521         [ #  # ]:          0 :                         ++i;
     522                 :            :                     // Otherwise set the working end to the smaller of the two
     523                 :            :                     // ends: either the next set end or the next input end.
     524                 :            :                     // We want the smaller of the two because the larger might
     525                 :            :                     // intersect additional ranges in the other list.
     526 [ +  - ][ +  - ]:         20 :                     else if( list_read->second <= i->second )
                 [ +  + ]
     527                 :            :                     {
     528                 :         18 :                         working.second = list_read->second;
     529                 :         18 :                         ++list_read;
     530                 :            :                     }
     531                 :            :                     else
     532                 :            :                     {
     533         [ #  # ]:          0 :                         working.second = i->second;
     534         [ #  # ]:          2 :                         ++i;
     535                 :            :                     }
     536                 :            :                 }
     537                 :            :                 // If only the input range intersect the current working range...
     538 [ +  + ][ +  + ]:      19392 :                 else if( inp_overlap )
     539                 :            :                 {
     540                 :            :                     // Would it be more efficient to just extent 'working' to
     541                 :            :                     // the end of the current input range?  We'd end up adding
     542                 :            :                     // adjacencies for for entities that are already in the tracking
     543                 :            :                     // set and therefore already have the adjacency.
     544         [ +  - ]:         87 :                     EntityHandle last = i->second;
     545 [ +  + ][ +  + ]:       9702 :                     if( list_read != list_end && list_read->first < last )
         [ +  + ][ +  + ]
     546                 :         20 :                         last = list_read->first - 1;
     547                 :            :                     else
     548         [ +  - ]:       9682 :                         ++i;
     549                 :            : 
     550 [ +  + ][ +  + ]:       9702 :                     if( last > working.second )
     551                 :            :                     {
     552 [ +  + ][ +  + ]:       9640 :                         if( adj )
     553 [ +  + ][ +  + ]:        345 :                             for( EntityHandle h = working.second + 1; h <= last; ++h )
     554 [ +  - ][ +  - ]:        325 :                                 adj->add_adjacency( h, my_handle, false );
     555                 :            : 
     556                 :       9702 :                         working.second = last;
     557                 :            :                     }
     558                 :            :                 }
     559 [ +  + ][ +  + ]:       9690 :                 else if( set_overlap )
     560                 :            :                 {
     561 [ +  - ][ +  + ]:         29 :                     if( working.second < list_read->second ) working.second = list_read->second;
     562                 :         29 :                     ++list_read;
     563                 :            :                 }
     564                 :            :                 else
     565                 :            :                 {
     566                 :       9661 :                     done = true;
     567                 :            :                 }
     568                 :            :             }
     569                 :            : 
     570 [ -  + ][ -  + ]:       9661 :             assert( list_write < list_read );
     571 [ +  - ][ +  - ]:       9661 :             *list_write = working;
     572                 :       9661 :             ++list_write;
     573                 :            :         }
     574                 :            :     }
     575                 :            : 
     576                 :            :     // shuffle down entries to fill holes
     577 [ +  + ][ +  + ]:      29893 :     if( list_read == list_write )
     578                 :      29875 :         list_read = list_write = list_end;
     579                 :            :     else
     580 [ +  + ][ +  + ]:         27 :         while( list_read < list_end )
     581                 :            :         {
     582         [ +  - ]:          9 :             *list_write = *list_read;
     583                 :          9 :             ++list_read;
     584                 :          9 :             ++list_write;
     585                 :            :         }
     586                 :            : 
     587                 :            :     // adjust allocated array size
     588                 :      29893 :     const size_t occupied_size = list_write - list;
     589                 :      29893 :     const size_t new_list_size = occupied_size + insert_count;
     590                 :      29893 :     list_ptr                   = resize_compact_list( count, clist, 2 * new_list_size );
     591                 :            :     // done?
     592 [ +  + ][ +  + ]:      29893 :     if( !insert_count ) return MB_SUCCESS;
     593                 :      20087 :     list = reinterpret_cast< MeshSetRange* >( list_ptr );
     594                 :            : 
     595                 :            :     // Second pass: insert non-mergable range pairs
     596                 :            :     // All range pairs in the input are either completely disjoint from
     597                 :            :     // the ones in the mesh set and must be inserted or are entirely contained
     598                 :            :     // within a range pair in the mesh set.
     599 [ +  - ][ -  + ]:      20087 :     assert( begin != end );  // can't have items to insert if given empty input list
                 [ -  + ]
     600                 :      20087 :     pair_iter_t ri = end;
     601         [ +  - ]:      18649 :     --ri;
     602                 :      20087 :     list_write = list + new_list_size - 1;
     603                 :      20087 :     list_read  = list + occupied_size - 1;
     604 [ +  - ][ +  - ]:      91823 :     for( ; list_write >= list; --list_write )
     605                 :            :     {
     606 [ +  + ][ +  + ]:      91823 :         if( list_read >= list )
     607                 :            :         {
     608 [ +  - ][ +  + ]:        848 :             while( ri->first >= list_read->first && ri->second <= list_read->second )
         [ +  - ][ +  + ]
         [ +  + ][ +  + ]
                 [ +  + ]
     609                 :            :             {
     610 [ +  - ][ -  + ]:         20 :                 assert( ri != begin );
                 [ -  + ]
     611         [ +  - ]:         20 :                 --ri;
     612                 :            :             }
     613                 :            : 
     614 [ +  - ][ +  + ]:        828 :             if( list_read->first > ri->second )
                 [ +  + ]
     615                 :            :             {
     616         [ +  - ]:         74 :                 *list_write = *list_read;
     617                 :         74 :                 --list_read;
     618                 :         74 :                 continue;
     619                 :            :             }
     620                 :            :         }
     621                 :            : 
     622 [ -  + ][ -  + ]:      91749 :         assert( insert_count > 0 );
     623 [ +  + ][ +  + ]:      91749 :         if( adj )
     624 [ +  - ][ +  - ]:     267868 :             for( EntityHandle h = ri->first; h <= ri->second; ++h )
         [ +  + ][ +  + ]
     625         [ +  - ]:     267615 :                 adj->add_adjacency( h, my_handle, false );
     626         [ +  - ]:      88005 :         list_write->first  = ri->first;
     627         [ +  - ]:      88005 :         list_write->second = ri->second;
     628                 :            : 
     629                 :            :         // don't have reverse iterator, so check before decrement
     630                 :            :         // if insert_count isn't zero, must be more in range
     631 [ +  + ][ +  + ]:      91749 :         if( 0 == --insert_count )
     632                 :            :         {
     633 [ -  + ][ -  + ]:      20087 :             assert( list_read == list_write - 1 );
     634                 :      20087 :             break;
     635                 :            :         }
     636                 :            :         else
     637                 :            :         {
     638         [ +  - ]:      71662 :             --ri;
     639                 :            :         }
     640                 :            :     }
     641                 :            : 
     642 [ -  + ][ -  + ]:      20087 :     assert( !insert_count );
     643                 :      29893 :     return MB_SUCCESS;
     644                 :            : }
     645                 :            : 
     646                 :            : template < typename pair_iter_t >
     647                 :        342 : inline ErrorCode range_tool< pair_iter_t >::ranged_remove_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
     648                 :            :                                                                     pair_iter_t begin, pair_iter_t end,
     649                 :            :                                                                     EntityHandle my_handle, AEntityFactory* adj )
     650                 :            : {
     651                 :            :     // first pass:
     652                 :            :     // 1) remove (from) existing ranges
     653                 :            :     // 2) count number of ranges that must be split
     654                 :        342 :     ptrdiff_t split_count = 0;
     655                 :            :     EntityHandle* list;
     656                 :            :     size_t list_size;
     657 [ +  + ][ +  + ]:        342 :     if( count < MeshSet::MANY )
     658                 :            :     {
     659                 :        121 :         list      = clist.hnd;
     660                 :        121 :         list_size = count;
     661                 :            :     }
     662                 :            :     else
     663                 :            :     {
     664                 :        221 :         list      = clist.ptr[0];
     665                 :        221 :         list_size = clist.ptr[1] - clist.ptr[0];
     666                 :            :     }
     667                 :            : 
     668                 :        342 :     EntityHandle* list_write     = list;
     669                 :        342 :     EntityHandle *const list_end = list + list_size, *list_read = list;
     670                 :        342 :     pair_iter_t i = begin;
     671                 :            : 
     672 [ +  + ][ +  - ]:        659 :     while( list_read != list_end && i != end )
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     673                 :            :     {
     674                 :            : 
     675 [ +  - ][ +  + ]:        415 :         while( i != end && i->second < list_read[0] )
         [ +  - ][ +  + ]
         [ +  + ][ +  + ]
                 [ +  + ]
     676         [ +  - ]:         80 :             ++i;
     677 [ +  - ][ +  + ]:        335 :         if( i == end ) break;
                 [ +  + ]
     678                 :            : 
     679                 :            :         // if there are holes in the current array, shuffle blocks
     680                 :            :         // down until we find the next block to remove
     681 [ +  + ][ +  + ]:        322 :         if( list_read != list_write )
     682                 :            :         {
     683 [ +  - ][ +  - ]:         57 :             while( list_read != list_end && i->second < list_read[0] )
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
     684                 :            :             {
     685                 :          0 :                 list_write[0] = list_read[0];
     686                 :          0 :                 list_write[1] = list_read[1];
     687                 :          0 :                 list_write += 2;
     688                 :          0 :                 list_read += 2;
     689                 :            :             }
     690                 :            :         }
     691                 :            :         // otherwise do a binary search
     692                 :            :         else
     693                 :            :         {
     694 [ +  - ][ +  - ]:        265 :             list_write = std::lower_bound( list_write, list_end, i->first );
     695                 :            :             // if in middle of range block (odd index), back up to start of block
     696                 :        265 :             list_write -= ( list_write - list ) % 2;
     697                 :        265 :             list_read = list_write;
     698                 :            :         }
     699                 :            : 
     700                 :            :         // if everything remaning is past end of set contents...
     701 [ +  + ][ +  + ]:        322 :         if( list_read == list_end ) break;
     702                 :            : 
     703                 :            :         // skip any remove pairs that aren't in the list
     704 [ +  - ][ -  + ]:        317 :         if( i->second < list_read[0] )
                 [ +  + ]
     705                 :            :         {
     706         [ #  # ]:          0 :             ++i;
     707                 :          3 :             continue;
     708                 :            :         }
     709                 :            : 
     710                 :            :         // Begin by assuming that we will keep the entire block
     711                 :        314 :         list_write[0] = list_read[0];
     712                 :        314 :         list_write[1] = list_read[1];
     713                 :        314 :         list_read += 2;
     714                 :            : 
     715 [ +  - ][ +  - ]:        536 :         for( ; i != end && i->first <= list_write[1]; ++i )
         [ +  + ][ +  - ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     716                 :            :         {
     717 [ +  - ][ +  + ]:        331 :             if( i->first <= list_write[0] )
                 [ +  + ]
     718                 :            :             {
     719                 :            :                 // remove whole block
     720 [ +  - ][ +  + ]:        264 :                 if( i->second >= list_write[1] )
                 [ +  + ]
     721                 :            :                 {
     722 [ +  + ][ +  + ]:         84 :                     if( adj )
     723 [ +  + ][ +  + ]:        909 :                         for( EntityHandle h = list_write[0]; h <= list_write[1]; ++h )
     724         [ +  - ]:        886 :                             adj->remove_adjacency( h, my_handle );
     725                 :         84 :                     list_write -= 2;
     726                 :         84 :                     break;
     727                 :            :                 }
     728                 :            :                 // remove from start of block
     729 [ +  - ][ +  - ]:        180 :                 else if( i->second >= list_write[0] )
                 [ +  - ]
     730                 :            :                 {
     731 [ +  + ][ +  + ]:        180 :                     if( adj )
     732 [ +  - ][ +  + ]:        245 :                         for( EntityHandle h = list_write[0]; h <= i->second; ++h )
                 [ +  + ]
     733         [ +  - ]:        155 :                             adj->remove_adjacency( h, my_handle );
     734         [ +  - ]:        180 :                     list_write[0] = i->second + 1;
     735                 :            :                 }
     736                 :            :             }
     737 [ +  - ][ +  - ]:         67 :             else if( i->first <= list_write[1] )
                 [ +  - ]
     738                 :            :             {
     739                 :            :                 // remove from end of block
     740 [ +  - ][ +  + ]:         67 :                 if( i->second >= list_write[1] )
                 [ +  + ]
     741                 :            :                 {
     742 [ +  + ][ +  + ]:         25 :                     if( adj )
     743 [ +  - ][ +  + ]:        272 :                         for( EntityHandle h = i->first; h <= list_write[1]; ++h )
                 [ +  + ]
     744         [ +  - ]:        259 :                             adj->remove_adjacency( h, my_handle );
     745         [ +  - ]:         10 :                     list_write[1] = i->first - 1;
     746                 :            :                     // list_write += 2;
     747                 :         25 :                     break;
     748                 :            :                 }
     749                 :            :                 // split block
     750                 :            :                 else
     751                 :            :                 {
     752 [ +  + ][ +  + ]:         42 :                     if( adj )
     753 [ +  - ][ +  - ]:        394 :                         for( EntityHandle h = i->first; h <= i->second; ++h )
         [ +  + ][ +  + ]
     754         [ +  - ]:        375 :                             adj->remove_adjacency( h, my_handle );
     755                 :            : 
     756 [ +  - ][ +  + ]:         42 :                     if( list_read - list_write <= 2 )
     757                 :            :                     {
     758                 :         40 :                         ++split_count;
     759                 :         40 :                         continue;
     760                 :            :                     }
     761                 :            :                     else
     762                 :            :                     {
     763                 :          2 :                         list_write[3] = list_write[1];
     764         [ #  # ]:          0 :                         list_write[1] = i->first - 1;
     765         [ #  # ]:          0 :                         list_write[2] = i->second + 1;
     766                 :          2 :                         list_write += 2;
     767                 :            :                     }
     768                 :            :                 }
     769                 :            :             }
     770                 :            :         }
     771                 :        314 :         list_write += 2;
     772                 :            :     }
     773                 :            : 
     774                 :            :     // shuffle down entries to fill holes
     775 [ +  + ][ +  + ]:        342 :     if( list_read == list_write )
     776                 :        306 :         list_read = list_write = list_end;
     777                 :            :     else
     778 [ +  + ][ +  + ]:         53 :         while( list_read < list_end )
     779                 :            :         {
     780                 :         17 :             list_write[0] = list_read[0];
     781                 :         17 :             list_write[1] = list_read[1];
     782                 :         17 :             list_read += 2;
     783                 :         17 :             list_write += 2;
     784                 :            :         }
     785                 :            : 
     786                 :            :     // adjust allocated array size
     787                 :        342 :     const size_t occupied_size = list_write - list;
     788                 :        342 :     const size_t new_list_size = occupied_size + 2 * split_count;
     789                 :        342 :     list                       = resize_compact_list( count, clist, new_list_size );
     790                 :            :     // done?
     791 [ +  + ][ +  + ]:        342 :     if( !split_count ) return MB_SUCCESS;
     792                 :            : 
     793                 :            :     // Second pass: split range pairs
     794                 :            :     // All range pairs in the input are either already removed or
     795                 :            :     // require one of the existing range pairs to be split
     796 [ +  - ][ -  + ]:         33 :     assert( begin != end );  // can't have ranges to split if given empty input list
                 [ -  + ]
     797                 :         33 :     pair_iter_t ri = end;
     798         [ +  - ]:         20 :     --ri;
     799                 :         33 :     list_write = list + new_list_size - 2;
     800                 :         33 :     list_read  = list + occupied_size - 2;
     801 [ +  - ][ +  - ]:         70 :     for( ; list_write >= list; list_write -= 2 )
     802                 :            :     {
     803 [ +  - ][ +  - ]:         70 :         if( list_read >= list )
     804                 :            :         {
     805 [ +  - ][ +  + ]:        108 :             while( ri->second > list_read[1] )
                 [ +  + ]
     806                 :            :             {
     807 [ +  - ][ -  + ]:         38 :                 assert( ri != begin );
                 [ -  + ]
     808         [ +  - ]:         38 :                 --ri;
     809                 :            :             }
     810                 :            : 
     811 [ +  - ][ +  + ]:         70 :             if( list_read[0] > ri->second )
                 [ +  + ]
     812                 :            :             {
     813                 :         30 :                 list_write[0] = list_read[0];
     814                 :         30 :                 list_write[1] = list_read[1];
     815                 :         30 :                 list_read -= 2;
     816                 :         30 :                 continue;
     817                 :            :             }
     818                 :            :         }
     819                 :            : 
     820 [ -  + ][ -  + ]:         40 :         assert( split_count > 0 );
     821         [ +  - ]:         24 :         list_write[0] = ri->second + 1;
     822                 :         40 :         list_write[1] = list_read[1];
     823         [ +  - ]:         24 :         list_read[1]  = ri->first - 1;
     824                 :            : 
     825                 :            :         // don't have reverse iterator, so check before decrement
     826                 :            :         // if insert_count isn't zero, must be more in range
     827 [ +  + ][ +  + ]:         40 :         if( 0 == --split_count )
     828                 :            :         {
     829 [ -  + ][ -  + ]:         33 :             assert( list_read == list_write - 2 );
     830                 :         33 :             break;
     831                 :            :         }
     832                 :            :         else
     833                 :            :         {
     834         [ +  - ]:          7 :             --ri;
     835                 :            :         }
     836                 :            :     }
     837                 :            : 
     838 [ -  + ][ -  + ]:         33 :     assert( !split_count );
     839                 :        150 :     return MB_SUCCESS;
     840                 :            : }
     841                 :            : 
     842                 :            : template < typename pair_iter_t >
     843                 :        196 : inline ErrorCode range_tool< pair_iter_t >::vector_insert_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
     844                 :            :                                                                     pair_iter_t begin, pair_iter_t end,
     845                 :            :                                                                     EntityHandle my_handle, AEntityFactory* adj )
     846                 :            : {
     847 [ +  + ][ +  + ]:        196 :     const size_t init_size = count < MeshSet::MANY ? (int)count : clist.ptr[1] - clist.ptr[0];
     848                 :        196 :     size_t add_size        = 0;
     849 [ +  - ][ +  - ]:        500 :     for( pair_iter_t i = begin; i != end; ++i )
         [ +  + ][ +  + ]
     850 [ +  - ][ +  - ]:        284 :         add_size += i->second - i->first + 1;
     851                 :        196 :     EntityHandle* list = resize_compact_list( count, clist, init_size + add_size );
     852                 :        196 :     EntityHandle* li   = list + init_size;
     853                 :            : 
     854 [ +  - ][ +  - ]:        500 :     for( pair_iter_t i = begin; i != end; ++i )
         [ +  + ][ +  + ]
     855                 :            :     {
     856 [ +  - ][ +  - ]:      16446 :         for( EntityHandle h = i->first; h <= i->second; ++h )
         [ +  + ][ +  + ]
     857                 :            :         {
     858 [ +  + ][ +  - ]:      16142 :             if( adj ) adj->add_adjacency( h, my_handle, false );
                 [ +  + ]
     859                 :      16142 :             *li = h;
     860                 :      16142 :             ++li;
     861                 :            :         }
     862                 :            :     }
     863                 :            : 
     864                 :        196 :     return MB_SUCCESS;
     865                 :            : }
     866                 :            : 
     867                 :         61 : static ErrorCode vector_remove_range( MeshSet::Count& count, MeshSet::CompactList& clist, const Range& range,
     868                 :            :                                       EntityHandle my_handle, AEntityFactory* adj )
     869                 :            : {
     870                 :            :     EntityHandle* list;
     871                 :            :     size_t list_size;
     872         [ +  + ]:         61 :     if( count < MeshSet::MANY )
     873                 :            :     {
     874                 :         10 :         list      = clist.hnd;
     875                 :         10 :         list_size = count;
     876                 :            :     }
     877                 :            :     else
     878                 :            :     {
     879                 :         51 :         list      = clist.ptr[0];
     880                 :         51 :         list_size = clist.ptr[1] - clist.ptr[0];
     881                 :            :     }
     882                 :            : 
     883                 :         61 :     const EntityHandle* const list_end = list + list_size;
     884                 :         61 :     EntityHandle* list_write           = list;
     885         [ +  + ]:      33775 :     for( const EntityHandle* list_read = list; list_read != list_end; ++list_read )
     886                 :            :     {
     887 [ +  - ][ +  - ]:      33714 :         if( range.find( *list_read ) == range.end() )
                 [ +  + ]
     888                 :            :         {  // keep
     889                 :      31223 :             *list_write = *list_read;
     890                 :      31223 :             ++list_write;
     891                 :            :         }
     892         [ +  + ]:       2491 :         else if( adj )
     893                 :            :         {
     894                 :       1246 :             adj->remove_adjacency( *list_read, my_handle );
     895                 :            :         }
     896                 :            :     }
     897                 :            : 
     898                 :         61 :     resize_compact_list( count, clist, list_write - list );
     899                 :         61 :     return MB_SUCCESS;
     900                 :            : }
     901                 :            : 
     902                 :          8 : static ErrorCode vector_remove_ranges( MeshSet::Count& count, MeshSet::CompactList& clist,
     903                 :            :                                        const EntityHandle* pair_list, size_t num_pairs, EntityHandle my_handle,
     904                 :            :                                        AEntityFactory* adj )
     905                 :            : {
     906                 :            :     EntityHandle* list;
     907                 :            :     size_t list_size;
     908         [ +  + ]:          8 :     if( count < MeshSet::MANY )
     909                 :            :     {
     910                 :          4 :         list      = clist.hnd;
     911                 :          4 :         list_size = count;
     912                 :            :     }
     913                 :            :     else
     914                 :            :     {
     915                 :          4 :         list      = clist.ptr[0];
     916                 :          4 :         list_size = clist.ptr[1] - clist.ptr[0];
     917                 :            :     }
     918                 :            : 
     919                 :          8 :     const EntityHandle *const list_end = list + list_size, *const input_end = pair_list + 2 * num_pairs;
     920                 :          8 :     EntityHandle* list_write = list;
     921         [ +  + ]:        856 :     for( const EntityHandle* list_read = list; list_read != list_end; ++list_read )
     922                 :            :     {
     923                 :        848 :         const EntityHandle* ptr = std::lower_bound( pair_list, input_end, *list_read );
     924 [ +  + ][ +  + ]:       1154 :         if( ( ptr != input_end && ( *ptr == *list_read || ( ptr - pair_list ) % 2 ) ) &&  // if in delete list
           [ +  +  +  - ]
                 [ +  + ]
     925                 :        306 :             std::find( list_read + 1, list_end, *list_read ) == list_end )
     926                 :            :         {  // and is last occurance in list
     927                 :            :             // only remove adj if no previous occurance
     928 [ +  + ][ +  - ]:        306 :             if( adj && std::find( list, list_write, *list_read ) == list_write )
                 [ +  + ]
     929                 :        153 :                 adj->remove_adjacency( *list_read, my_handle );
     930                 :            :         }
     931                 :            :         else
     932                 :            :         {
     933                 :        542 :             *list_write = *list_read;
     934                 :        542 :             ++list_write;
     935                 :            :         }
     936                 :            :     }
     937                 :            : 
     938                 :          8 :     resize_compact_list( count, clist, list_write - list );
     939                 :          8 :     return MB_SUCCESS;
     940                 :            : }
     941                 :            : 
     942                 :         31 : static ErrorCode vector_remove_vector( MeshSet::Count& count, MeshSet::CompactList& clist, const EntityHandle* vect,
     943                 :            :                                        size_t vect_size, EntityHandle my_handle, AEntityFactory* adj )
     944                 :            : {
     945                 :            :     EntityHandle* list;
     946                 :            :     size_t list_size;
     947         [ +  + ]:         31 :     if( count < MeshSet::MANY )
     948                 :            :     {
     949                 :          7 :         list      = clist.hnd;
     950                 :          7 :         list_size = count;
     951                 :            :     }
     952                 :            :     else
     953                 :            :     {
     954                 :         24 :         list      = clist.ptr[0];
     955                 :         24 :         list_size = clist.ptr[1] - clist.ptr[0];
     956                 :            :     }
     957                 :            : 
     958                 :         31 :     const EntityHandle *const list_end = list + list_size, *const input_end = vect + vect_size;
     959                 :         31 :     EntityHandle* list_write = list;
     960         [ +  + ]:       5938 :     for( const EntityHandle* list_read = list; list_read != list_end; ++list_read )
     961                 :            :     {
     962   [ +  +  +  - ]:       8640 :         if( std::find( vect, input_end, *list_read ) != input_end &&  // if in delete list
                 [ +  + ]
     963                 :       2733 :             std::find( list_read + 1, list_end, *list_read ) == list_end )
     964                 :            :         {  // and is last occurance in list
     965                 :            :             // only remove adj if no previous occurance?
     966         [ +  + ]:       2733 :             if( adj )  // && std::find(list, list_write, *list_read) == list_write)
     967                 :        409 :                 adj->remove_adjacency( *list_read, my_handle );
     968                 :            :         }
     969                 :            :         else
     970                 :            :         {
     971                 :       3174 :             *list_write = *list_read;
     972                 :       3174 :             ++list_write;
     973                 :            :         }
     974                 :            :     }
     975                 :            : 
     976                 :         31 :     resize_compact_list( count, clist, list_write - list );
     977                 :         31 :     return MB_SUCCESS;
     978                 :            : }
     979                 :            : 
     980                 :        576 : static ErrorCode vector_insert_vector( MeshSet::Count& count, MeshSet::CompactList& clist, const EntityHandle* vect,
     981                 :            :                                        size_t vect_size, EntityHandle my_handle, AEntityFactory* adj )
     982                 :            : {
     983         [ +  + ]:        576 :     const size_t orig_size = count < MeshSet::MANY ? (int)count : clist.ptr[1] - clist.ptr[0];
     984                 :        576 :     EntityHandle* list     = resize_compact_list( count, clist, orig_size + vect_size );
     985         [ +  + ]:        576 :     if( adj )
     986         [ +  + ]:       1475 :         for( size_t i = 0; i < vect_size; ++i )
     987                 :       1374 :             adj->add_adjacency( vect[i], my_handle, false );
     988                 :        576 :     memcpy( list + orig_size, vect, sizeof( EntityHandle ) * vect_size );
     989                 :        576 :     return MB_SUCCESS;
     990                 :            : }
     991                 :            : 
     992                 :         20 : ErrorCode MeshSet::insert_entity_ranges( const EntityHandle* range_vect, size_t len, EntityHandle my_h,
     993                 :            :                                          AEntityFactory* adj )
     994                 :            : {
     995                 :            :     typedef const std::pair< EntityHandle, EntityHandle >* pair_vect_t;
     996                 :         20 :     pair_vect_t pair_vect = reinterpret_cast< pair_vect_t >( range_vect );
     997                 :         20 :     MeshSet::Count count  = static_cast< MeshSet::Count >( mContentCount );
     998                 :            :     ErrorCode rval;
     999 [ +  - ][ +  + ]:         20 :     if( !vector_based() )
    1000                 :         12 :         rval = range_tool< pair_vect_t >::ranged_insert_entities( count, contentList, pair_vect, pair_vect + len / 2,
    1001 [ +  - ][ +  + ]:         12 :                                                                   my_h, tracking() ? adj : 0 );
                 [ +  - ]
    1002                 :            :     else
    1003                 :          8 :         rval = range_tool< pair_vect_t >::vector_insert_entities( count, contentList, pair_vect, pair_vect + len / 2,
    1004 [ +  - ][ +  + ]:          8 :                                                                   my_h, tracking() ? adj : 0 );
                 [ +  - ]
    1005                 :         20 :     mContentCount = count;
    1006                 :         20 :     return rval;
    1007                 :            : }
    1008                 :            : 
    1009                 :      19052 : ErrorCode MeshSet::insert_entity_ranges( const Range& range, EntityHandle my_h, AEntityFactory* adj )
    1010                 :            : {
    1011                 :            :     ErrorCode rval;
    1012                 :      19052 :     MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
    1013 [ +  - ][ +  + ]:      19052 :     if( !vector_based() )
    1014                 :            :         rval = range_tool< Range::const_pair_iterator >::ranged_insert_entities(
    1015 [ +  - ][ +  + ]:      18864 :             count, contentList, range.const_pair_begin(), range.const_pair_end(), my_h, tracking() ? adj : 0 );
         [ +  - ][ +  - ]
                 [ +  - ]
    1016                 :            :     else
    1017                 :            :         rval = range_tool< Range::const_pair_iterator >::vector_insert_entities(
    1018 [ +  - ][ +  + ]:        188 :             count, contentList, range.const_pair_begin(), range.const_pair_end(), my_h, tracking() ? adj : 0 );
         [ +  - ][ +  - ]
                 [ +  - ]
    1019                 :      19052 :     mContentCount = count;
    1020                 :      19052 :     return rval;
    1021                 :            : }
    1022                 :            : 
    1023                 :         23 : ErrorCode MeshSet::remove_entity_ranges( const EntityHandle* range_vect, size_t len, EntityHandle my_h,
    1024                 :            :                                          AEntityFactory* adj )
    1025                 :            : {
    1026                 :            :     ErrorCode rval;
    1027                 :         23 :     MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
    1028 [ +  - ][ +  + ]:         23 :     if( vector_based() )
    1029 [ +  - ][ +  + ]:          8 :         rval = vector_remove_ranges( count, contentList, range_vect, len / 2, my_h, tracking() ? adj : 0 );
                 [ +  - ]
    1030                 :            :     else
    1031                 :            :     {
    1032                 :            :         typedef const std::pair< EntityHandle, EntityHandle >* pair_vect_t;
    1033                 :         15 :         pair_vect_t pair_vect = reinterpret_cast< pair_vect_t >( range_vect );
    1034                 :         15 :         rval = range_tool< pair_vect_t >::ranged_remove_entities( count, contentList, pair_vect, pair_vect + len / 2,
    1035 [ +  - ][ +  + ]:         15 :                                                                   my_h, tracking() ? adj : 0 );
                 [ +  - ]
    1036                 :            :     }
    1037                 :         23 :     mContentCount = count;
    1038                 :         23 :     return rval;
    1039                 :            : }
    1040                 :            : 
    1041                 :        198 : ErrorCode MeshSet::remove_entity_ranges( const Range& range, EntityHandle my_h, AEntityFactory* adj )
    1042                 :            : {
    1043                 :            :     ErrorCode rval;
    1044                 :        198 :     MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
    1045 [ +  - ][ +  + ]:        198 :     if( vector_based() )
    1046 [ +  - ][ +  + ]:         61 :         rval = vector_remove_range( count, contentList, range, my_h, tracking() ? adj : 0 );
                 [ +  - ]
    1047                 :            :     else
    1048                 :            :         rval = range_tool< Range::const_pair_iterator >::ranged_remove_entities(
    1049 [ +  - ][ +  + ]:        137 :             count, contentList, range.const_pair_begin(), range.const_pair_end(), my_h, tracking() ? adj : 0 );
         [ +  - ][ +  - ]
                 [ +  - ]
    1050                 :        198 :     mContentCount = count;
    1051                 :        198 :     return rval;
    1052                 :            : }
    1053                 :            : 
    1054                 :         37 : ErrorCode MeshSet::intersect( const MeshSet* other, EntityHandle my_handle, AEntityFactory* adj )
    1055                 :            : {
    1056                 :            :     ErrorCode rval;
    1057 [ +  + ][ +  + ]:         37 :     if( !vector_based() && !other->vector_based() )
                 [ +  + ]
    1058                 :            :     {
    1059                 :         11 :         size_t other_count             = 0;
    1060         [ +  - ]:         11 :         const EntityHandle* other_vect = other->get_contents( other_count );
    1061 [ +  + ][ +  - ]:         11 :         if( !other_count ) return clear( my_handle, adj );
    1062         [ -  + ]:          5 :         assert( 0 == other_count % 2 );
    1063                 :            : 
    1064         [ +  - ]:          5 :         std::vector< EntityHandle > compliment;
    1065         [ +  - ]:          5 :         compliment.reserve( other_count + 4 );
    1066         [ +  - ]:          5 :         if( *other_vect > 0 )
    1067                 :            :         {
    1068         [ +  - ]:          5 :             compliment.push_back( 0 );
    1069         [ +  - ]:          5 :             compliment.push_back( *other_vect - 1 );
    1070                 :            :         }
    1071                 :          5 :         ++other_vect;
    1072                 :          5 :         const EntityHandle* const other_end = other_vect + other_count - 2;
    1073         [ +  + ]:         17 :         for( ; other_vect < other_end; other_vect += 2 )
    1074                 :            :         {
    1075         [ +  - ]:         12 :             compliment.push_back( other_vect[0] + 1 );
    1076         [ +  - ]:         12 :             compliment.push_back( other_vect[1] - 1 );
    1077                 :            :         }
    1078         [ +  - ]:          5 :         if( *other_vect < ~(EntityHandle)0 )
    1079                 :            :         {
    1080         [ +  - ]:          5 :             compliment.push_back( *other_vect + 1 );
    1081         [ +  - ]:          5 :             compliment.push_back( ~(EntityHandle)0 );
    1082                 :            :         }
    1083                 :            : 
    1084 [ +  - ][ +  - ]:         11 :         return remove_entity_ranges( &compliment[0], compliment.size(), my_handle, adj );
    1085                 :            :     }
    1086                 :            :     else
    1087                 :            :     {
    1088 [ +  - ][ +  - ]:         52 :         Range my_ents, other_ents;
    1089         [ +  - ]:         26 :         rval = get_entities( my_ents );
    1090         [ -  + ]:         26 :         if( MB_SUCCESS != rval ) return rval;
    1091         [ +  - ]:         26 :         rval = other->get_entities( other_ents );
    1092 [ +  - ][ +  - ]:         63 :         return remove_entities( moab::subtract( my_ents, other_ents ), my_handle, adj );
    1093                 :            :     }
    1094                 :            : }
    1095                 :            : 
    1096                 :      11208 : static void convert_to_ranges( const EntityHandle* vect_in, size_t vect_in_len, std::vector< EntityHandle >& vect_out )
    1097                 :            : {
    1098         [ +  - ]:      11208 :     vect_out.reserve( 2 * vect_in_len );
    1099         [ +  - ]:      11208 :     vect_out.resize( vect_in_len );
    1100         [ +  - ]:      11208 :     std::copy( vect_in, vect_in + vect_in_len, vect_out.begin() );
    1101         [ +  - ]:      11208 :     std::sort( vect_out.begin(), vect_out.end() );
    1102 [ +  - ][ +  - ]:      11208 :     vect_out.erase( std::unique( vect_out.begin(), vect_out.end() ), vect_out.end() );
    1103                 :            : 
    1104                 :            :     // duplicate all entries
    1105         [ +  - ]:      11208 :     vect_out.resize( vect_out.size() * 2 );
    1106         [ +  + ]:      67212 :     for( long i = vect_out.size() - 1; i >= 0; --i )
    1107 [ +  - ][ +  - ]:      56004 :         vect_out[i] = vect_out[i / 2];
    1108                 :            : 
    1109                 :            :     // compact adjacent ranges
    1110                 :      11208 :     std::vector< EntityHandle >::iterator r = vect_out.begin(), w = vect_out.begin();
    1111 [ +  - ][ +  + ]:      24779 :     while( r != vect_out.end() )
    1112                 :            :     {
    1113 [ +  - ][ +  - ]:      13571 :         *w = *r;
    1114         [ +  - ]:      13571 :         ++w;
    1115         [ +  - ]:      13571 :         ++r;
    1116 [ +  - ][ +  - ]:      13571 :         *w = *r;
    1117         [ +  - ]:      13571 :         ++r;
    1118                 :            : 
    1119 [ +  - ][ +  + ]:      28002 :         while( r != vect_out.end() && *w + 1 == *r )
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
           [ +  +  #  # ]
    1120                 :            :         {
    1121         [ +  - ]:      14431 :             ++r;
    1122 [ +  - ][ +  - ]:      14431 :             *w = *r;
    1123         [ +  - ]:      14431 :             ++r;
    1124                 :            :         }
    1125         [ +  - ]:      13571 :         ++w;
    1126                 :            :     }
    1127                 :            : 
    1128                 :            :     // remove extra space
    1129         [ +  - ]:      11208 :     vect_out.erase( w, vect_out.end() );
    1130                 :      11208 : }
    1131                 :            : 
    1132                 :      11593 : ErrorCode MeshSet::insert_entity_vector( const EntityHandle* vect, size_t len, EntityHandle my_h, AEntityFactory* adj )
    1133                 :            : {
    1134                 :      11593 :     MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
    1135                 :            :     ErrorCode rval;
    1136 [ +  - ][ +  + ]:      11593 :     if( vector_based() )
    1137 [ +  - ][ +  + ]:        576 :         rval = vector_insert_vector( count, contentList, vect, len, my_h, tracking() ? adj : 0 );
                 [ +  - ]
    1138                 :            :     else
    1139                 :            :     {
    1140         [ +  - ]:      11017 :         std::vector< EntityHandle > rangevect;
    1141         [ +  - ]:      11017 :         convert_to_ranges( vect, len, rangevect );
    1142                 :            :         typedef const std::pair< EntityHandle, EntityHandle >* pair_vect_t;
    1143 [ +  + ][ +  - ]:      11017 :         pair_vect_t pair_vect = ( rangevect.empty() ) ? NULL : reinterpret_cast< pair_vect_t >( &rangevect[0] );
    1144                 :            :         rval                  = range_tool< pair_vect_t >::ranged_insert_entities(
    1145 [ +  - ][ +  + ]:      11017 :             count, contentList, pair_vect, pair_vect + rangevect.size() / 2, my_h, tracking() ? adj : 0 );
                 [ +  - ]
    1146                 :            :     }
    1147                 :      11593 :     mContentCount = count;
    1148                 :      11593 :     return rval;
    1149                 :            : }
    1150                 :            : 
    1151                 :        221 : ErrorCode MeshSet::remove_entity_vector( const EntityHandle* vect, size_t len, EntityHandle my_h, AEntityFactory* adj )
    1152                 :            : {
    1153                 :        221 :     MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
    1154                 :            :     ErrorCode rval;
    1155 [ +  - ][ +  + ]:        221 :     if( vector_based() )
    1156 [ +  - ][ +  + ]:         31 :         rval = vector_remove_vector( count, contentList, vect, len, my_h, tracking() ? adj : 0 );
                 [ +  - ]
    1157                 :            :     else
    1158                 :            :     {
    1159         [ +  - ]:        190 :         std::vector< EntityHandle > rangevect;
    1160         [ +  - ]:        190 :         convert_to_ranges( vect, len, rangevect );
    1161                 :            :         typedef const std::pair< EntityHandle, EntityHandle >* pair_vect_t;
    1162 [ +  + ][ +  - ]:        190 :         pair_vect_t pair_vect = ( rangevect.empty() ) ? NULL : reinterpret_cast< pair_vect_t >( &rangevect[0] );
    1163                 :            :         rval                  = range_tool< pair_vect_t >::ranged_remove_entities(
    1164 [ +  - ][ +  + ]:        190 :             count, contentList, pair_vect, pair_vect + rangevect.size() / 2, my_h, tracking() ? adj : 0 );
                 [ +  - ]
    1165                 :            :     }
    1166                 :        221 :     mContentCount = count;
    1167                 :        221 :     return rval;
    1168                 :            : }
    1169                 :            : 
    1170                 :          6 : ErrorCode MeshSet::replace_entities( EntityHandle my_handle, const EntityHandle* old_entities,
    1171                 :            :                                      const EntityHandle* new_entities, size_t num_ents, AEntityFactory* adjfact )
    1172                 :            : {
    1173         [ +  + ]:          6 :     if( vector_based() )
    1174                 :            :     {
    1175                 :          5 :         ErrorCode result = MB_SUCCESS;
    1176                 :            :         size_t count;
    1177         [ +  - ]:          5 :         EntityHandle* vect           = get_contents( count );
    1178                 :          5 :         EntityHandle* const vect_end = vect + count;
    1179         [ +  + ]:         12 :         for( size_t i = 0; i < num_ents; ++i )
    1180                 :            :         {
    1181         [ +  - ]:          7 :             EntityHandle* p = std::find( vect, vect_end, old_entities[i] );
    1182         [ -  + ]:          7 :             if( p == vect_end ) { result = MB_ENTITY_NOT_FOUND; }
    1183                 :            :             else
    1184         [ +  + ]:          8 :                 do
    1185                 :            :                 {
    1186 [ +  - ][ +  + ]:          8 :                     if( tracking() )
    1187                 :            :                     {
    1188         [ +  - ]:          3 :                         adjfact->remove_adjacency( *p, my_handle );
    1189         [ +  - ]:          3 :                         adjfact->add_adjacency( new_entities[i], my_handle, false );
    1190                 :            :                     }
    1191                 :          8 :                     *p = new_entities[i];
    1192         [ +  - ]:          8 :                     p  = std::find( p + 1, vect_end, old_entities[i] );
    1193                 :            :                 } while( p != vect_end );
    1194                 :            :         }
    1195                 :          5 :         return result;
    1196                 :            :     }
    1197                 :            :     else
    1198                 :            :     {
    1199                 :          1 :         ErrorCode r1 = remove_entities( old_entities, num_ents, my_handle, adjfact );
    1200                 :          1 :         ErrorCode r2 = add_entities( new_entities, num_ents, my_handle, adjfact );
    1201         [ +  - ]:          6 :         return ( MB_SUCCESS == r2 ) ? r1 : r2;
    1202                 :            :     }
    1203                 :            : }
    1204                 :            : 
    1205                 :            : /*****************************************************************************************
    1206                 :            :  *                                  Misc. Methods                                        *
    1207                 :            :  *****************************************************************************************/
    1208                 :            : 
    1209                 :          0 : unsigned long MeshSet::get_memory_use() const
    1210                 :            : {
    1211                 :          0 :     unsigned long result = 0;
    1212         [ #  # ]:          0 :     if( mParentCount == MANY ) result += parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
    1213         [ #  # ]:          0 :     if( mChildCount == MANY ) result += childMeshSets.ptr[1] - childMeshSets.ptr[0];
    1214         [ #  # ]:          0 :     if( mContentCount == MANY ) result += contentList.ptr[1] - contentList.ptr[0];
    1215                 :          0 :     return sizeof( EntityHandle ) * result;
    1216                 :            : }
    1217                 :            : 
    1218 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11