Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/valop

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_valop
  5 #define tools_valop
  6 
  7 #include "ival_func"
  8 
  9 namespace tools {
 10 
 11 class valop {
 12   static const std::string& s_class() {
 13     static const std::string s_v("tools::valop");
 14     return s_v;
 15   }
 16 public:
 17   enum e_type {
 18     CMP_GT = 1,
 19     CMP_GE = 2,
 20     CMP_LT = 3,
 21     CMP_LE = 4,
 22     CMP_EQ = 5,
 23     CMP_NE = 6,
 24     CMP_AND = 7,
 25     CMP_OR = 8,
 26 
 27     ADD = 9,
 28     MUL = 10,
 29     SUB = 11,
 30     DIV = 12,
 31 
 32     ASSIGN = 13,
 33     MINUS = 14,
 34     UNSIGNED_INTEGER = 15,
 35     REAL = 16,
 36     NAME = 17,
 37     STRING = 18,
 38     //PI = 19,
 39     FUNC = 20,
 40     BOOL_TRUE = 21,
 41     BOOL_FALSE = 22,
 42     NOT = 23,
 43     // math edition :
 44     SYMBOL = 100,
 45     ASIDE = 101,
 46     NVMUL = 102, //not visible mul
 47     EQUAL = 103,
 48     SUPS = 104,  //super script
 49     SUBS = 105   //sub script
 50   };
 51 
 52 public:
 53   static bool is_binary(e_type a_type) {
 54     switch(a_type) {
 55     case CMP_GT:
 56     case CMP_GE:
 57     case CMP_LT:
 58     case CMP_LE:
 59     case CMP_EQ:
 60     case CMP_NE:
 61     case CMP_AND:
 62     case CMP_OR:
 63 
 64     case ADD:
 65     case MUL:
 66     case SUB:
 67     case DIV:
 68 
 69     case ASIDE:
 70     case NVMUL:
 71     case EQUAL:
 72     case SUPS:
 73     case SUBS:
 74       return true;
 75     default:
 76       return false;
 77     }
 78   }
 79 /*
 80   static bool is_unary(e_type a_type) {
 81     switch(a_type) {
 82     case MINUS:
 83       return true;
 84     default:
 85       return false;
 86     }
 87   }
 88   static bool is_edition(e_type a_type) { //for valop2s
 89     switch(a_type) {
 90     case SYMBOL:
 91     case ASIDE:
 92     case NVMUL:
 93     case EQUAL:
 94     case SUPS:
 95     case SUBS:
 96       return true;
 97     default:
 98       return false;
 99     }
100   }
101 */
102 public:
103   valop(e_type a_type)
104   :m_type(a_type),m_function(0),m_index(not_found())
105   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
106 #ifdef TOOLS_MEM
107     mem::increment(s_class().c_str());
108 #endif
109   }
110 
111   valop(e_type a_type,valop* a_A)
112   :m_type(a_type),m_function(0),m_index(not_found())
113   ,m_A(a_A),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
114 #ifdef TOOLS_MEM
115     mem::increment(s_class().c_str());
116 #endif
117   }
118 
119   valop(e_type a_type,valop* a_A,valop* a_B)
120   :m_type(a_type),m_function(0),m_index(not_found())
121   ,m_A(a_A),m_B(a_B),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
122 #ifdef TOOLS_MEM
123     mem::increment(s_class().c_str());
124 #endif
125   }
126 
127   valop(e_type a_type,ival_func* a_function,valop* a_A)
128   :m_type(a_type),m_function(0),m_index(not_found())
129   ,m_A(a_A),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
130 #ifdef TOOLS_MEM
131     mem::increment(s_class().c_str());
132 #endif
133     m_function = a_function?a_function->copy():0;
134   }
135 
136   valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B)
137   :m_type(a_type),m_function(0),m_index(not_found())
138   ,m_A(a_A),m_B(a_B),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
139 #ifdef TOOLS_MEM
140     mem::increment(s_class().c_str());
141 #endif
142     m_function = a_function?a_function->copy():0;
143   }
144 
145   valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B,valop* a_C)
146   :m_type(a_type),m_function(0),m_index(not_found())
147   ,m_A(a_A),m_B(a_B),m_C(a_C),m_D(0),m_E(0),m_F(0),m_tag(0){
148 #ifdef TOOLS_MEM
149     mem::increment(s_class().c_str());
150 #endif
151     m_function = a_function?a_function->copy():0;
152   }
153 
154   valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B,valop* a_C,valop* a_D)
155   :m_type(a_type),m_function(0),m_index(not_found())
156   ,m_A(a_A),m_B(a_B),m_C(a_C),m_D(a_D),m_E(0),m_F(0),m_tag(0){
157 #ifdef TOOLS_MEM
158     mem::increment(s_class().c_str());
159 #endif
160     m_function = a_function?a_function->copy():0;
161   }
162 
163   valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B,valop* a_C,valop* a_D,valop* a_E)
164   :m_type(a_type),m_function(0),m_index(not_found())
165   ,m_A(a_A),m_B(a_B),m_C(a_C),m_D(a_D),m_E(a_E),m_F(0),m_tag(0){
166 #ifdef TOOLS_MEM
167     mem::increment(s_class().c_str());
168 #endif
169     m_function = a_function?a_function->copy():0;
170   }
171 
172   valop(e_type a_type,ival_func* a_function,
173              valop* a_A,valop* a_B,valop* a_C,
174              valop* a_D,valop* a_E,valop* a_F)
175   :m_type(a_type),m_function(0),m_index(not_found())
176   ,m_A(a_A),m_B(a_B),m_C(a_C),m_D(a_D),m_E(a_E),m_F(a_F),m_tag(0){
177 #ifdef TOOLS_MEM
178     mem::increment(s_class().c_str());
179 #endif
180     m_function = a_function?a_function->copy():0;
181   }
182 
183   valop(e_type a_type,bool a_v)
184   :m_type(a_type),m_function(0),m_index(not_found())
185   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
186 #ifdef TOOLS_MEM
187     mem::increment(s_class().c_str());
188 #endif
189     m_variable.set(a_v);
190   }
191 
192   valop(e_type a_type,unsigned int a_number)
193   :m_type(a_type),m_function(0),m_index(not_found())
194   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
195 #ifdef TOOLS_MEM
196     mem::increment(s_class().c_str());
197 #endif
198     m_variable.set(a_number);
199   }
200 
201   valop(e_type a_type,double a_number)
202   :m_type(a_type),m_function(0),m_index(not_found())
203   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
204 #ifdef TOOLS_MEM
205     mem::increment(s_class().c_str());
206 #endif
207     m_variable.set(a_number);
208   }
209 
210   valop(e_type a_type,const std::string& a_string)
211   :m_type(a_type),m_function(0),m_index(not_found())
212   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
213 #ifdef TOOLS_MEM
214     mem::increment(s_class().c_str());
215 #endif
216     m_variable.set(a_string);
217   }
218 
219   //NOTE : the below is needed so that valop("t") not put on valop(bool).
220   valop(e_type a_type,const char* a_cstr)
221   :m_type(a_type),m_function(0),m_index(not_found())
222   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
223 #ifdef TOOLS_MEM
224     mem::increment(s_class().c_str());
225 #endif
226     m_variable.set(a_cstr);
227   }
228 
229   valop(e_type a_type,const std::string& a_name,int a_index)
230   :m_type(a_type),m_function(0),m_name(a_name),m_index(a_index)
231   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
232     // a_name needed to not confuse with the constructor (e_type,unsigned int).
233 #ifdef TOOLS_MEM
234     mem::increment(s_class().c_str());
235 #endif
236   }
237 
238   virtual ~valop() {
239     delete m_function;
240     delete m_A;
241     delete m_B;
242     delete m_C;
243     delete m_D;
244     delete m_E;
245     delete m_F;
246 #ifdef TOOLS_MEM
247     mem::decrement(s_class().c_str());
248 #endif
249   }
250 public:
251   valop(const valop& a_from)
252   :m_type(a_from.m_type)
253   ,m_function(a_from.m_function?a_from.m_function->copy():0)
254   ,m_variable(a_from.m_variable)
255   ,m_name(a_from.m_name)
256   ,m_index(a_from.m_index)
257 
258   ,m_A(a_from.m_A?new valop(*a_from.m_A):0)
259   ,m_B(a_from.m_B?new valop(*a_from.m_B):0)
260   ,m_C(a_from.m_C?new valop(*a_from.m_C):0)
261   ,m_D(a_from.m_D?new valop(*a_from.m_D):0)
262   ,m_E(a_from.m_E?new valop(*a_from.m_E):0)
263   ,m_F(a_from.m_F?new valop(*a_from.m_F):0)
264 
265   ,m_tag(a_from.m_tag)
266   {
267 #ifdef TOOLS_MEM
268     mem::increment(s_class().c_str());
269 #endif
270   }
271   valop& operator=(const valop& a_from) {
272     if(&a_from==this) return *this;
273 
274     m_type = a_from.m_type;
275 
276     delete m_function;
277     m_function = a_from.m_function?a_from.m_function->copy():0;
278 
279     m_variable = a_from.m_variable;
280     m_name = a_from.m_name;
281     m_index = a_from.m_index;
282 
283     delete m_A;
284     delete m_B;
285     delete m_C;
286     delete m_D;
287     delete m_E;
288     delete m_F;
289     m_A = a_from.m_A?new valop(*a_from.m_A):0;
290     m_B = a_from.m_B?new valop(*a_from.m_B):0;
291     m_C = a_from.m_C?new valop(*a_from.m_C):0;
292     m_D = a_from.m_D?new valop(*a_from.m_D):0;
293     m_E = a_from.m_E?new valop(*a_from.m_E):0;
294     m_F = a_from.m_F?new valop(*a_from.m_F):0;
295 
296     m_tag = a_from.m_tag;
297     return *this;
298   }
299 public:
300   static valop def() {return valop(REAL,0.0);}
301 
302   valop* copy() const {return new valop(*this);}
303 
304   e_type type() const {return m_type;}
305 
306   void print(std::ostream& a_out) {
307     a_out << "Type : " << this << " " << (int)m_type << std::endl;
308     //if(!m_variable.is_none()) m_variable.print(a_out);
309     if(m_A) m_A->print(a_out);
310     if(m_B) m_B->print(a_out);
311   }
312 
313   bool is_leaf() const {
314     switch(m_type) {
315     case UNSIGNED_INTEGER:
316     case REAL:
317     case STRING:
318     case NAME:
319     //case PI:
320     case SYMBOL:
321     case BOOL_TRUE:
322     case BOOL_FALSE:
323       return true;
324     default:
325       return false;
326     }
327   }
328   bool is_binary() const {
329     switch(m_type) {
330     case CMP_GT:
331     case CMP_GE:
332     case CMP_LT:
333     case CMP_LE:
334     case CMP_EQ:
335     case CMP_NE:
336     case CMP_AND:
337     case CMP_OR:
338 
339     case ADD:
340     case MUL:
341     case SUB:
342     case DIV:
343 
344     case ASIDE:
345     case NVMUL:
346     case EQUAL:
347     case SUPS:
348     case SUBS:
349       return true;
350     default:
351       return false;
352     }
353   }
354   bool is_unary() const {
355     switch(m_type) {
356     case MINUS:
357     case NOT:
358     case ASSIGN:
359       return true;
360     case FUNC:
361       if(!m_A) return false;
362       if(!m_function) return false;
363       if(m_function->number_of_arguments()==1) return true;
364       return false;
365     default:
366       return false;
367     }
368   }
369 
370   //const value& variable() const {return m_variable;}
371   //value& variable() {return m_variable;}
372 
373   void replace(valop* a_node,valop* a_to,bool a_delete) {
374     if(m_A==a_node) {if(a_delete) delete m_A;m_A = a_to;return;}
375     if(m_B==a_node) {if(a_delete) delete m_B;m_B = a_to;return;}
376     if(m_C==a_node) {if(a_delete) delete m_C;m_C = a_to;return;}
377     if(m_D==a_node) {if(a_delete) delete m_D;m_D = a_to;return;}
378     if(m_E==a_node) {if(a_delete) delete m_E;m_E = a_to;return;}
379     if(m_F==a_node) {if(a_delete) delete m_F;m_F = a_to;return;}
380   }
381 
382 protected:
383   static int not_found() {return -1;}
384 public:
385   e_type m_type;
386   ival_func* m_function; //owner
387   value m_variable;
388   std::string m_name;
389   int m_index;
390   valop* m_A;
391   valop* m_B;
392   valop* m_C;
393   valop* m_D;
394   valop* m_E;
395   valop* m_F;
396 public:
397   int m_tag;
398 };
399 
400 class valop_visitor {
401 public:
402   virtual ~valop_visitor() {}
403 public:
404   virtual bool binary(unsigned int,const valop&,const valop&) = 0;
405   virtual bool unary(unsigned int,const valop&) = 0;
406   virtual bool variable(unsigned int,const value&) = 0;
407   virtual bool option(const valop&) = 0;
408   virtual bool func_1(const valop&,const valop&) = 0;
409   virtual bool func_2(const valop&,const valop&,const valop&) = 0;
410   virtual bool func_3(const valop&,const valop&,const valop&,const valop&) = 0;
411   virtual bool func_4(const valop&,const valop&,const valop&,
412                                    const valop&,const valop&) = 0;
413   virtual bool func_5(const valop&,const valop&,const valop&,
414                                    const valop&,const valop&,const valop&) = 0;
415   virtual bool func_6(const valop&,const valop&,const valop&,
416                                    const valop&,const valop&,
417                                    const valop&,const valop&) = 0;
418 public:
419   bool visit(const valop& a_valop) {
420     switch(a_valop.m_type) {
421     case valop::CMP_GT:
422     case valop::CMP_GE:
423     case valop::CMP_LT:
424     case valop::CMP_LE:
425     case valop::CMP_EQ:
426     case valop::CMP_NE:
427     case valop::CMP_AND:
428     case valop::CMP_OR:
429 
430     case valop::ADD:
431     case valop::MUL:
432     case valop::SUB:
433     case valop::DIV:
434 
435     case valop::ASIDE:
436     case valop::NVMUL:
437     case valop::EQUAL:
438     case valop::SUPS:
439     case valop::SUBS:
440       if(!a_valop.m_A || !a_valop.m_B) break;
441       return binary(a_valop.m_type,*a_valop.m_A,*a_valop.m_B);
442 
443     case valop::BOOL_TRUE:
444     case valop::BOOL_FALSE:
445     case valop::UNSIGNED_INTEGER:
446     case valop::REAL:
447     case valop::STRING:
448     case valop::SYMBOL:
449       return variable(a_valop.m_type,a_valop.m_variable);
450     case valop::NAME:
451       return option(a_valop);
452     case valop::MINUS:
453     case valop::NOT:
454     case valop::ASSIGN:
455       if(!a_valop.m_A) break;
456       return unary(a_valop.m_type,*a_valop.m_A);
457     case valop::FUNC:{
458       if(!a_valop.m_A) break;
459       if(!a_valop.m_function) {
460         //a_error = std::string("valop::execute : null function");
461         return false;
462       }
463       size_t argn = a_valop.m_function->number_of_arguments();
464       if(argn==1) {
465         return func_1(a_valop,*a_valop.m_A);
466       } else if(argn==2) {
467         if(!a_valop.m_B) break;
468         return func_2(a_valop,*a_valop.m_A,*a_valop.m_B);
469       } else if(argn==3) {
470         if(!a_valop.m_B || !a_valop.m_C) break;
471         return func_3(a_valop,*a_valop.m_A,*a_valop.m_B,*a_valop.m_C);
472       } else if(argn==4) {
473         if(!a_valop.m_B || !a_valop.m_C || !a_valop.m_D) break;
474         return func_4(a_valop,*a_valop.m_A,*a_valop.m_B,*a_valop.m_C,*a_valop.m_D);
475       } else if(argn==5) {
476         if(!a_valop.m_B || !a_valop.m_C || !a_valop.m_D || !a_valop.m_E) break;
477         return func_5(a_valop,*a_valop.m_A,*a_valop.m_B,*a_valop.m_C,*a_valop.m_D,*a_valop.m_E);
478       } else if(argn==6) {
479         if(!a_valop.m_B || !a_valop.m_C || !a_valop.m_D || !a_valop.m_E || !a_valop.m_F) break;
480         return func_6(a_valop,*a_valop.m_A,*a_valop.m_B,*a_valop.m_C,*a_valop.m_D,*a_valop.m_E,*a_valop.m_F);
481       } else {
482         return false;
483       }}
484     default:
485       break;
486     }
487     return false;
488   }
489 };
490 
491 class get_path : public virtual valop_visitor {
492 public:
493   virtual bool binary(unsigned int,const valop& a_1,const valop& a_2) {
494     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
495     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
496     m_path.push_back((valop*)&a_1);
497     if(!visit(a_1)) return false; //found in sub hierachy
498     m_path.pop_back();
499     m_path.push_back((valop*)&a_2);
500     if(!visit(a_2)) return false;
501     m_path.pop_back();
502     return true; //continue searching
503   }
504 
505   virtual bool unary(unsigned int,const valop& a_1) {
506     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
507     m_path.push_back((valop*)&a_1);
508     if(!visit(a_1)) return false; //found in sub hierachy
509     m_path.pop_back();
510     return true; //continue searching
511   }
512 
513   virtual bool variable(unsigned int,const value&) {return true;}
514   virtual bool option(const valop&) {return true;}
515 
516   virtual bool func_1(const valop&,const valop& a_1) {
517     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
518     m_path.push_back((valop*)&a_1);
519     if(!visit(a_1)) return false; //found in sub hierachy
520     m_path.pop_back();
521     return true; //continue searching
522   }
523   virtual bool func_2(const valop&,const valop& a_1,const valop& a_2) {
524     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
525     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
526     m_path.push_back((valop*)&a_1);
527     if(!visit(a_1)) return false; //found in sub hierachy
528     m_path.pop_back();
529     m_path.push_back((valop*)&a_2);
530     if(!visit(a_2)) return false;
531     m_path.pop_back();
532     return true; //continue searching
533   }
534   virtual bool func_3(const valop&,
535                       const valop& a_1,const valop& a_2,const valop& a_3) {
536     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
537     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
538     if(match(a_3)) {m_path.push_back(m_node);return false;} //stop searching
539     m_path.push_back((valop*)&a_1);
540     if(!visit(a_1)) return false; //found in sub hierachy
541     m_path.pop_back();
542     m_path.push_back((valop*)&a_2);
543     if(!visit(a_2)) return false;
544     m_path.pop_back();
545     m_path.push_back((valop*)&a_3);
546     if(!visit(a_3)) return false;
547     m_path.pop_back();
548     return true; //continue searching
549   }
550   virtual bool func_4(const valop&,
551                       const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4) {
552     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
553     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
554     if(match(a_3)) {m_path.push_back(m_node);return false;} //stop searching
555     if(match(a_4)) {m_path.push_back(m_node);return false;} //stop searching
556     m_path.push_back((valop*)&a_1);
557     if(!visit(a_1)) return false; //found in sub hierachy
558     m_path.pop_back();
559     m_path.push_back((valop*)&a_2);
560     if(!visit(a_2)) return false;
561     m_path.pop_back();
562     m_path.push_back((valop*)&a_3);
563     if(!visit(a_3)) return false;
564     m_path.pop_back();
565     m_path.push_back((valop*)&a_4);
566     if(!visit(a_4)) return false;
567     m_path.pop_back();
568     return true; //continue searching
569   }
570   virtual bool func_5(const valop&,
571                  const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4,const valop& a_5) {
572     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
573     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
574     if(match(a_3)) {m_path.push_back(m_node);return false;} //stop searching
575     if(match(a_4)) {m_path.push_back(m_node);return false;} //stop searching
576     if(match(a_5)) {m_path.push_back(m_node);return false;} //stop searching
577     m_path.push_back((valop*)&a_1);
578     if(!visit(a_1)) return false; //found in sub hierachy
579     m_path.pop_back();
580     m_path.push_back((valop*)&a_2);
581     if(!visit(a_2)) return false;
582     m_path.pop_back();
583     m_path.push_back((valop*)&a_3);
584     if(!visit(a_3)) return false;
585     m_path.pop_back();
586     m_path.push_back((valop*)&a_4);
587     if(!visit(a_4)) return false;
588     m_path.pop_back();
589     m_path.push_back((valop*)&a_5);
590     if(!visit(a_5)) return false;
591     m_path.pop_back();
592     return true; //continue searching
593   }
594   virtual bool func_6(const valop&,
595                       const valop& a_1,const valop& a_2,const valop& a_3,
596                       const valop& a_4,const valop& a_5,const valop& a_6) {
597     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
598     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
599     if(match(a_3)) {m_path.push_back(m_node);return false;} //stop searching
600     if(match(a_4)) {m_path.push_back(m_node);return false;} //stop searching
601     if(match(a_5)) {m_path.push_back(m_node);return false;} //stop searching
602     if(match(a_6)) {m_path.push_back(m_node);return false;} //stop searching
603     m_path.push_back((valop*)&a_1);
604     if(!visit(a_1)) return false; //found in sub hierachy
605     m_path.pop_back();
606     m_path.push_back((valop*)&a_2);
607     if(!visit(a_2)) return false;
608     m_path.pop_back();
609     m_path.push_back((valop*)&a_3);
610     if(!visit(a_3)) return false;
611     m_path.pop_back();
612     m_path.push_back((valop*)&a_4);
613     if(!visit(a_4)) return false;
614     m_path.pop_back();
615     m_path.push_back((valop*)&a_5);
616     if(!visit(a_5)) return false;
617     m_path.pop_back();
618     m_path.push_back((valop*)&a_6);
619     if(!visit(a_6)) return false;
620     m_path.pop_back();
621     return true; //continue searching
622   }
623 public:
624   get_path():m_node(0),m_tag(0){}
625   virtual ~get_path() {}
626 public:
627   get_path(const get_path& a_from)
628   :valop_visitor(a_from)
629   ,m_node(a_from.m_node)
630   ,m_tag(a_from.m_tag)
631   {}
632   get_path& operator=(const get_path& a_from){
633     m_node = a_from.m_node;
634     m_tag = a_from.m_tag;
635     return *this;
636   }
637 protected:
638   bool match(const valop& a_node) {
639     if(m_node) {
640       if((&a_node)==m_node) return true;
641     } else {
642       if(a_node.m_tag==m_tag) return true;
643     }
644     return false;
645   }
646 public:
647   valop* m_node;
648   int m_tag;
649   std::vector<valop*> m_path;
650 };
651 
652 class get_named : public virtual valop_visitor {
653 public:
654   virtual bool binary(unsigned int,const valop& a_1,const valop& a_2) {
655     if(!visit(a_1)) return false;
656     if(!visit(a_2)) return false;
657     return true; //continue searching
658   }
659 
660   virtual bool unary(unsigned int,const valop& a_1) {
661     if(!visit(a_1)) return false;
662     return true;
663   }
664 
665   virtual bool variable(unsigned int,const value&) {return true;}
666   virtual bool option(const valop& a_node) {
667     m_nodes.push_back((valop*)&a_node);
668     return true;
669   }
670 
671   virtual bool func_1(const valop&,const valop& a_1) {
672     if(!visit(a_1)) return false;
673     return true;
674   }
675 
676   virtual bool func_2(const valop&,const valop& a_1,const valop& a_2) {
677     if(!visit(a_1)) return false;
678     if(!visit(a_2)) return false;
679     return true;
680   }
681   virtual bool func_3(const valop&,
682                       const valop& a_1,const valop& a_2,const valop& a_3) {
683     if(!visit(a_1)) return false;
684     if(!visit(a_2)) return false;
685     if(!visit(a_3)) return false;
686     return true;
687   }
688   virtual bool func_4(const valop&,
689                       const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4) {
690     if(!visit(a_1)) return false;
691     if(!visit(a_2)) return false;
692     if(!visit(a_3)) return false;
693     if(!visit(a_4)) return false;
694     return true;
695   }
696   virtual bool func_5(const valop&,
697                  const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4,const valop& a_5) {
698     if(!visit(a_1)) return false;
699     if(!visit(a_2)) return false;
700     if(!visit(a_3)) return false;
701     if(!visit(a_4)) return false;
702     if(!visit(a_5)) return false;
703     return true;
704   }
705   virtual bool func_6(const valop&,
706                       const valop& a_1,const valop& a_2,const valop& a_3,
707                       const valop& a_4,const valop& a_5,const valop& a_6) {
708     if(!visit(a_1)) return false;
709     if(!visit(a_2)) return false;
710     if(!visit(a_3)) return false;
711     if(!visit(a_4)) return false;
712     if(!visit(a_5)) return false;
713     if(!visit(a_6)) return false;
714     return true;
715   }
716 public:
717   get_named(){}
718   virtual ~get_named() {}
719 public:
720   get_named(const get_named& a_from):valop_visitor(a_from){}
721   get_named& operator=(const get_named&){return *this;}
722 public:
723   std::vector<valop*> m_nodes;
724 };
725 
726 class get_funcs : public virtual valop_visitor {
727 public:
728   virtual bool binary(unsigned int,const valop& a_1,const valop& a_2) {
729     if(!visit(a_1)) return false;
730     if(!visit(a_2)) return false;
731     return true; //continue searching
732   }
733 
734   virtual bool unary(unsigned int,const valop& a_1) {
735     if(!visit(a_1)) return false;
736     return true;
737   }
738 
739   virtual bool variable(unsigned int,const value&) {return true;}
740   virtual bool option(const valop&) {return true;}
741 
742   virtual bool func_1(const valop& a_node,const valop& a_1) {
743     m_nodes.push_back((valop*)&a_node);
744     if(!visit(a_1)) return false;
745     return true;
746   }
747 
748   virtual bool func_2(const valop& a_node,const valop& a_1,const valop& a_2) {
749     m_nodes.push_back((valop*)&a_node);
750     if(!visit(a_1)) return false;
751     if(!visit(a_2)) return false;
752     return true;
753   }
754   virtual bool func_3(const valop& a_node,
755                       const valop& a_1,const valop& a_2,const valop& a_3) {
756     m_nodes.push_back((valop*)&a_node);
757     if(!visit(a_1)) return false;
758     if(!visit(a_2)) return false;
759     if(!visit(a_3)) return false;
760     return true;
761   }
762   virtual bool func_4(const valop& a_node,
763                       const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4) {
764     m_nodes.push_back((valop*)&a_node);
765     if(!visit(a_1)) return false;
766     if(!visit(a_2)) return false;
767     if(!visit(a_3)) return false;
768     if(!visit(a_4)) return false;
769     return true;
770   }
771   virtual bool func_5(const valop& a_node,
772                  const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4,const valop& a_5) {
773     m_nodes.push_back((valop*)&a_node);
774     if(!visit(a_1)) return false;
775     if(!visit(a_2)) return false;
776     if(!visit(a_3)) return false;
777     if(!visit(a_4)) return false;
778     if(!visit(a_5)) return false;
779     return true;
780   }
781   virtual bool func_6(const valop& a_node,
782                       const valop& a_1,const valop& a_2,const valop& a_3,
783                       const valop& a_4,const valop& a_5,const valop& a_6) {
784     m_nodes.push_back((valop*)&a_node);
785     if(!visit(a_1)) return false;
786     if(!visit(a_2)) return false;
787     if(!visit(a_3)) return false;
788     if(!visit(a_4)) return false;
789     if(!visit(a_5)) return false;
790     if(!visit(a_6)) return false;
791     return true;
792   }
793 public:
794   get_funcs(){}
795   virtual ~get_funcs() {}
796 public:
797   get_funcs(const get_funcs& a_from):valop_visitor(a_from){}
798   get_funcs& operator=(const get_funcs&){return *this;}
799 public:
800   std::vector<valop*> m_nodes;
801 };
802 
803 }
804 
805 #endif