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), index(0){};
 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:     void operator+=(const Point& q) {
 61:       this->prefix += q.prefix;
 62:       this->index  += q.index;
 63:     };
 64:     // Printing
 65:     friend std::ostream& operator<<(std::ostream& os, const Point& p) {
 66:       os << "(" << p.prefix << ", "<< p.index << ")";
 67:       return os;
 68:     };
 69:   };

 71:   template <typename Element_>
 72:   class array : public std::vector<Element_, ALE_ALLOCATOR<Element_> > {
 73:   public:
 74:     array()             : std::vector<Element_, ALE_ALLOCATOR<Element_> >(){};
 75:     array(int32_t size) : std::vector<Element_, ALE_ALLOCATOR<Element_> >(size){};
 76:     //
 77:     template <typename ostream_type>
 78:     void view(ostream_type& os, const char *name = NULL) {
 79:       os << "Viewing array";
 80:       if(name != NULL) {
 81:         os << " " << name;
 82:       }
 83:       os << " of size " << (int) this->size() << std::endl;
 84:       os << "[";
 85:       for(unsigned int cntr = 0; cntr < this->size(); cntr++) {
 86:         Element_ e = (*this)[cntr];
 87:         os << e;
 88:       }
 89:       os << " ]" << std::endl;
 90: 
 91:     };
 92:   };


 95:   template <typename Element_>
 96:   class set : public std::set<Element_, typename Element_::less_than,  ALE_ALLOCATOR<Element_> > {
 97:   public:
 98:     // Encapsulated types
 99:     typedef std::set<Element_, typename Element_::less_than, ALE_ALLOCATOR<Element_> > base_type;
100:     typedef typename base_type::iterator                                               iterator;
101:     // Basic interface
102:     set()        : std::set<Element_, typename Element_::less_than, ALE_ALLOCATOR<Element_> >(){};
103:     set(Point p) : std::set<Element_, typename Element_::less_than, ALE_ALLOCATOR<Element_> >(){insert(p);};
104:     // Redirection:
105:     // FIX: it is a little weird that methods aren't inheritec,
106:     //      but perhaps can be fixed by calling insert<Element_> (i.e., insert<Point> etc)?

108:     std::pair<iterator, bool>
109:     insert(const Element_& e) { return base_type::insert(e); };

111:     iterator
112:     insert(iterator position, const Element_& e) {return base_type::insert(position,e);};

114:     template <class InputIterator>
115:     void
116:     insert(InputIterator b, InputIterator e) { return base_type::insert(b,e);};

118: 
119:     // Extensions to std::set interface
120:     bool contains(const Element_& e) {return (this->find(e) != this->end());};
121:     void join(Obj<set> s) {
122:       for(iterator s_itor = s->begin(); s_itor != s->end(); s_itor++) {
123:         this->insert(*s_itor);
124:       }
125:     };
126:     void meet(Obj<set> s) {// this should be called 'intersect' (the verb)
127:       set removal;
128:       for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
129:         Element_ e = *self_itor;
130:         if(!s->contains(e)){
131:           removal.insert(e);
132:         }
133:       }
134:       for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
135:         Element_ ee = *rem_itor;
136:         this->erase(ee);
137:       }
138:     };
139:     void subtract(Obj<set> s) {
140:       set removal;
141:       for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
142:         Element_ e = *self_itor;
143:         if(s->contains(e)){
144:           removal.insert(e);
145:         }
146:       }
147:       for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
148:         Element_ ee = *rem_itor;
149:         this->erase(ee);
150:       }
151:     };

153:     //
154:     template <typename ostream_type>
155:     void view(ostream_type& os, const char *name = NULL) {
156:       os << "Viewing set";
157:       if(name != NULL) {
158:         os << " " << name;
159:       }
160:       os << " of size " << (int) this->size() << std::endl;
161:       os << "[";
162:       for(iterator s_itor = this->begin(); s_itor != this->end(); s_itor++) {
163:         Element_ e = *s_itor;
164:         os << e;
165:       }
166:       os << " ]" << std::endl;
167:     };
168:   };

170:   template <typename X>
171:   struct singleton {
172:     X first;
173:     //
174:     singleton(const X& x)         : first(x) {};
175:     singleton(const singleton& s) : first(s.first) {};
176:   };

178:   template <typename X, typename Y>
179:   struct pair : public std::pair<X,Y> {
180:     pair() : std::pair<X,Y>(){};
181:     pair(const pair& p) : std::pair<X,Y>(p.first, p.second) {};
182:     pair(const X& x, const Y& y) : std::pair<X,Y>(x,y) {};
183:     ~pair(){};
184:     friend std::ostream& operator<<(std::ostream& os, const pair& p) {
185:       os << "<" << p.first << ", "<< p.second << ">";
186:       return os;
187:     };
188:   };// struct pair

