Actual source code: ALE_containers.hh

  1: #ifndef included_ALE_containers_hh
  2: #define included_ALE_containers_hh
  3: // This should be included indirectly -- only by including ALE.hh

  5: #include <boost/multi_index_container.hpp>
  6: #include <boost/multi_index/member.hpp>
  7: #include <boost/multi_index/ordered_index.hpp>
  8: #include <boost/multi_index/composite_key.hpp>

 10: #include <iostream>
 11: #include <map>
 12: #include <set>
 13: #include <vector>

 15: #ifndef  included_ALE_exception_hh
 16: #include <ALE_exception.hh>
 17: #endif
 18: #ifndef  included_ALE_mem_hh
 19: #include <ALE_mem.hh>
 20: #endif
 21: #ifndef  included_ALE_log_hh
 22: #include <ALE_log.hh>
 23: #endif

 25: namespace ALE {
 26:   class ParallelObject {
 27:   protected:
 28:     int         _debug;
 29:     MPI_Comm    _comm;
 30:     int         _commRank;
 31:     int         _commSize;
 32:     std::string _name;
 33:     PetscObject _petscObj;
 34:     void __init(MPI_Comm comm) {
 35:       static PetscCookie objType = -1;
 36:       //const char        *id_name = ALE::getClassName<T>();
 37:       const char        *id_name = "ParallelObject";
 38:       PetscErrorCode     ierr;

 40:       if (objType < 0) {
 41:         PetscLogClassRegister(&objType, id_name);CHKERROR(ierr, "Error in PetscLogClassRegister");
 42:       }
 43:       this->_comm = comm;
 44:       MPI_Comm_rank(this->_comm, &this->_commRank); CHKERROR(ierr, "Error in MPI_Comm_rank");
 45:       MPI_Comm_size(this->_comm, &this->_commSize); CHKERROR(ierr, "Error in MPI_Comm_size");
 46: #ifdef USE_PETSC_OBJ
 47:       PetscObjectCreateGeneric(this->_comm, objType, id_name, &this->_petscObj);CHKERROR(ierr, "Error in PetscObjectCreate");
 48: #endif
 49:       //ALE::restoreClassName<T>(id_name);
 50:     };
 51:   public:
 52:     ParallelObject(MPI_Comm comm = PETSC_COMM_SELF, const int debug = 0) : _debug(debug), _petscObj(NULL) {__init(comm);}
 53:     virtual ~ParallelObject() {
 54: #ifdef USE_PETSC_OBJ
 55:       if (this->_petscObj) {
 56:         PetscErrorCode PetscObjectDestroy(this->_petscObj); CHKERROR(ierr, "Failed in PetscObjectDestroy");
 57:         this->_petscObj = NULL;
 58:       }
 59: #endif
 60:     };
 61:   public:
 62:     int                debug()    const {return this->_debug;};
 63:     void               setDebug(const int debug) {this->_debug = debug;};
 64:     MPI_Comm           comm()     const {return this->_comm;};
 65:     int                commSize() const {return this->_commSize;};
 66:     int                commRank() const {return this->_commRank;}
 67: #ifdef USE_PETSC_OBJ
 68:     PetscObject        petscObj() const {return this->_petscObj;};
 69: #endif
 70:     const std::string& getName() const {return this->_name;};
 71:     void               setName(const std::string& name) {this->_name = name;};
 72:   };

 74:   // Use for ArrowSections
 75:   template<typename Source_, typename Target_>
 76:   struct MinimalArrow {
 77:     typedef Source_ source_type;
 78:     typedef Target_ target_type;
 79:     source_type source;
 80:     target_type target;
 81:     MinimalArrow() {};
 82:     MinimalArrow(const source_type& source, const target_type& target) : source(source), target(target) {};
 83:     MinimalArrow(const MinimalArrow& a) : source(a.source), target(a.target) {};
 84:     friend std::ostream& operator<<(std::ostream& os, const MinimalArrow& a) {
 85:       os << a.source << " ----> " << a.target;
 86:       return os;
 87:     }
 88:     // Comparisons
 89:     class less_than {
 90:     public:
 91:       bool operator()(const MinimalArrow& p, const MinimalArrow& q) const {
 92:         return((p.source < q.source) || ((p.source == q.source) && (p.target < q.target)));
 93:       };
 94:     };
 95:     typedef less_than Cmp;
 96:     bool operator==(const MinimalArrow& q) const {
 97:       return((this->source == q.source) && (this->target == q.target));
 98:     };
 99:     bool operator!=(const MinimalArrow& q) const {
100:       return((this->source != q.source) || (this->target != q.target));
101:     };
102:     bool operator<(const MinimalArrow& q) const {
103:       return((this->source < q.source) || ((this->source == q.source) && (this->target < q.target)));
104:     };
105:   };

107:   //
108:   // This is a set of classes and class templates describing an interface to point containers.
109:   //
110: 
111:   // Basic object
112:   class Point {
113:   public:
114:     typedef ALE_ALLOCATOR<Point> allocator;
115:     typedef int32_t prefix_type;
116:     typedef int32_t index_type;
117:     prefix_type prefix;
118:     index_type  index;
119:     // Constructors
120:     Point() : prefix(0), index(0){};
121:     Point(int p) : prefix(p), index(0){};
122:     Point(int p, int i) : prefix(p), index(i){};
123:     Point(const Point& p) : prefix(p.prefix), index(p.index){};
124:     // Comparisons
125:     class less_than {
126:     public:
127:       bool operator()(const Point& p, const Point& q) const {
128:         return( (p.prefix < q.prefix) || ((p.prefix == q.prefix) && (p.index < q.index)));
129:       };
130:     };
131:     typedef less_than Cmp;
132: 
133:     bool operator==(const Point& q) const {
134:       return ( (this->prefix == q.prefix) && (this->index == q.index) );
135:     };
136:     bool operator!=(const Point& q) const {
137:       return ( (this->prefix != q.prefix) || (this->index != q.index) );
138:     };
139:     bool operator<(const Point& q) const {
140:       return( (this->prefix < q.prefix) || ((this->prefix == q.prefix) && (this->index < q.index)));
141:     };
142:     void operator+=(const Point& q) {
143:       this->prefix += q.prefix;
144:       this->index  += q.index;
145:     };
146:     // Printing
147:     friend std::ostream& operator<<(std::ostream& os, const Point& p) {
148:       os << "(" << p.prefix << ", "<< p.index << ")";
149:       return os;
150:     };
151:   };

153:   template <typename Element_>
154:   class array : public std::vector<Element_, ALE_ALLOCATOR<Element_> > {
155:   public:
156:     array()             : std::vector<Element_, ALE_ALLOCATOR<Element_> >(){};
157:     array(int32_t size) : std::vector<Element_, ALE_ALLOCATOR<Element_> >(size){};
158:     //
159:     template <typename ostream_type>
160:     void view(ostream_type& os, const char *name = NULL) {
161:       os << "Viewing array";
162:       if(name != NULL) {
163:         os << " " << name;
164:       }
165:       os << " of size " << (int) this->size() << std::endl;
166:       os << "[";
167:       for(unsigned int cntr = 0; cntr < this->size(); cntr++) {
168:         Element_ e = (*this)[cntr];
169:         os << e;
170:       }
171:       os << " ]" << std::endl;
172: 
173:     };
174:   };


177:   template <typename Element_>
178:   class set : public std::set<Element_, typename Element_::less_than,  ALE_ALLOCATOR<Element_> > {
179:   public:
180:     // Encapsulated types
181:     typedef std::set<Element_, typename Element_::less_than, ALE_ALLOCATOR<Element_> > super;
182:     typedef typename super::iterator                                                   iterator;
183:     typedef Element_                                                                   element_type;
184:     typedef element_type                                                               value_type;
185:     //
186:     // Basic interface
187:     //
188:     set()        : super(){};
189:     // FIX: this is a little weird that there is a specific constructor with Point
190:     set(Point p) : super(){insert(p);};
191:     //
192:     set(const element_type& e) : super() {insert(e);}
193:     //
194:     template<typename ElementSequence_>
195:     set(const ElementSequence_& eseq) : super(eseq.begin(), eseq.end()){};
196:     //
197:     // Standard interface
198:     //
199:     // Redirection:
200:     // FIX: it is a little weird that 'insert' methods aren't inherited
201:     //      but perhaps can be fixed by calling insert<Element_> (i.e., insert<Point> etc)?
202:         std::pair<iterator, bool>
203:     inline insert(const Element_& e) { return super::insert(e); };
204:     //
205:     iterator
206:     inline insert(iterator position, const Element_& e) {return super::insert(position,e);};
207:     //
208:     template <class InputIterator>
209:     void
210:     inline insert(InputIterator b, InputIterator e) { return super::insert(b,e);};
211:     //
212:     // Extended interface
213:     //
214:     inline iterator last() {
215:       return this->rbegin();
216:     };// last()
217:     //
218:     inline bool contains(const Element_& e) {return (this->find(e) != this->end());};
219:     //
220:     inline void join(Obj<set> s) {
221:       for(iterator s_itor = s->begin(); s_itor != s->end(); s_itor++) {
222:         this->insert(*s_itor);
223:       }
224:     };
225:     //
226:     inline void meet(Obj<set> s) {// this should be called 'intersect' (the verb)
227:       set removal;
228:       for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
229:         Element_ e = *self_itor;
230:         if(!s->contains(e)){
231:           removal.insert(e);
232:         }
233:       }
234:       for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
235:         Element_ ee = *rem_itor;
236:         this->erase(ee);
237:       }
238:     };
239:     //
240:     inline void subtract(Obj<set> s) {
241:       set removal;
242:       for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
243:         Element_ e = *self_itor;
244:         if(s->contains(e)){
245:           removal.insert(e);
246:         }
247:       }
248:       for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
249:         Element_ ee = *rem_itor;
250:         this->erase(ee);
251:       }
252:     };
253:     //
254:     template <typename ostream_type>
255:     void view(ostream_type& os, const char *name = NULL) {
256:       os << "Viewing set";
257:       if(name != NULL) {
258:         os << " " << name;
259:       }
260:       os << " of size " << (int) this->size() << std::endl;
261:       os << "[";
262:       for(iterator s_itor = this->begin(); s_itor != this->end(); s_itor++) {
263:         Element_ e = *s_itor;
264:         os << e;
265:       }
266:       os << " ]" << std::endl;
267:     };
268:   };

