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