Actual source code: X.hh

  1: #ifndef included_ALE_X_hh
  2: #define included_ALE_X_hh

  4: // BEGIN: these includes come from boost/multi_index/mem_fun.hpp
  5: #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  6: #include <boost/mpl/if.hpp>
  7: #include <boost/type_traits/remove_reference.hpp>
  8: // END


 11: #include <boost/multi_index_container.hpp>
 12: #include <boost/multi_index/key_extractors.hpp>
 13: #include <boost/multi_index/ordered_index.hpp>
 14: #include <boost/multi_index/composite_key.hpp>

 16: #include <boost/lambda/lambda.hpp>
 17: using namespace ::boost::lambda;

 19: #include <iostream>


 22: #include <ALE.hh>

 24: namespace ALE {
 25:   //
 26:   class XObject {
 27:   public:
 28:     XObject() {};
 29:     XObject(const XObject& xobject) {};
 30:   };// class XObject
 31:   //
 32:   class XParallelObject : public XObject {
 33:   protected:
 34:     MPI_Comm _comm;
 35:     int      _commRank, _commSize;
 36:   protected:
 37:     void __setupComm(const MPI_Comm& comm) {
 38:       this->_comm = comm;
 40:       MPI_Comm_size(this->_comm, &this->_commSize); CHKERROR(ierr, "Error in MPI_Comm_size");
 41:       MPI_Comm_rank(this->_comm, &this->_commRank); CHKERROR(ierr, "Error in MPI_Comm_rank");
 42:     }
 43:   public:
 44:     XParallelObject(const MPI_Comm& comm = PETSC_COMM_WORLD) : XObject()      {this->__setupComm(comm);};
 45:     XParallelObject(const XParallelObject& xpobject)         : XObject(xpobject), _comm(xpobject._comm) {};
 46:     //
 47:     MPI_Comm comm()     {return this->_comm;};
 48:     int      commSize() {return this->_commSize;};
 49:     int      commRank() {return this->_commRank;};
 50:   };// class XParallelObject
 51: 
 52:   //
 53:   // Key extractors
 54:   //
 55:   //
 56:   // The following member function return a const result.
 57:   // It is best used through the macro ALE_CONST_MEM_FUN which takes only three arguments:
 58:   //  Class, ResultType, MemberFunctionPtr (see below).
 59:   // OutputType (the actual return type) is different from the ResultType for somewhat obscure reasons.
 60:   // Once I (have time to) understand the issue better, the usage pattern may get simplified.
 61:   template<class InputType_, typename ResultType_, typename OutputType_, OutputType_ (InputType_::*PtrToMemberFunction)()const>
 62:   struct const_const_mem_fun
 63:   {
 64:     typedef InputType_                                            input_type;
 65:     typedef typename ::boost::remove_reference<ResultType_>::type result_type;
 66:     typedef OutputType_                                           output_type;
 67:     //
 68:     // Main interface
 69:     //
 70:     template<typename ChainedPtrTarget>
 71:     output_type operator()(const ChainedPtrTarget*& x)const
 72:     {
 73:       return operator()((*x));
 74:     }
 75: 
 76:     output_type operator()(const input_type& x)const
 77:     {
 78:       return (x.*PtrToMemberFunction)();
 79:     }
 80: 
 81:     output_type operator()(const ::boost::reference_wrapper<const input_type>& x)const
 82:     {
 83:       return operator()(x.get());
 84:     }
 85: 
 86:     output_type operator()(const ::boost::reference_wrapper<input_type>& x,int=0)const
 87:     {
 88:       return operator()(x.get());
 89:     }
 90:   };// struct const_const_mem_fun
 91: #define ALE_CONST_MEM_FUN(CLASS, RESULT_TYPE, FUN) ::ALE::const_const_mem_fun<CLASS, RESULT_TYPE, const RESULT_TYPE, FUN>

 93: #ifdef ALE_USE_DEBUGGING
 94:   //   Xdebug and Xcodebug might have confusing interpretations, but the usage should be relatively transparent.
 95:   // X sets the number of debugging layers laid so far -- ALE_XDEBUG_HEIGHT -- laid chronologically --
 96:   // with the oldest layers laid first and having the lowest numbers: 1,2,etc.
 97:   //   Now, debug works from the top of the debugging layers, and codebug works from the bottom:
 98:   // Setting '--debug N' will activate N LAST layers of debuggin: if a routine has its __ALE_XDEBUG__
 99:   // within N of the top, its debugging will be activated.
100:   // Likewise, setting '--codebug N' will activate the first N layers of debugging,
101:   // which is not what the developer usually want.
102:   // Hence, 'debug' is made to have the more common meaning.
103:   static int Xdebug   = 0;
104:   static int Xcodebug = 0;
105:   // Debugging works from the top: setting ALE::XSifterDef::debug to n will 'uncover' the *last* (newest) n layers of debugging.
106:   // Thus, the functions with the n heighest __ALE_DEBUG__ markers will produce debugging output.
107:   // Co-debugging works from the bottom: setting ALE::XSifterDef::codebug to n will 'uncover' the *first* (oldest) n layers of debugging.
108:   // Thus, the functions with the n lowest __ALE_DEBUG__ markers will produce debugging output.
109: #endif 

111: #define ALE_XDEBUG_HEIGHT 7
112: #define ALE_XDEBUG_LEVEL(n)  ((ALE::Xcodebug >= n) || (n > ALE_XDEBUG_HEIGHT - ALE::Xdebug))
113: #define ALE_XDEBUG           (ALE_XDEBUG_LEVEL(__ALE_XDEBUG__))

115: 

117:   template <typename Element_>
118:   struct SetElementTraits {
119:     typedef Element_ element_type;
120:     typedef typename std::template less<element_type> less_than;
121:   };

123:   template <typename Argument_>
124:   struct NoOp {
125:     typedef Argument_ argument_type;
126:     void operator()(const argument_type& arg) const{};
127:   };// struct NoOp

129:   template <typename Element_, typename Traits_ = SetElementTraits<Element_> , typename Allocator_ = ALE_ALLOCATOR<Element_> >
130:   class Set : public std::set<Element_, typename Traits_::less_than, Allocator_ > {
131:   public:
132:     // Encapsulated types
133:     typedef typename std::set<Element_, typename Traits_::less_than, Allocator_>       super;
134:     typedef Set                                                                        set_type;
135:     typedef Element_                                                                   element_type;
136:     typedef Traits_                                                                    element_traits;
137:     typedef typename super::iterator                                                   iterator;
138:     typedef element_type                                                               value_type;
139:     //
140:     // Standard
141:     //
142:     // making constructors explicit may prevent ambiguous application of operators, such as operator<<
143:     Set()                               : super(){};
144:     explicit Set(const element_type& e) : super() {insert(e);}     //
145:     template<typename ElementSequence_>
146:     explicit Set(const ElementSequence_& eseq) : super(eseq.begin(), eseq.end()){};
147:     //
148:     // Main
149:     //
150:     // Redirection:
151:     // FIX: it is a little weird that 'insert' methods aren't inherited
152:     // but perhaps can be fixed by calling insert<Element_> (i.e., insert<Point> etc)?
153:     std::pair<iterator, bool>
154:     inline insert(const Element_& e) { return super::insert(e); };
155:     //
156:     iterator
157:     inline insert(iterator position, const Element_& e) {return super::insert(position,e);};
158:     //
159:     template <class InputIterator>
160:     void
161:     inline insert(InputIterator b, InputIterator e) { return super::insert(b,e);};
162:     //
163:     // Extended interface
164:     //
165:     inline iterator last() {
166:       return this->rbegin();
167:     };// last()
168:     //
169:     inline bool contains(const Element_& e) {return (this->find(e) != this->end());};
170:     //
171:     inline void join(const Set& s) {
172:       for(iterator s_itor = s.begin(); s_itor != s.end(); s_itor++) {
173:         this->insert(*s_itor);
174:       }
175:     };
176:     inline void join(const Obj<Set>& s) { this->join(s->object());};
177:     //
178:     inline void meet(const Set& s) {// this should be called 'intersect' (the verb)
179:       Set removal;
180:       for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
181:         Element_ e = *self_itor;
182:         if(!s.contains(e)){
183:           removal.insert(e);
184:         }
185:       }
186:       for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
187:         Element_ ee = *rem_itor;
188:         this->erase(ee);
189:       }
190:     };
191:     inline void meet(const Obj<Set>& s) { this->meet(s.object());};
192:     //
193:     inline void subtract(const Set& s) {
194:       Set removal;
195:       for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
196:         Element_ e = *self_itor;
197:         if(s->contains(e)){
198:           removal.insert(e);
199:         }
200:       }
201:       for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
202:         Element_ ee = *rem_itor;
203:         this->erase(ee);
204:       }
205:     };
206:     inline void subtract(const Obj<Set>& s) {this->subtract(s.object());};
207:     //
208:     template <typename Op_>
209:     inline void traverse(const Op_& op) {
210:       for(iterator iter = this->begin(); iter!= this->end(); ++iter) {
211:         op(*iter);
212:       }
213:     };
214:     //
215:     template <typename ostream_type>
216:     friend ostream_type& operator<<(ostream_type& os, const Set& s) {
217:       os << "[[ ";
218:       for(iterator s_itor = s.begin(); s_itor != s.end(); s_itor++) {
219:         Element_ e = *s_itor;
220:         os << e << " ";
221:       }
222:       os << " ]]";
223:       return os;
224:     };
225:     //
226:     template <typename ostream_type>
227:     void view(ostream_type& os, const char *name = NULL) {
228:       os << "Viewing set";
229:       if(name != NULL) {
230:         os << " " << name;
231:       }
232:       os << " of size " << (int) this->size() << std::endl;
233:       os << *this << "\n";
234:     };
235:   };
236: }//namespace ALE

238: #endif