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:     std::string _className;
 34:   protected:
 35:     void __init(MPI_Comm comm) {

 38:       this->_comm = comm;
 39:       MPI_Comm_rank(this->_comm, &this->_commRank); CHKERROR(ierr, "Error in MPI_Comm_rank");
 40:       MPI_Comm_size(this->_comm, &this->_commSize); CHKERROR(ierr, "Error in MPI_Comm_size");
 41:       const char *class_name = ALE::getClassName(this);
 42:       this->_className = class_name;
 43:       ALE::restoreClassName(this, class_name);
 44:     };
 45:   public:
 46:     ParallelObject(MPI_Comm comm = PETSC_COMM_SELF, const int debug = 0) : _debug(debug) {__init(comm);}
 47:     ~ParallelObject() {};
 48:   public:
 49:     int                debug()    const {return this->_debug;};
 50:     void               setDebug(const int debug) {this->_debug = debug;};
 51:     MPI_Comm           comm()     const {return this->_comm;};
 52:     int                commSize() const {return this->_commSize;};
 53:     int                commRank() const {return this->_commRank;}
 54:     const std::string& getName() const {return this->_name;};
 55:     void               setName(const std::string& name) {this->_name = name;};
 56:     const std::string& getClassName() const {return this->_className;};
 57:     void               setClassName(const std::string& name) {this->_className = name;};
 58:   public:
 59:     void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
 60:       ostringstream txt;
 61:       int           rank;

 63:       if (comm == MPI_COMM_NULL) {
 64:         comm = this->comm();
 65:         rank = this->commRank();
 66:       } else {
 67:         MPI_Comm_rank(comm, &rank);
 68:       }
 69:       if (name == "") {
 70:         if(rank == 0) {
 71:           txt << "viewing a " << this->getClassName() << std::endl;
 72:         }
 73:       } else {
 74:         if(rank == 0) {
 75:           txt << "viewing " << this->getClassName() << " '" << name << "'" << std::endl;
 76:         }
 77:       }
 78:       PetscSynchronizedPrintf(comm, txt.str().c_str());
 79:       PetscSynchronizedFlush(comm);
 80:     };
 81:   };

 83:   // Use for ArrowSections
 84:   template<typename Source_, typename Target_>
 85:   struct MinimalArrow {
 86:     typedef Source_ source_type;
 87:     typedef Target_ target_type;
 88:     source_type source;
 89:     target_type target;
 90:     MinimalArrow() {};
 91:     MinimalArrow(const source_type& source, const target_type& target) : source(source), target(target) {};
 92:     MinimalArrow(const MinimalArrow& a) : source(a.source), target(a.target) {};
 93:     friend std::ostream& operator<<(std::ostream& os, const MinimalArrow& a) {
 94:       os << a.source << " ----> " << a.target;
 95:       return os;
 96:     }
 97:     // Comparisons
 98:     class less_than {
 99:     public:
100:       bool operator()(const MinimalArrow& p, const MinimalArrow& q) const {
101:         return((p.source < q.source) || ((p.source == q.source) && (p.target < q.target)));
102:       };
103:     };
104:     typedef less_than Cmp;
105:     bool operator==(const MinimalArrow& q) const {
106:       return((this->source == q.source) && (this->target == q.target));
107:     };
108:     bool operator!=(const MinimalArrow& q) const {
109:       return((this->source != q.source) || (this->target != q.target));
110:     };
111:     bool operator<(const MinimalArrow& q) const {
112:       return((this->source < q.source) || ((this->source == q.source) && (this->target < q.target)));
113:     };
114:   };