270:   template <typename X>
271:   struct singleton {
272:     X first;
273:     //
274:     singleton(const X& x)         : first(x) {};
275:     singleton(const singleton& s) : first(s.first) {};
276:   };

278:   template <typename X, typename Y>
279:   struct pair : public std::pair<X,Y> {
280:     pair() : std::pair<X,Y>(){};
281:     pair(const pair& p) : std::pair<X,Y>(p.first, p.second) {};
282:     pair(const X& x, const Y& y) : std::pair<X,Y>(x,y) {};
283:     ~pair(){};
284:     friend std::ostream& operator<<(std::ostream& os, const pair& p) {
285:       os << "<" << p.first << ", "<< p.second << ">";
286:       return os;
287:     };
288:   };// struct pair

290:   //
291:   // Arrow definitions
292:   //
293:   template<typename Source_, typename Target_, typename Color_>
294:   struct  Arrow { //: public ALE::def::Arrow<Source_, Target_, Color_> {
295:     typedef Arrow   arrow_type;
296:     typedef Source_ source_type;
297:     typedef Target_ target_type;
298:     typedef Color_  color_type;
299:     source_type source;
300:     target_type target;
301:     color_type  color;
302:     // Arrow modifiers
303:     struct sourceChanger {
304:       sourceChanger(const source_type& newSource) : _newSource(newSource) {};
305:       void operator()(arrow_type& a) {a.source = this->_newSource;}
306:     private:
307:       source_type _newSource;
308:     };
309: 
310:     struct targetChanger {
311:       targetChanger(const target_type& newTarget) : _newTarget(newTarget) {};
312:       void operator()(arrow_type& a) { a.target = this->_newTarget;}
313:     private:
314:       const target_type _newTarget;
315:     };
316:     // Flipping
317:     template <typename OtherSource_, typename OtherTarget_, typename OtherColor_>
318:     struct rebind {
319:       typedef Arrow<OtherSource_, OtherTarget_, OtherColor_> type;
320:     };
321:     struct flip {
322:       typedef Arrow<target_type, source_type, color_type> type;
323:       type arrow(const arrow_type& a) { return type(a.target, a.source, a.color);};
324:     };
325:   public:
326:     //
327:     // Basic interface
328:     Arrow(const source_type& s, const target_type& t, const color_type& c) : source(s), target(t), color(c) {};
329:     Arrow(const Arrow& a) : source(a.source), target(a.target), color(a.color) {};
330:     ~Arrow(){};
331:     //
332:     // Extended interface
333:     // Printing
334:     template <typename Stream_>
335:     friend Stream_& operator<<(Stream_& os, const Arrow& a) {
336:       os << a.source << " --(" << a.color << ")--> " << a.target;
337:       return os;
338:     }
339:   };// struct Arrow