190:   //
191:   // Arrow definitions
192:   //
193:   template<typename Source_, typename Target_, typename Color_>
194:   struct  Arrow { //: public ALE::def::Arrow<Source_, Target_, Color_> {
195:     typedef Arrow   arrow_type;
196:     typedef Source_ source_type;
197:     typedef Target_ target_type;
198:     typedef Color_  color_type;
199:     source_type source;
200:     target_type target;
201:     color_type  color;
202:     // Arrow modifiers
203:     struct sourceChanger {
204:       sourceChanger(const source_type& newSource) : _newSource(newSource) {};
205:       void operator()(arrow_type& a) {a.source = this->_newSource;}
206:     private:
207:       source_type _newSource;
208:     };
209: 
210:     struct targetChanger {
211:       targetChanger(const target_type& newTarget) : _newTarget(newTarget) {};
212:       void operator()(arrow_type& a) { a.target = this->_newTarget;}
213:     private:
214:       const target_type _newTarget;
215:     };
216:     // Flipping
217:     template <typename OtherSource_, typename OtherTarget_, typename OtherColor_>
218:     struct rebind {
219:       typedef Arrow<OtherSource_, OtherTarget_, OtherColor_> type;
220:     };
221:     struct flip {
222:       typedef Arrow<target_type, source_type, color_type> type;
223:       type arrow(const arrow_type& a) { return type(a.target, a.source, a.color);};
224:     };
225:   public:
226:     //
227:     // Basic interface
228:     Arrow(const source_type& s, const target_type& t, const color_type& c) : source(s), target(t), color(c) {};
229:     Arrow(const Arrow& a) : source(a.source), target(a.target), color(a.color) {};
230:     ~Arrow(){};
231:     //
232:     // Extended interface
233:     // Printing
234:     template <typename Stream_>
235:     friend Stream_& operator<<(Stream_& os, const Arrow& a) {
236:       os << a.source << " --(" << a.color << ")--> " << a.target;
237:       return os;
238:     }
239:   };// struct Arrow

241:   // Defines a sequence representing a subset of a multi_index container Index_.
242:   // A sequence defines output (input in std terminology) iterators for traversing an Index_ object.
243:   // Upon dereferencing values are extracted from each result record using a ValueExtractor_ object.
244:   template <typename Index_, typename ValueExtractor_ = ::boost::multi_index::identity<typename Index_::value_type> >
245:   struct IndexSequence {
246:     typedef Index_                                   index_type;
247:     typedef ValueExtractor_                          extractor_type;
248:     //
249:     template <typename Sequence_ = IndexSequence>
250:     class iterator {
251:     public:
252:       // Parent sequence type
253:       typedef Sequence_                              sequence_type;
254:       // Standard iterator typedefs
255:       typedef std::input_iterator_tag                iterator_category;
256:       typedef typename extractor_type::result_type   value_type;
257:       typedef int                                    difference_type;
258:       typedef value_type*                            pointer;
259:       typedef value_type&                            reference;
260:       // Underlying iterator type
261:       typedef typename index_type::iterator          itor_type;
262:     protected:
263:       // Parent sequence
264:       sequence_type&  _sequence;
265:       // Underlying iterator
266:       itor_type      _itor;
267:       // Member extractor
268:       extractor_type _ex;
269:     public:
270:       iterator(sequence_type& sequence, itor_type itor)       : _sequence(sequence),_itor(itor) {};
271:       iterator(const iterator& iter)                          : _sequence(iter._sequence),_itor(iter._itor) {}
272:       virtual ~iterator() {};
273:       virtual bool              operator==(const iterator& iter) const {return this->_itor == iter._itor;};
274:       virtual bool              operator!=(const iterator& iter) const {return this->_itor != iter._itor;};
275:       // FIX: operator*() should return a const reference, but it won't compile that way, because _ex() returns const value_type
276:       virtual const value_type  operator*() const {return _ex(*(this->_itor));};
277:       virtual iterator   operator++() {++this->_itor; return *this;};
278:       virtual iterator   operator++(int n) {iterator tmp(*this); ++this->_itor; return tmp;};
279:     };// class iterator
280:   protected:
281:     index_type& _index;
282:   public:
283:     //
284:     // Basic interface
285:     //
286:     IndexSequence(const IndexSequence& seq)  : _index(seq._index) {};
287:     IndexSequence(index_type& index)         : _index(index) {};
288:     virtual ~IndexSequence() {};
289:     //
290:     // Extended interface
291:     //
292:     virtual bool         empty() {return this->_index.empty();};

294:     virtual typename index_type::size_type  size()  {
295:       typename index_type::size_type sz = 0;
296:       for(typename index_type::iterator itor = this->_index.begin(); itor != this->_index.end(); itor++) {
297:         ++sz;
298:       }
299:       return sz;
300:     };
301:     template<typename ostream_type>
302:     void view(ostream_type& os, const char* label = NULL){
303:       if(label != NULL) {
304:         os << "Viewing " << label << " sequence:" << std::endl;
305:       }
306:       os << "[";
307:       for(iterator<> i = this->begin(); i != this->end(); i++) {
308:         os << " "<< *i;
309:       }
310:       os << " ]" << std::endl;
311:     };
312:   };// class IndexSequence

314: } // namespace ALE


317: #endif