116:   //
117:   // This is a set of classes and class templates describing an interface to point containers.
118:   //
119: 
120:   // Basic object
121:   class Point {
122:   public:
123:     typedef ALE_ALLOCATOR<Point> allocator;
124:     typedef int32_t prefix_type;
125:     typedef int32_t index_type;
126:     prefix_type prefix;
127:     index_type  index;
128:     // Constructors
129:     Point() : prefix(0), index(0){};
130:     Point(int p) : prefix(p), index(0){};
131:     Point(int p, int i) : prefix(p), index(i){};
132:     Point(const Point& p) : prefix(p.prefix), index(p.index){};
133:     // Comparisons
134:     class less_than {
135:     public:
136:       bool operator()(const Point& p, const Point& q) const {
137:         return( (p.prefix < q.prefix) || ((p.prefix == q.prefix) && (p.index < q.index)));
138:       };
139:     };
140:     typedef less_than Cmp;
141: 
142:     bool operator==(const Point& q) const {
143:       return ( (this->prefix == q.prefix) && (this->index == q.index) );
144:     };
145:     bool operator!=(const Point& q) const {
146:       return ( (this->prefix != q.prefix) || (this->index != q.index) );
147:     };
148:     bool operator<(const Point& q) const {
149:       return( (this->prefix < q.prefix) || ((this->prefix == q.prefix) && (this->index < q.index)));
150:     };
151:     void operator+=(const Point& q) {
152:       this->prefix += q.prefix;
153:       this->index  += q.index;
154:     };
155:     // Printing
156:     friend std::ostream& operator<<(std::ostream& os, const Point& p) {
157:       os << "(" << p.prefix << ", "<< p.index << ")";
158:       return os;
159:     };
160:   };
161:   template<typename FirstType, typename SecondType>
162:   class Pair {
163:   public:
164:     typedef FirstType  first_type;
165:     typedef SecondType second_type;
166:     first_type  first;
167:     second_type second;
168:     // Constructors
169:     Pair() : first(0), second(0) {};
170:     Pair(FirstType f) : first(f), second(0) {};
171:     Pair(FirstType f, SecondType s) : first(f), second(s) {};
172:     Pair(const Pair& p) : first(p.first), second(p.second) {};
173:     // Comparisons
174:     class less_than {
175:     public:
176:       bool operator()(const Pair& p, const Pair& q) const {
177:         return( (p.first < q.first) || ((p.first == q.first) && (p.second < q.second)));
178:       };
179:     };
180:     typedef less_than Cmp;
181: 
182:     bool operator==(const Pair& q) const {
183:       return((this->first == q.first) && (this->second == q.second));
184:     };
185:     bool operator!=(const Pair& q) const {
186:       return((this->first != q.first) || (this->second != q.second));
187:     };
188:     bool operator<(const Pair& q) const {
189:       return((this->first < q.first) || ((this->first == q.first) && (this->second < q.second)));
190:     };
191:     void operator+=(const Pair& q) {
192:       this->first  += q.first;
193:       this->second += q.second;
194:     };
195:     // Printing
196:     friend std::ostream& operator<<(std::ostream& os, const Pair& p) {
197:       os << "(" << p.first << ", "<< p.second << ")";
198:       return os;
199:     };
200:   };

202:   template <typename Element_>
203:   class array : public std::vector<Element_, ALE_ALLOCATOR<Element_> > {
204:   public:
205:     array()             : std::vector<Element_, ALE_ALLOCATOR<Element_> >(){};
206:     array(int32_t size) : std::vector<Element_, ALE_ALLOCATOR<Element_> >(size){};
207:     //
208:     template <typename ostream_type>
209:     void view(ostream_type& os, const char *name = NULL) {
210:       os << "Viewing array";
211:       if(name != NULL) {
212:         os << " " << name;
213:       }
214:       os << " of size " << (int) this->size() << std::endl;
215:       os << "[";
216:       for(unsigned int cntr = 0; cntr < this->size(); cntr++) {
217:         Element_ e = (*this)[cntr];
218:         os << e;
219:       }
220:       os << " ]" << std::endl;
221: 
222:     };
223:   };