341:   // Defines a sequence representing a subset of a multi_index container Index_.
342:   // A sequence defines output (input in std terminology) iterators for traversing an Index_ object.
343:   // Upon dereferencing values are extracted from each result record using a ValueExtractor_ object.
344:   template <typename Index_, typename ValueExtractor_ = ::boost::multi_index::identity<typename Index_::value_type> >
345:   struct IndexSequence {
346:     typedef Index_                                   index_type;
347:     typedef ValueExtractor_                          extractor_type;
348:     //
349:     template <typename Sequence_ = IndexSequence>
350:     class iterator {
351:     public:
352:       // Parent sequence type
353:       typedef Sequence_                              sequence_type;
354:       // Standard iterator typedefs
355:       typedef std::input_iterator_tag                iterator_category;
356:       typedef typename extractor_type::result_type   value_type;
357:       typedef int                                    difference_type;
358:       typedef value_type*                            pointer;
359:       typedef value_type&                            reference;
360:       // Underlying iterator type
361:       typedef typename index_type::iterator          itor_type;
362:     protected:
363:       // Parent sequence
364:       sequence_type&  _sequence;
365:       // Underlying iterator
366:       itor_type      _itor;
367:       // Member extractor
368:       extractor_type _ex;
369:     public:
370:       iterator(sequence_type& sequence, itor_type itor)       : _sequence(sequence),_itor(itor) {};
371:       iterator(const iterator& iter)                          : _sequence(iter._sequence),_itor(iter._itor) {}
372:       virtual ~iterator() {};
373:       virtual bool              operator==(const iterator& iter) const {return this->_itor == iter._itor;};
374:       virtual bool              operator!=(const iterator& iter) const {return this->_itor != iter._itor;};
375:       // FIX: operator*() should return a const reference, but it won't compile that way, because _ex() returns const value_type
376:       virtual const value_type  operator*() const {return _ex(*(this->_itor));};
377:       virtual iterator   operator++() {++this->_itor; return *this;};
378:       virtual iterator   operator++(int n) {iterator tmp(*this); ++this->_itor; return tmp;};
379:     };// class iterator
380:   protected:
381:     index_type& _index;
382:   public:
383:     //
384:     // Basic interface
385:     //
386:     IndexSequence(const IndexSequence& seq)  : _index(seq._index) {};
387:     IndexSequence(index_type& index)         : _index(index) {};
388:     virtual ~IndexSequence() {};
389:     //
390:     // Extended interface
391:     //
392:     virtual bool         empty() {return this->_index.empty();};

394:     virtual typename index_type::size_type  size()  {
395:       typename index_type::size_type sz = 0;
396:       for(typename index_type::iterator itor = this->_index.begin(); itor != this->_index.end(); itor++) {
397:         ++sz;
398:       }
399:       return sz;
400:     };
401:     template<typename ostream_type>
402:     void view(ostream_type& os, const char* label = NULL){
403:       if(label != NULL) {
404:         os << "Viewing " << label << " sequence:" << std::endl;
405:       }
406:       os << "[";
407:       for(iterator<> i = this->begin(); i != this->end(); i++) {
408:         os << " "<< *i;
409:       }
410:       os << " ]" << std::endl;
411:     };
412:   };// class IndexSequence

414: } // namespace ALE


417: #endif