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 {
28: //
29: // This is a set of classes and class templates describing an interface to point containers.
30: //
31:
32: // Basic object
33: class Point {
34: public:
35: typedef ALE_ALLOCATOR<Point> allocator;
36: int32_t prefix, index;
37: // Constructors
38: Point() : prefix(0), index(0){};
39: Point(int p) : prefix(p){};
40: Point(int p, int i) : prefix(p), index(i){};
41: Point(const Point& p) : prefix(p.prefix), index(p.index){};
42: // Comparisons
43: class less_than {
44: public:
45: bool operator()(const Point& p, const Point& q) const {
46: return( (p.prefix < q.prefix) || ((p.prefix == q.prefix) && (p.index < q.index)));
47: };
48: };
49: typedef less_than Cmp;
50:
51: bool operator==(const Point& q) const {
52: return ( (this->prefix == q.prefix) && (this->index == q.index) );
53: };
54: bool operator!=(const Point& q) const {
55: return ( (this->prefix != q.prefix) || (this->index != q.index) );
56: };
57: bool operator<(const Point& q) const {
58: return( (this->prefix < q.prefix) || ((this->prefix == q.prefix) && (this->index < q.index)));
59: };
60: // Printing
61: friend std::ostream& operator<<(std::ostream& os, const Point& p) {
62: os << "(" << p.prefix << ", "<< p.index << ")";
63: return os;
64: };
65: };
67: template <typename Element_>
68: class array : public std::vector<Element_, ALE_ALLOCATOR<Element_> > {
69: public:
70: array() : std::vector<Element_, ALE_ALLOCATOR<Element_> >(){};
71: array(int32_t size) : std::vector<Element_, ALE_ALLOCATOR<Element_> >(size){};
72: //
73: template <typename ostream_type>
74: void view(ostream_type& os, const char *name = NULL) {
75: os << "Viewing array";
76: if(name != NULL) {
77: os << " " << name;
78: }
79: os << " of size " << (int) this->size() << std::endl;
80: os << "[";
81: for(unsigned int cntr = 0; cntr < this->size(); cntr++) {
82: Element_ e = (*this)[cntr];
83: os << e;
84: }
85: os << " ]" << std::endl;
86:
87: };
88: };
91: template <typename Element_>
92: class set : public std::set<Element_, typename Element_::less_than, ALE_ALLOCATOR<Element_> > {
93: public:
94: // Encapsulated types
95: typedef std::set<Element_, typename Element_::less_than, ALE_ALLOCATOR<Element_> > base_type;
96: typedef typename base_type::iterator iterator;
97: // Basic interface
98: set() : std::set<Element_, typename Element_::less_than, ALE_ALLOCATOR<Element_> >(){};
99: set(Point p) : std::set<Element_, typename Element_::less_than, ALE_ALLOCATOR<Element_> >(){insert(p);};
100: // Redirection:
101: // FIX: it is a little weird that methods aren't inheritec,
102: // but perhaps can be fixed by calling insert<Element_> (i.e., insert<Point> etc)?
104: std::pair<iterator, bool>
105: insert(const Element_& e) { return base_type::insert(e); };
107: iterator
108: insert(iterator position, const Element_& e) {return base_type::insert(position,e);};
110: template <class InputIterator>
111: void
112: insert(InputIterator b, InputIterator e) { return base_type::insert(b,e);};
114:
115: // Extensions to std::set interface
116: bool contains(const Element_& e) {return (this->find(e) != this->end());};
117: void join(Obj<set> s) {
118: for(iterator s_itor = s->begin(); s_itor != s->end(); s_itor++) {
119: this->insert(*s_itor);
120: }
121: };
122: void meet(Obj<set> s) {// this should be called 'intersect' (the verb)
123: set removal;
124: for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
125: Element_ e = *self_itor;
126: if(!s->contains(e)){
127: removal.insert(e);
128: }
129: }
130: for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
131: Element_ ee = *rem_itor;
132: this->erase(ee);
133: }
134: };
135: void subtract(Obj<set> s) {
136: set removal;
137: for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
138: Element_ e = *self_itor;
139: if(s->contains(e)){
140: removal.insert(e);
141: }
142: }
143: for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
144: Element_ ee = *rem_itor;
145: this->erase(ee);
146: }
147: };
149: //
150: template <typename ostream_type>
151: void view(ostream_type& os, const char *name = NULL) {
152: os << "Viewing set";
153: if(name != NULL) {
154: os << " " << name;
155: }
156: os << " of size " << (int) this->size() << std::endl;
157: os << "[";
158: for(iterator s_itor = this->begin(); s_itor != this->end(); s_itor++) {
159: Element_ e = *s_itor;
160: os << e;
161: }
162: os << " ]" << std::endl;
163: };
164: };
166: template <typename X, typename Y>
167: struct pair : public std::pair<X,Y> {
168: pair() : std::pair<X,Y>(){};
169: pair(const pair& p) : std::pair<X,Y>(p.first, p.second) {};
170: pair(const X& x, const Y& y) : std::pair<X,Y>(x,y) {};
171: ~pair(){};
172: friend std::ostream& operator<<(std::ostream& os, const pair& p) {
173: os << "<" << p.first << ", "<< p.second << ">";
174: return os;
175: };
176: };// struct pair
178: //
179: // Arrow definitions
180: //
181: template<typename Source_, typename Target_, typename Color_>
182: struct Arrow { //: public ALE::def::Arrow<Source_, Target_, Color_> {
183: typedef Arrow arrow_type;
184: typedef Source_ source_type;
185: typedef Target_ target_type;
186: typedef Color_ color_type;
187: source_type source;
188: target_type target;
189: color_type color;
190: // Arrow modifiers
191: struct sourceChanger {
192: sourceChanger(const source_type& newSource) : _newSource(newSource) {};
193: void operator()(arrow_type& a) {a.source = this->_newSource;}
194: private:
195: source_type _newSource;
196: };
197:
198: struct targetChanger {
199: targetChanger(const target_type& newTarget) : _newTarget(newTarget) {};
200: void operator()(arrow_type& a) { a.target = this->_newTarget;}
201: private:
202: const target_type _newTarget;
203: };
204: // Flipping
205: template <typename OtherSource_, typename OtherTarget_, typename OtherColor_>
206: struct rebind {
207: typedef Arrow<OtherSource_, OtherTarget_, OtherColor_> type;
208: };
209: struct flip {
210: typedef Arrow<target_type, source_type, color_type> type;
211: type arrow(const arrow_type& a) { return type(a.target, a.source, a.color);};
212: };
213: public:
214: //
215: // Basic interface
216: Arrow(const source_type& s, const target_type& t, const color_type& c) : source(s), target(t), color(c) {};
217: Arrow(const Arrow& a) : source(a.source), target(a.target), color(a.color) {};
218: ~Arrow(){};
219: //
220: // Extended interface
221: // Printing
222: template <typename Stream_>
223: friend Stream_& operator<<(Stream_& os, const Arrow& a) {
224: os << a.source << " --(" << a.color << ")--> " << a.target;
225: return os;
226: }
227: };// struct Arrow
229: // Defines a sequence representing a subset of a multi_index container Index_.
230: // A sequence defines output (input in std terminology) iterators for traversing an Index_ object.
231: // Upon dereferencing values are extracted from each result record using a ValueExtractor_ object.
232: template <typename Index_, typename ValueExtractor_ = ::boost::multi_index::identity<typename Index_::value_type> >
233: struct IndexSequence {
234: typedef Index_ index_type;
235: typedef ValueExtractor_ extractor_type;
236: //
237: template <typename Sequence_ = IndexSequence>
238: class iterator {
239: public:
240: // Parent sequence type
241: typedef Sequence_ sequence_type;
242: // Standard iterator typedefs
243: typedef std::input_iterator_tag iterator_category;
244: typedef typename extractor_type::result_type value_type;
245: typedef int difference_type;
246: typedef value_type* pointer;
247: typedef value_type& reference;
248: // Underlying iterator type
249: typedef typename index_type::iterator itor_type;
250: protected:
251: // Parent sequence
252: sequence_type& _sequence;
253: // Underlying iterator
254: itor_type _itor;
255: // Member extractor
256: extractor_type _ex;
257: public:
258: iterator(sequence_type& sequence, itor_type itor) : _sequence(sequence),_itor(itor) {};
259: iterator(const iterator& iter) : _sequence(iter._sequence),_itor(iter._itor) {}
260: virtual ~iterator() {};
261: virtual bool operator==(const iterator& iter) const {return this->_itor == iter._itor;};
262: virtual bool operator!=(const iterator& iter) const {return this->_itor != iter._itor;};
263: // FIX: operator*() should return a const reference, but it won't compile that way, because _ex() returns const value_type
264: virtual const value_type operator*() const {return _ex(*(this->_itor));};
265: virtual iterator operator++() {++this->_itor; return *this;};
266: virtual iterator operator++(int n) {iterator tmp(*this); ++this->_itor; return tmp;};
267: };// class iterator
268: protected:
269: index_type& _index;
270: public:
271: //
272: // Basic interface
273: //
274: IndexSequence(const IndexSequence& seq) : _index(seq._index) {};
275: IndexSequence(index_type& index) : _index(index) {};
276: virtual ~IndexSequence() {};
277: //
278: // Extended interface
279: //
280: virtual bool empty() {return this->_index.empty();};
282: virtual typename index_type::size_type size() {
283: typename index_type::size_type sz = 0;
284: for(typename index_type::iterator itor = this->_index.begin(); itor != this->_index.end(); itor++) {
285: ++sz;
286: }
287: return sz;
288: };
289: template<typename ostream_type>
290: void view(ostream_type& os, const char* label = NULL){
291: if(label != NULL) {
292: os << "Viewing " << label << " sequence:" << std::endl;
293: }
294: os << "[";
295: for(iterator<> i = this->begin(); i != this->end(); i++) {
296: os << " "<< *i;
297: }
298: os << " ]" << std::endl;
299: };
300: };// class IndexSequence
302: } // namespace ALE
305: #endif