226:   template <typename Element_>
227:   class set : public std::set<Element_, typename Element_::less_than,  ALE_ALLOCATOR<Element_> > {
228:   public:
229:     // Encapsulated types
230:     typedef std::set<Element_, typename Element_::less_than, ALE_ALLOCATOR<Element_> > super;
231:     typedef typename super::iterator                                                   iterator;
232:     typedef Element_                                                                   element_type;
233:     typedef element_type                                                               value_type;
234:     //
235:     // Basic interface
236:     //
237:     set()        : super(){};
238:     // FIX: this is a little weird that there is a specific constructor with Point
239:     set(Point p) : super(){insert(p);};
240:     //
241:     set(const element_type& e) : super() {insert(e);}
242:     //
243:     template<typename ElementSequence_>
244:     set(const ElementSequence_& eseq) : super(eseq.begin(), eseq.end()){};
245:     //
246:     // Standard interface
247:     //
248:     // Redirection:
249:     // FIX: it is a little weird that 'insert' methods aren't inherited
250:     //      but perhaps can be fixed by calling insert<Element_> (i.e., insert<Point> etc)?
251:         std::pair<iterator, bool>
252:     inline insert(const Element_& e) { return super::insert(e); };
253:     //
254:     iterator
255:     inline insert(iterator position, const Element_& e) {return super::insert(position,e);};
256:     //
257:     template <class InputIterator>
258:     void
259:     inline insert(InputIterator b, InputIterator e) { return super::insert(b,e);};
260:     //
261:     // Extended interface
262:     //
263:     inline iterator last() {
264:       return this->rbegin();
265:     };// last()
266:     //
267:     inline bool contains(const Element_& e) {return (this->find(e) != this->end());};
268:     //
269:     inline void join(Obj<set> s) {
270:       for(iterator s_itor = s->begin(); s_itor != s->end(); s_itor++) {
271:         this->insert(*s_itor);
272:       }
273:     };
274:     //
275:     inline void meet(Obj<set> s) {// this should be called 'intersect' (the verb)
276:       set removal;
277:       for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
278:         Element_ e = *self_itor;
279:         if(!s->contains(e)){
280:           removal.insert(e);
281:         }
282:       }
283:       for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
284:         Element_ ee = *rem_itor;
285:         this->erase(ee);
286:       }
287:     };
288:     //
289:     inline void subtract(Obj<set> s) {
290:       set removal;
291:       for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
292:         Element_ e = *self_itor;
293:         if(s->contains(e)){
294:           removal.insert(e);
295:         }
296:       }
297:       for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
298:         Element_ ee = *rem_itor;
299:         this->erase(ee);
300:       }
301:     };
302:     //
303:     template <typename ostream_type>
304:     void view(ostream_type& os, const char *name = NULL) {
305:       os << "Viewing set";
306:       if(name != NULL) {
307:         os << " " << name;
308:       }
309:       os << " of size " << (int) this->size() << std::endl;
310:       os << "[";
311:       for(iterator s_itor = this->begin(); s_itor != this->end(); s_itor++) {
312:         Element_ e = *s_itor;
313:         os << e;
314:       }
315:       os << " ]" << std::endl;
316:     };
317:   };

319:   template <typename X>
320:   struct singleton {
321:     X first;
322:     //
323:     singleton(const X& x)         : first(x) {};
324:     singleton(const singleton& s) : first(s.first) {};
325:   };

327:   template <typename X, typename Y>
328:   struct pair : public std::pair<X,Y> {
329:     pair() : std::pair<X,Y>(){};
330:     pair(const pair& p) : std::pair<X,Y>(p.first, p.second) {};
331:     pair(const X& x, const Y& y) : std::pair<X,Y>(x,y) {};
332:     ~pair(){};
333:     friend std::ostream& operator<<(std::ostream& os, const pair& p) {
334:       os << "<" << p.first << ", "<< p.second << ">";
335:       return os;
336:     };
337:   };// struct pair

339:   //
340:   // Arrow definitions
341:   //
342:   template<typename Source_, typename Target_, typename Color_>
343:   struct  Arrow { //: public ALE::def::Arrow<Source_, Target_, Color_> {
344:     typedef Arrow   arrow_type;
345:     typedef Source_ source_type;
346:     typedef Target_ target_type;
347:     typedef Color_  color_type;
348:     source_type source;
349:     target_type target;
350:     color_type  color;
351:     // Arrow modifiers
352:     struct sourceChanger {
353:       sourceChanger(const source_type& newSource) : _newSource(newSource) {};
354:       void operator()(arrow_type& a) {a.source = this->_newSource;}
355:     private:
356:       source_type _newSource;
357:     };
358: 
359:     struct targetChanger {
360:       targetChanger(const target_type& newTarget) : _newTarget(newTarget) {};
361:       void operator()(arrow_type& a) { a.target = this->_newTarget;}
362:     private:
363:       const target_type _newTarget;
364:     };
365:     // Flipping
366:     template <typename OtherSource_, typename OtherTarget_, typename OtherColor_>
367:     struct rebind {
368:       typedef Arrow<OtherSource_, OtherTarget_, OtherColor_> type;
369:     };
370:     struct flip {
371:       typedef Arrow<target_type, source_type, color_type> type;
372:       type arrow(const arrow_type& a) { return type(a.target, a.source, a.color);};
373:     };
374:   public:
375:     //
376:     // Basic interface
377:     Arrow(const source_type& s, const target_type& t, const color_type& c) : source(s), target(t), color(c) {};
378:     Arrow(const Arrow& a) : source(a.source), target(a.target), color(a.color) {};
379:     ~Arrow(){};
380:     //
381:     // Extended interface
382:     // Printing
383:     template <typename Stream_>
384:     friend Stream_& operator<<(Stream_& os, const Arrow& a) {
385:       os << a.source << " --(" << a.color << ")--> " << a.target;
386:       return os;
387:     }
388:   };// struct Arrow

390:   // Defines a sequence representing a subset of a multi_index container Index_.
391:   // A sequence defines output (input in std terminology) iterators for traversing an Index_ object.
392:   // Upon dereferencing values are extracted from each result record using a ValueExtractor_ object.
393:   template <typename Index_, typename ValueExtractor_ = ::boost::multi_index::identity<typename Index_::value_type> >
394:   struct IndexSequence {
395:     typedef Index_                                   index_type;
396:     typedef ValueExtractor_                          extractor_type;
397:     //
398:     template <typename Sequence_ = IndexSequence>
399:     class iterator {
400:     public:
401:       // Parent sequence type
402:       typedef Sequence_                              sequence_type;
403:       // Standard iterator typedefs
404:       typedef std::input_iterator_tag                iterator_category;
405:       typedef typename extractor_type::result_type   value_type;
406:       typedef int                                    difference_type;
407:       typedef value_type*                            pointer;
408:       typedef value_type&                            reference;
409:       // Underlying iterator type
410:       typedef typename index_type::iterator          itor_type;
411:     protected:
412:       // Parent sequence
413:       sequence_type&  _sequence;
414:       // Underlying iterator
415:       itor_type      _itor;
416:       // Member extractor
417:       extractor_type _ex;
418:     public:
419:       iterator(sequence_type& sequence, itor_type itor)       : _sequence(sequence),_itor(itor) {};
420:       iterator(const iterator& iter)                          : _sequence(iter._sequence),_itor(iter._itor) {}
421:       virtual ~iterator() {};
422:       virtual bool              operator==(const iterator& iter) const {return this->_itor == iter._itor;};
423:       virtual bool              operator!=(const iterator& iter) const {return this->_itor != iter._itor;};
424:       // FIX: operator*() should return a const reference, but it won't compile that way, because _ex() returns const value_type
425:       virtual const value_type  operator*() const {return _ex(*(this->_itor));};
426:       virtual iterator   operator++() {++this->_itor; return *this;};
427:       virtual iterator   operator++(int n) {iterator tmp(*this); ++this->_itor; return tmp;};
428:     };// class iterator
429:   protected:
430:     index_type& _index;
431:   public:
432:     //
433:     // Basic interface
434:     //
435:     IndexSequence(const IndexSequence& seq)  : _index(seq._index) {};
436:     IndexSequence(index_type& index)         : _index(index) {};
437:     virtual ~IndexSequence() {};
438:     //
439:     // Extended interface
440:     //
441:     virtual bool         empty() {return this->_index.empty();};

443:     virtual typename index_type::size_type  size()  {
444:       typename index_type::size_type sz = 0;
445:       for(typename index_type::iterator itor = this->_index.begin(); itor != this->_index.end(); itor++) {
446:         ++sz;
447:       }
448:       return sz;
449:     };
450:     template<typename ostream_type>
451:     void view(ostream_type& os, const char* label = NULL){
452:       if(label != NULL) {
453:         os << "Viewing " << label << " sequence:" << std::endl;
454:       }
455:       os << "[";
456:       for(iterator<> i = this->begin(); i != this->end(); i++) {
457:         os << " "<< *i;
458:       }
459:       os << " ]" << std::endl;
460:     };
461:   };// class IndexSequence

463: } // namespace ALE


466: #endif