moab
MBIter.hpp
Go to the documentation of this file.
00001 #ifndef MOAB_MB_ITER_HPP
00002 #define MOAB_MB_ITER_HPP
00003 
00004 #define IS_BUILDING_MB
00005 #include "Internals.hpp"
00006 #include "moab/Range.hpp"
00007 #include "moab/Core.hpp"
00008 #include <vector>
00009 #include <algorithm>
00010 
00011 struct iBase_EntityArrIterator_Private 
00012 {
00013   protected:
00014     iBase_EntityType entType;
00015     iMesh_EntityTopology entTopo;
00016     EntityHandle entSet;
00017     int arrSize;
00018     bool isRecursive;
00019     
00020   public:
00021     iBase_EntityArrIterator_Private( iBase_EntityType type,
00022                                      iMesh_EntityTopology topology,
00023                                      EntityHandle set,
00024                                      int array_sz,
00025                                      bool recursive = false)
00026             : entType(type), entTopo(topology), entSet(set), arrSize(array_sz), isRecursive(recursive)
00027       {}
00028 
00029     virtual ~iBase_EntityArrIterator_Private() {}
00030 
00031     int array_size() const { return arrSize; }
00032 
00033   virtual ErrorCode step(int num_steps, bool &at_end)=0;
00034 
00035     // NOTE: input array must be at least arrLen long
00036     virtual void get_entities( Core* mb, 
00037                                EntityHandle* array,
00038                                int& count_out ) = 0;
00039     
00040     virtual ErrorCode reset( Interface* mb ) = 0;
00041     
00042     class IsType { 
00043       private: EntityType type;
00044       public:  IsType( EntityType t ) : type(t) {}
00045                bool operator()( EntityHandle h )
00046                  { return TYPE_FROM_HANDLE(h) == type; }
00047     };
00048 
00049     void remove_type( std::vector<EntityHandle>& vect, EntityType t ) {
00050       vect.erase( std::remove_if( vect.begin(), vect.end(), IsType(t) ), vect.end() );
00051     }
00052     
00053     void remove_type( Range& range, EntityType t ) {
00054       std::pair<Range::iterator,Range::iterator> p = range.equal_range(t);
00055       range.erase( p.first, p.second );
00056     }
00057 };
00058 
00059 // step_iterator will safely step forward N steps in a iterator. We specialize
00060 // for random-access iterators (vectors and Ranges) so that they perform better.
00061 
00062 template <typename T>
00063 inline
00064 ErrorCode step_iterator(T &curr, const T &end, int num_steps, bool &at_end) 
00065 {
00066   if (0 > num_steps) return MB_FAILURE;
00067 
00068   while (num_steps && curr != end) {
00069     num_steps--;
00070     curr++;
00071   }
00072   at_end = (curr == end);
00073   return MB_SUCCESS;
00074 }
00075 
00076 template <typename T>
00077 inline
00078 ErrorCode step_iterator(typename std::vector<T>::const_iterator &curr,
00079                         const typename std::vector<T>::const_iterator &end,
00080                         int num_steps, bool &at_end) 
00081 {
00082   if (0 > num_steps) return MB_FAILURE;
00083 
00084   assert(curr <= end); // Sanity check
00085   at_end = (end - curr <= num_steps);
00086 
00087   if (at_end)
00088     curr = end;
00089   else
00090     curr += num_steps;
00091   return MB_SUCCESS;
00092 }
00093 
00094 inline
00095 ErrorCode step_iterator(Range::const_iterator &curr, 
00096                         const Range::const_iterator &end, int num_steps,
00097                         bool &at_end) 
00098 {
00099   if (0 > num_steps) return MB_FAILURE;
00100 
00101   at_end = (end - curr <= num_steps);
00102 
00103   if (at_end)
00104     curr = end;
00105   else
00106     curr += num_steps;
00107   return MB_SUCCESS;
00108 }
00109 
00110 template <class Container> class MBIter : public iBase_EntityArrIterator_Private 
00111 {
00112   protected:
00113     Container iterData;
00114     typename Container::const_iterator iterPos;
00115       
00116   public:
00117     MBIter( iBase_EntityType type,
00118             iMesh_EntityTopology topology,
00119             EntityHandle set,
00120             int arr_size,
00121             bool recursive = false)
00122             : iBase_EntityArrIterator_Private( type, topology, set, arr_size, recursive ),
00123         iterPos(iterData.end()) {}
00124       
00125     ~MBIter() {}
00126 
00127     typename Container::const_iterator position() const {return iterPos;};
00128 
00129     typename Container::const_iterator end() const {return iterData.end();};
00130 
00131     ErrorCode step(int num_steps, bool &at_end)
00132     {
00133       return step_iterator(iterPos, end(), num_steps, at_end);
00134     }
00135     
00136     void get_entities( Core* mb, EntityHandle* array, int& count )
00137     {
00138       for (count = 0; count < arrSize && iterPos != iterData.end(); ++iterPos)
00139         if (mb->is_valid(*iterPos))
00140           array[count++] = *iterPos;
00141     }
00142       
00143     virtual ErrorCode reset( Interface* mb ) {
00144       ErrorCode result;
00145       iterData.clear();
00146       if (entTopo != iMesh_ALL_TOPOLOGIES) {
00147         if (entTopo == iMesh_SEPTAHEDRON)
00148           result = MB_SUCCESS;
00149         else
00150           result = mb->get_entities_by_type( entSet, mb_topology_table[entTopo], iterData, isRecursive );
00151       }
00152       else if (entType != iBase_ALL_TYPES) {
00153         result = mb->get_entities_by_dimension( entSet, entType, iterData, isRecursive );
00154         if (entType == iBase_REGION)
00155           remove_type( iterData, MBKNIFE );
00156       }
00157       else {
00158         result = mb->get_entities_by_handle( entSet, iterData, isRecursive );
00159         remove_type( iterData, MBENTITYSET );
00160         remove_type( iterData, MBKNIFE );
00161       }
00162       iterPos = iterData.begin();
00163       return result;
00164     }  
00165 };
00166 
00167 typedef MBIter< std::vector<EntityHandle> > MBListIter;
00168 typedef MBIter< moab::Range > MBRangeIter;
00169 
00170 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines