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