Branch data Line data Source code
1 : : #ifndef MOAB_MB_ITER_HPP
2 : : #define MOAB_MB_ITER_HPP
3 : :
4 : : #define IS_BUILDING_MB
5 : : #include "Internals.hpp"
6 : : #include "moab/Range.hpp"
7 : : #include "moab/Core.hpp"
8 : : #include <vector>
9 : : #include <algorithm>
10 : :
11 : : struct iBase_EntityArrIterator_Private
12 : : {
13 : : protected:
14 : : iBase_EntityType entType;
15 : : iMesh_EntityTopology entTopo;
16 : : EntityHandle entSet;
17 : : int arrSize;
18 : : bool isRecursive;
19 : :
20 : : public:
21 : 96 : iBase_EntityArrIterator_Private( iBase_EntityType type, iMesh_EntityTopology topology, EntityHandle set,
22 : : int array_sz, bool recursive = false )
23 : 96 : : entType( type ), entTopo( topology ), entSet( set ), arrSize( array_sz ), isRecursive( recursive )
24 : : {
25 : 96 : }
26 : :
27 [ - + ]: 192 : virtual ~iBase_EntityArrIterator_Private() {}
28 : :
29 : 52894 : int array_size() const
30 : : {
31 : 52894 : return arrSize;
32 : : }
33 : :
34 : : virtual ErrorCode step( int num_steps, bool& at_end ) = 0;
35 : :
36 : : // NOTE: input array must be at least arrLen long
37 : : virtual void get_entities( Core* mb, EntityHandle* array, int& count_out ) = 0;
38 : :
39 : : virtual ErrorCode reset( Interface* mb ) = 0;
40 : :
41 : : class IsType
42 : : {
43 : : private:
44 : : EntityType type;
45 : :
46 : : public:
47 : 6 : IsType( EntityType t ) : type( t ) {}
48 : 5994 : bool operator()( EntityHandle h )
49 : : {
50 : 5994 : return TYPE_FROM_HANDLE( h ) == type;
51 : : }
52 : : };
53 : :
54 : 6 : void remove_type( std::vector< EntityHandle >& vect, EntityType t )
55 : : {
56 [ + - ][ + - ]: 6 : vect.erase( std::remove_if( vect.begin(), vect.end(), IsType( t ) ), vect.end() );
57 : 6 : }
58 : :
59 : 20 : void remove_type( Range& range, EntityType t )
60 : : {
61 [ + - ]: 20 : std::pair< Range::iterator, Range::iterator > p = range.equal_range( t );
62 [ + - ]: 20 : range.erase( p.first, p.second );
63 : 20 : }
64 : : };
65 : :
66 : : // step_iterator will safely step forward N steps in a iterator. We specialize
67 : : // for random-access iterators (vectors and Ranges) so that they perform better.
68 : :
69 : : template < typename T >
70 : 0 : inline ErrorCode step_iterator( T& curr, const T& end, int num_steps, bool& at_end )
71 : : {
72 [ # # ]: 0 : if( 0 > num_steps ) return MB_FAILURE;
73 : :
74 [ # # ][ # # ]: 0 : while( num_steps && curr != end )
[ # # ]
75 : : {
76 : 0 : num_steps--;
77 : 0 : curr++;
78 : : }
79 : 0 : at_end = ( curr == end );
80 : 0 : return MB_SUCCESS;
81 : : }
82 : :
83 : : template < typename T >
84 : : inline ErrorCode step_iterator( typename std::vector< T >::const_iterator& curr,
85 : : const typename std::vector< T >::const_iterator& end, int num_steps, bool& at_end )
86 : : {
87 : : if( 0 > num_steps ) return MB_FAILURE;
88 : :
89 : : assert( curr <= end ); // Sanity check
90 : : at_end = ( end - curr <= num_steps );
91 : :
92 : : if( at_end )
93 : : curr = end;
94 : : else
95 : : curr += num_steps;
96 : : return MB_SUCCESS;
97 : : }
98 : :
99 : 6 : inline ErrorCode step_iterator( Range::const_iterator& curr, const Range::const_iterator& end, int num_steps,
100 : : bool& at_end )
101 : : {
102 [ - + ]: 6 : if( 0 > num_steps ) return MB_FAILURE;
103 : :
104 : 6 : at_end = ( end - curr <= num_steps );
105 : :
106 [ + + ]: 6 : if( at_end )
107 : 3 : curr = end;
108 : : else
109 : 3 : curr += num_steps;
110 : 6 : return MB_SUCCESS;
111 : : }
112 : :
113 : : template < class Container >
114 : : class MBIter : public iBase_EntityArrIterator_Private
115 : : {
116 : : protected:
117 : : Container iterData;
118 : : typename Container::const_iterator iterPos;
119 : :
120 : : public:
121 : 96 : MBIter( iBase_EntityType type, iMesh_EntityTopology topology, EntityHandle set, int arr_size,
122 : : bool recursive = false )
123 [ + - ][ + - ]: 96 : : iBase_EntityArrIterator_Private( type, topology, set, arr_size, recursive ), iterPos( iterData.end() )
[ + - ][ + - ]
[ # ][ # # ]
[ # # ]
124 : : {
125 : 96 : }
126 : :
127 [ - + ][ - + ]: 384 : ~MBIter() {}
128 : :
129 : 5 : typename Container::const_iterator position() const
130 : : {
131 : 5 : return iterPos;
132 : : };
133 : :
134 : 11 : typename Container::const_iterator end() const
135 : : {
136 : 11 : return iterData.end();
137 : : };
138 : :
139 : 6 : ErrorCode step( int num_steps, bool& at_end )
140 : : {
141 [ + - ][ # # ]: 6 : return step_iterator( iterPos, end(), num_steps, at_end );
142 : : }
143 : :
144 : 52894 : void get_entities( Core* mb, EntityHandle* array, int& count )
145 : : {
146 [ + + ][ + - ]: 135518 : for( count = 0; count < arrSize && iterPos != iterData.end(); ++iterPos )
[ + - ][ + + ]
[ + + ]
[ + + # # ]
[ + + ][ + - ]
[ + + ][ + + ]
[ + + # # ]
[ # ][ # # ]
[ # # # # ]
[ # # ][ # ]
147 [ + - ][ + - ]: 82624 : if( mb->is_valid( *iterPos ) ) array[count++] = *iterPos;
148 : 52894 : }
149 : :
150 : 276 : virtual ErrorCode reset( Interface* mb )
151 : : {
152 : : ErrorCode result;
153 : 276 : iterData.clear();
154 [ + + + + ]: 276 : if( entTopo != iMesh_ALL_TOPOLOGIES )
155 : : {
156 [ + + ][ + + ]: 200 : if( entTopo == iMesh_SEPTAHEDRON )
157 : 18 : result = MB_SUCCESS;
158 : : else
159 : 200 : result = mb->get_entities_by_type( entSet, mb_topology_table[entTopo], iterData, isRecursive );
160 : : }
161 [ + + ][ + - ]: 76 : else if( entType != iBase_ALL_TYPES )
162 : : {
163 : 72 : result = mb->get_entities_by_dimension( entSet, entType, iterData, isRecursive );
164 [ + + ][ + + ]: 72 : if( entType == iBase_REGION ) remove_type( iterData, MBKNIFE );
165 : : }
166 : : else
167 : : {
168 : 4 : result = mb->get_entities_by_handle( entSet, iterData, isRecursive );
169 : 4 : remove_type( iterData, MBENTITYSET );
170 : 4 : remove_type( iterData, MBKNIFE );
171 : : }
172 [ + - ]: 276 : iterPos = iterData.begin();
173 : 276 : return result;
174 : : }
175 : : };
176 : :
177 : : typedef MBIter< std::vector< EntityHandle > > MBListIter;
178 : : typedef MBIter< moab::Range > MBRangeIter;
179 : :
180 : : #endif
|