Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/valop is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_valop
0005 #define tools_valop
0006 
0007 #include "ival_func"
0008 
0009 namespace tools {
0010 
0011 class valop {
0012   static const std::string& s_class() {
0013     static const std::string s_v("tools::valop");
0014     return s_v;
0015   }
0016 public:
0017   enum e_type {
0018     CMP_GT = 1,
0019     CMP_GE = 2,
0020     CMP_LT = 3,
0021     CMP_LE = 4,
0022     CMP_EQ = 5,
0023     CMP_NE = 6,
0024     CMP_AND = 7,
0025     CMP_OR = 8,
0026 
0027     ADD = 9,
0028     MUL = 10,
0029     SUB = 11,
0030     DIV = 12,
0031 
0032     ASSIGN = 13,
0033     MINUS = 14,
0034     UNSIGNED_INTEGER = 15,
0035     REAL = 16,
0036     NAME = 17,
0037     STRING = 18,
0038     //PI = 19,
0039     FUNC = 20,
0040     BOOL_TRUE = 21,
0041     BOOL_FALSE = 22,
0042     NOT = 23,
0043     // math edition :
0044     SYMBOL = 100,
0045     ASIDE = 101,
0046     NVMUL = 102, //not visible mul
0047     EQUAL = 103,
0048     SUPS = 104,  //super script
0049     SUBS = 105   //sub script
0050   };
0051 
0052 public:
0053   static bool is_binary(e_type a_type) {
0054     switch(a_type) {
0055     case CMP_GT:
0056     case CMP_GE:
0057     case CMP_LT:
0058     case CMP_LE:
0059     case CMP_EQ:
0060     case CMP_NE:
0061     case CMP_AND:
0062     case CMP_OR:
0063 
0064     case ADD:
0065     case MUL:
0066     case SUB:
0067     case DIV:
0068 
0069     case ASIDE:
0070     case NVMUL:
0071     case EQUAL:
0072     case SUPS:
0073     case SUBS:
0074       return true;
0075     default:
0076       return false;
0077     }
0078   }
0079 /*
0080   static bool is_unary(e_type a_type) {
0081     switch(a_type) {
0082     case MINUS:
0083       return true;
0084     default:
0085       return false;
0086     }
0087   }
0088   static bool is_edition(e_type a_type) { //for valop2s
0089     switch(a_type) {
0090     case SYMBOL:
0091     case ASIDE:
0092     case NVMUL:
0093     case EQUAL:
0094     case SUPS:
0095     case SUBS:
0096       return true;
0097     default:
0098       return false;
0099     }
0100   }
0101 */
0102 public:
0103   valop(e_type a_type)
0104   :m_type(a_type),m_function(0),m_index(not_found())
0105   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0106 #ifdef TOOLS_MEM
0107     mem::increment(s_class().c_str());
0108 #endif
0109   }
0110 
0111   valop(e_type a_type,valop* a_A)
0112   :m_type(a_type),m_function(0),m_index(not_found())
0113   ,m_A(a_A),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0114 #ifdef TOOLS_MEM
0115     mem::increment(s_class().c_str());
0116 #endif
0117   }
0118 
0119   valop(e_type a_type,valop* a_A,valop* a_B)
0120   :m_type(a_type),m_function(0),m_index(not_found())
0121   ,m_A(a_A),m_B(a_B),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0122 #ifdef TOOLS_MEM
0123     mem::increment(s_class().c_str());
0124 #endif
0125   }
0126 
0127   valop(e_type a_type,ival_func* a_function,valop* a_A)
0128   :m_type(a_type),m_function(0),m_index(not_found())
0129   ,m_A(a_A),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0130 #ifdef TOOLS_MEM
0131     mem::increment(s_class().c_str());
0132 #endif
0133     m_function = a_function?a_function->copy():0;
0134   }
0135 
0136   valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B)
0137   :m_type(a_type),m_function(0),m_index(not_found())
0138   ,m_A(a_A),m_B(a_B),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0139 #ifdef TOOLS_MEM
0140     mem::increment(s_class().c_str());
0141 #endif
0142     m_function = a_function?a_function->copy():0;
0143   }
0144 
0145   valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B,valop* a_C)
0146   :m_type(a_type),m_function(0),m_index(not_found())
0147   ,m_A(a_A),m_B(a_B),m_C(a_C),m_D(0),m_E(0),m_F(0),m_tag(0){
0148 #ifdef TOOLS_MEM
0149     mem::increment(s_class().c_str());
0150 #endif
0151     m_function = a_function?a_function->copy():0;
0152   }
0153 
0154   valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B,valop* a_C,valop* a_D)
0155   :m_type(a_type),m_function(0),m_index(not_found())
0156   ,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){
0157 #ifdef TOOLS_MEM
0158     mem::increment(s_class().c_str());
0159 #endif
0160     m_function = a_function?a_function->copy():0;
0161   }
0162 
0163   valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B,valop* a_C,valop* a_D,valop* a_E)
0164   :m_type(a_type),m_function(0),m_index(not_found())
0165   ,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){
0166 #ifdef TOOLS_MEM
0167     mem::increment(s_class().c_str());
0168 #endif
0169     m_function = a_function?a_function->copy():0;
0170   }
0171 
0172   valop(e_type a_type,ival_func* a_function,
0173              valop* a_A,valop* a_B,valop* a_C,
0174              valop* a_D,valop* a_E,valop* a_F)
0175   :m_type(a_type),m_function(0),m_index(not_found())
0176   ,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){
0177 #ifdef TOOLS_MEM
0178     mem::increment(s_class().c_str());
0179 #endif
0180     m_function = a_function?a_function->copy():0;
0181   }
0182 
0183   valop(e_type a_type,bool a_v)
0184   :m_type(a_type),m_function(0),m_index(not_found())
0185   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0186 #ifdef TOOLS_MEM
0187     mem::increment(s_class().c_str());
0188 #endif
0189     m_variable.set(a_v);
0190   }
0191 
0192   valop(e_type a_type,unsigned int a_number)
0193   :m_type(a_type),m_function(0),m_index(not_found())
0194   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0195 #ifdef TOOLS_MEM
0196     mem::increment(s_class().c_str());
0197 #endif
0198     m_variable.set(a_number);
0199   }
0200 
0201   valop(e_type a_type,double a_number)
0202   :m_type(a_type),m_function(0),m_index(not_found())
0203   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0204 #ifdef TOOLS_MEM
0205     mem::increment(s_class().c_str());
0206 #endif
0207     m_variable.set(a_number);
0208   }
0209 
0210   valop(e_type a_type,const std::string& a_string)
0211   :m_type(a_type),m_function(0),m_index(not_found())
0212   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0213 #ifdef TOOLS_MEM
0214     mem::increment(s_class().c_str());
0215 #endif
0216     m_variable.set(a_string);
0217   }
0218 
0219   //NOTE : the below is needed so that valop("t") not put on valop(bool).
0220   valop(e_type a_type,const char* a_cstr)
0221   :m_type(a_type),m_function(0),m_index(not_found())
0222   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0223 #ifdef TOOLS_MEM
0224     mem::increment(s_class().c_str());
0225 #endif
0226     m_variable.set(a_cstr);
0227   }
0228 
0229   valop(e_type a_type,const std::string& a_name,int a_index)
0230   :m_type(a_type),m_function(0),m_name(a_name),m_index(a_index)
0231   ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){
0232     // a_name needed to not confuse with the constructor (e_type,unsigned int).
0233 #ifdef TOOLS_MEM
0234     mem::increment(s_class().c_str());
0235 #endif
0236   }
0237 
0238   virtual ~valop() {
0239     delete m_function;
0240     delete m_A;
0241     delete m_B;
0242     delete m_C;
0243     delete m_D;
0244     delete m_E;
0245     delete m_F;
0246 #ifdef TOOLS_MEM
0247     mem::decrement(s_class().c_str());
0248 #endif
0249   }
0250 public:
0251   valop(const valop& a_from)
0252   :m_type(a_from.m_type)
0253   ,m_function(a_from.m_function?a_from.m_function->copy():0)
0254   ,m_variable(a_from.m_variable)
0255   ,m_name(a_from.m_name)
0256   ,m_index(a_from.m_index)
0257 
0258   ,m_A(a_from.m_A?new valop(*a_from.m_A):0)
0259   ,m_B(a_from.m_B?new valop(*a_from.m_B):0)
0260   ,m_C(a_from.m_C?new valop(*a_from.m_C):0)
0261   ,m_D(a_from.m_D?new valop(*a_from.m_D):0)
0262   ,m_E(a_from.m_E?new valop(*a_from.m_E):0)
0263   ,m_F(a_from.m_F?new valop(*a_from.m_F):0)
0264 
0265   ,m_tag(a_from.m_tag)
0266   {
0267 #ifdef TOOLS_MEM
0268     mem::increment(s_class().c_str());
0269 #endif
0270   }
0271   valop& operator=(const valop& a_from) {
0272     if(&a_from==this) return *this;
0273 
0274     m_type = a_from.m_type;
0275 
0276     delete m_function;
0277     m_function = a_from.m_function?a_from.m_function->copy():0;
0278 
0279     m_variable = a_from.m_variable;
0280     m_name = a_from.m_name;
0281     m_index = a_from.m_index;
0282 
0283     delete m_A;
0284     delete m_B;
0285     delete m_C;
0286     delete m_D;
0287     delete m_E;
0288     delete m_F;
0289     m_A = a_from.m_A?new valop(*a_from.m_A):0;
0290     m_B = a_from.m_B?new valop(*a_from.m_B):0;
0291     m_C = a_from.m_C?new valop(*a_from.m_C):0;
0292     m_D = a_from.m_D?new valop(*a_from.m_D):0;
0293     m_E = a_from.m_E?new valop(*a_from.m_E):0;
0294     m_F = a_from.m_F?new valop(*a_from.m_F):0;
0295 
0296     m_tag = a_from.m_tag;
0297     return *this;
0298   }
0299 public:
0300   static valop def() {return valop(REAL,0.0);}
0301 
0302   valop* copy() const {return new valop(*this);}
0303 
0304   e_type type() const {return m_type;}
0305 
0306   void print(std::ostream& a_out) {
0307     a_out << "Type : " << this << " " << (int)m_type << std::endl;
0308     //if(!m_variable.is_none()) m_variable.print(a_out);
0309     if(m_A) m_A->print(a_out);
0310     if(m_B) m_B->print(a_out);
0311   }
0312 
0313   bool is_leaf() const {
0314     switch(m_type) {
0315     case UNSIGNED_INTEGER:
0316     case REAL:
0317     case STRING:
0318     case NAME:
0319     //case PI:
0320     case SYMBOL:
0321     case BOOL_TRUE:
0322     case BOOL_FALSE:
0323       return true;
0324     default:
0325       return false;
0326     }
0327   }
0328   bool is_binary() const {
0329     switch(m_type) {
0330     case CMP_GT:
0331     case CMP_GE:
0332     case CMP_LT:
0333     case CMP_LE:
0334     case CMP_EQ:
0335     case CMP_NE:
0336     case CMP_AND:
0337     case CMP_OR:
0338 
0339     case ADD:
0340     case MUL:
0341     case SUB:
0342     case DIV:
0343 
0344     case ASIDE:
0345     case NVMUL:
0346     case EQUAL:
0347     case SUPS:
0348     case SUBS:
0349       return true;
0350     default:
0351       return false;
0352     }
0353   }
0354   bool is_unary() const {
0355     switch(m_type) {
0356     case MINUS:
0357     case NOT:
0358     case ASSIGN:
0359       return true;
0360     case FUNC:
0361       if(!m_A) return false;
0362       if(!m_function) return false;
0363       if(m_function->number_of_arguments()==1) return true;
0364       return false;
0365     default:
0366       return false;
0367     }
0368   }
0369 
0370   //const value& variable() const {return m_variable;}
0371   //value& variable() {return m_variable;}
0372 
0373   void replace(valop* a_node,valop* a_to,bool a_delete) {
0374     if(m_A==a_node) {if(a_delete) delete m_A;m_A = a_to;return;}
0375     if(m_B==a_node) {if(a_delete) delete m_B;m_B = a_to;return;}
0376     if(m_C==a_node) {if(a_delete) delete m_C;m_C = a_to;return;}
0377     if(m_D==a_node) {if(a_delete) delete m_D;m_D = a_to;return;}
0378     if(m_E==a_node) {if(a_delete) delete m_E;m_E = a_to;return;}
0379     if(m_F==a_node) {if(a_delete) delete m_F;m_F = a_to;return;}
0380   }
0381 
0382 protected:
0383   static int not_found() {return -1;}
0384 public:
0385   e_type m_type;
0386   ival_func* m_function; //owner
0387   value m_variable;
0388   std::string m_name;
0389   int m_index;
0390   valop* m_A;
0391   valop* m_B;
0392   valop* m_C;
0393   valop* m_D;
0394   valop* m_E;
0395   valop* m_F;
0396 public:
0397   int m_tag;
0398 };
0399 
0400 class valop_visitor {
0401 public:
0402   virtual ~valop_visitor() {}
0403 public:
0404   virtual bool binary(unsigned int,const valop&,const valop&) = 0;
0405   virtual bool unary(unsigned int,const valop&) = 0;
0406   virtual bool variable(unsigned int,const value&) = 0;
0407   virtual bool option(const valop&) = 0;
0408   virtual bool func_1(const valop&,const valop&) = 0;
0409   virtual bool func_2(const valop&,const valop&,const valop&) = 0;
0410   virtual bool func_3(const valop&,const valop&,const valop&,const valop&) = 0;
0411   virtual bool func_4(const valop&,const valop&,const valop&,
0412                                    const valop&,const valop&) = 0;
0413   virtual bool func_5(const valop&,const valop&,const valop&,
0414                                    const valop&,const valop&,const valop&) = 0;
0415   virtual bool func_6(const valop&,const valop&,const valop&,
0416                                    const valop&,const valop&,
0417                                    const valop&,const valop&) = 0;
0418 public:
0419   bool visit(const valop& a_valop) {
0420     switch(a_valop.m_type) {
0421     case valop::CMP_GT:
0422     case valop::CMP_GE:
0423     case valop::CMP_LT:
0424     case valop::CMP_LE:
0425     case valop::CMP_EQ:
0426     case valop::CMP_NE:
0427     case valop::CMP_AND:
0428     case valop::CMP_OR:
0429 
0430     case valop::ADD:
0431     case valop::MUL:
0432     case valop::SUB:
0433     case valop::DIV:
0434 
0435     case valop::ASIDE:
0436     case valop::NVMUL:
0437     case valop::EQUAL:
0438     case valop::SUPS:
0439     case valop::SUBS:
0440       if(!a_valop.m_A || !a_valop.m_B) break;
0441       return binary(a_valop.m_type,*a_valop.m_A,*a_valop.m_B);
0442 
0443     case valop::BOOL_TRUE:
0444     case valop::BOOL_FALSE:
0445     case valop::UNSIGNED_INTEGER:
0446     case valop::REAL:
0447     case valop::STRING:
0448     case valop::SYMBOL:
0449       return variable(a_valop.m_type,a_valop.m_variable);
0450     case valop::NAME:
0451       return option(a_valop);
0452     case valop::MINUS:
0453     case valop::NOT:
0454     case valop::ASSIGN:
0455       if(!a_valop.m_A) break;
0456       return unary(a_valop.m_type,*a_valop.m_A);
0457     case valop::FUNC:{
0458       if(!a_valop.m_A) break;
0459       if(!a_valop.m_function) {
0460         //a_error = std::string("valop::execute : null function");
0461         return false;
0462       }
0463       size_t argn = a_valop.m_function->number_of_arguments();
0464       if(argn==1) {
0465         return func_1(a_valop,*a_valop.m_A);
0466       } else if(argn==2) {
0467         if(!a_valop.m_B) break;
0468         return func_2(a_valop,*a_valop.m_A,*a_valop.m_B);
0469       } else if(argn==3) {
0470         if(!a_valop.m_B || !a_valop.m_C) break;
0471         return func_3(a_valop,*a_valop.m_A,*a_valop.m_B,*a_valop.m_C);
0472       } else if(argn==4) {
0473         if(!a_valop.m_B || !a_valop.m_C || !a_valop.m_D) break;
0474         return func_4(a_valop,*a_valop.m_A,*a_valop.m_B,*a_valop.m_C,*a_valop.m_D);
0475       } else if(argn==5) {
0476         if(!a_valop.m_B || !a_valop.m_C || !a_valop.m_D || !a_valop.m_E) break;
0477         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);
0478       } else if(argn==6) {
0479         if(!a_valop.m_B || !a_valop.m_C || !a_valop.m_D || !a_valop.m_E || !a_valop.m_F) break;
0480         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);
0481       } else {
0482         return false;
0483       }}
0484     default:
0485       break;
0486     }
0487     return false;
0488   }
0489 };
0490 
0491 class get_path : public virtual valop_visitor {
0492 public:
0493   virtual bool binary(unsigned int,const valop& a_1,const valop& a_2) {
0494     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
0495     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
0496     m_path.push_back((valop*)&a_1);
0497     if(!visit(a_1)) return false; //found in sub hierachy
0498     m_path.pop_back();
0499     m_path.push_back((valop*)&a_2);
0500     if(!visit(a_2)) return false;
0501     m_path.pop_back();
0502     return true; //continue searching
0503   }
0504 
0505   virtual bool unary(unsigned int,const valop& a_1) {
0506     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
0507     m_path.push_back((valop*)&a_1);
0508     if(!visit(a_1)) return false; //found in sub hierachy
0509     m_path.pop_back();
0510     return true; //continue searching
0511   }
0512 
0513   virtual bool variable(unsigned int,const value&) {return true;}
0514   virtual bool option(const valop&) {return true;}
0515 
0516   virtual bool func_1(const valop&,const valop& a_1) {
0517     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
0518     m_path.push_back((valop*)&a_1);
0519     if(!visit(a_1)) return false; //found in sub hierachy
0520     m_path.pop_back();
0521     return true; //continue searching
0522   }
0523   virtual bool func_2(const valop&,const valop& a_1,const valop& a_2) {
0524     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
0525     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
0526     m_path.push_back((valop*)&a_1);
0527     if(!visit(a_1)) return false; //found in sub hierachy
0528     m_path.pop_back();
0529     m_path.push_back((valop*)&a_2);
0530     if(!visit(a_2)) return false;
0531     m_path.pop_back();
0532     return true; //continue searching
0533   }
0534   virtual bool func_3(const valop&,
0535                       const valop& a_1,const valop& a_2,const valop& a_3) {
0536     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
0537     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
0538     if(match(a_3)) {m_path.push_back(m_node);return false;} //stop searching
0539     m_path.push_back((valop*)&a_1);
0540     if(!visit(a_1)) return false; //found in sub hierachy
0541     m_path.pop_back();
0542     m_path.push_back((valop*)&a_2);
0543     if(!visit(a_2)) return false;
0544     m_path.pop_back();
0545     m_path.push_back((valop*)&a_3);
0546     if(!visit(a_3)) return false;
0547     m_path.pop_back();
0548     return true; //continue searching
0549   }
0550   virtual bool func_4(const valop&,
0551                       const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4) {
0552     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
0553     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
0554     if(match(a_3)) {m_path.push_back(m_node);return false;} //stop searching
0555     if(match(a_4)) {m_path.push_back(m_node);return false;} //stop searching
0556     m_path.push_back((valop*)&a_1);
0557     if(!visit(a_1)) return false; //found in sub hierachy
0558     m_path.pop_back();
0559     m_path.push_back((valop*)&a_2);
0560     if(!visit(a_2)) return false;
0561     m_path.pop_back();
0562     m_path.push_back((valop*)&a_3);
0563     if(!visit(a_3)) return false;
0564     m_path.pop_back();
0565     m_path.push_back((valop*)&a_4);
0566     if(!visit(a_4)) return false;
0567     m_path.pop_back();
0568     return true; //continue searching
0569   }
0570   virtual bool func_5(const valop&,
0571                  const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4,const valop& a_5) {
0572     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
0573     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
0574     if(match(a_3)) {m_path.push_back(m_node);return false;} //stop searching
0575     if(match(a_4)) {m_path.push_back(m_node);return false;} //stop searching
0576     if(match(a_5)) {m_path.push_back(m_node);return false;} //stop searching
0577     m_path.push_back((valop*)&a_1);
0578     if(!visit(a_1)) return false; //found in sub hierachy
0579     m_path.pop_back();
0580     m_path.push_back((valop*)&a_2);
0581     if(!visit(a_2)) return false;
0582     m_path.pop_back();
0583     m_path.push_back((valop*)&a_3);
0584     if(!visit(a_3)) return false;
0585     m_path.pop_back();
0586     m_path.push_back((valop*)&a_4);
0587     if(!visit(a_4)) return false;
0588     m_path.pop_back();
0589     m_path.push_back((valop*)&a_5);
0590     if(!visit(a_5)) return false;
0591     m_path.pop_back();
0592     return true; //continue searching
0593   }
0594   virtual bool func_6(const valop&,
0595                       const valop& a_1,const valop& a_2,const valop& a_3,
0596                       const valop& a_4,const valop& a_5,const valop& a_6) {
0597     if(match(a_1)) {m_path.push_back(m_node);return false;} //stop searching
0598     if(match(a_2)) {m_path.push_back(m_node);return false;} //stop searching
0599     if(match(a_3)) {m_path.push_back(m_node);return false;} //stop searching
0600     if(match(a_4)) {m_path.push_back(m_node);return false;} //stop searching
0601     if(match(a_5)) {m_path.push_back(m_node);return false;} //stop searching
0602     if(match(a_6)) {m_path.push_back(m_node);return false;} //stop searching
0603     m_path.push_back((valop*)&a_1);
0604     if(!visit(a_1)) return false; //found in sub hierachy
0605     m_path.pop_back();
0606     m_path.push_back((valop*)&a_2);
0607     if(!visit(a_2)) return false;
0608     m_path.pop_back();
0609     m_path.push_back((valop*)&a_3);
0610     if(!visit(a_3)) return false;
0611     m_path.pop_back();
0612     m_path.push_back((valop*)&a_4);
0613     if(!visit(a_4)) return false;
0614     m_path.pop_back();
0615     m_path.push_back((valop*)&a_5);
0616     if(!visit(a_5)) return false;
0617     m_path.pop_back();
0618     m_path.push_back((valop*)&a_6);
0619     if(!visit(a_6)) return false;
0620     m_path.pop_back();
0621     return true; //continue searching
0622   }
0623 public:
0624   get_path():m_node(0),m_tag(0){}
0625   virtual ~get_path() {}
0626 public:
0627   get_path(const get_path& a_from)
0628   :valop_visitor(a_from)
0629   ,m_node(a_from.m_node)
0630   ,m_tag(a_from.m_tag)
0631   {}
0632   get_path& operator=(const get_path& a_from){
0633     m_node = a_from.m_node;
0634     m_tag = a_from.m_tag;
0635     return *this;
0636   }
0637 protected:
0638   bool match(const valop& a_node) {
0639     if(m_node) {
0640       if((&a_node)==m_node) return true;
0641     } else {
0642       if(a_node.m_tag==m_tag) return true;
0643     }
0644     return false;
0645   }
0646 public:
0647   valop* m_node;
0648   int m_tag;
0649   std::vector<valop*> m_path;
0650 };
0651 
0652 class get_named : public virtual valop_visitor {
0653 public:
0654   virtual bool binary(unsigned int,const valop& a_1,const valop& a_2) {
0655     if(!visit(a_1)) return false;
0656     if(!visit(a_2)) return false;
0657     return true; //continue searching
0658   }
0659 
0660   virtual bool unary(unsigned int,const valop& a_1) {
0661     if(!visit(a_1)) return false;
0662     return true;
0663   }
0664 
0665   virtual bool variable(unsigned int,const value&) {return true;}
0666   virtual bool option(const valop& a_node) {
0667     m_nodes.push_back((valop*)&a_node);
0668     return true;
0669   }
0670 
0671   virtual bool func_1(const valop&,const valop& a_1) {
0672     if(!visit(a_1)) return false;
0673     return true;
0674   }
0675 
0676   virtual bool func_2(const valop&,const valop& a_1,const valop& a_2) {
0677     if(!visit(a_1)) return false;
0678     if(!visit(a_2)) return false;
0679     return true;
0680   }
0681   virtual bool func_3(const valop&,
0682                       const valop& a_1,const valop& a_2,const valop& a_3) {
0683     if(!visit(a_1)) return false;
0684     if(!visit(a_2)) return false;
0685     if(!visit(a_3)) return false;
0686     return true;
0687   }
0688   virtual bool func_4(const valop&,
0689                       const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4) {
0690     if(!visit(a_1)) return false;
0691     if(!visit(a_2)) return false;
0692     if(!visit(a_3)) return false;
0693     if(!visit(a_4)) return false;
0694     return true;
0695   }
0696   virtual bool func_5(const valop&,
0697                  const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4,const valop& a_5) {
0698     if(!visit(a_1)) return false;
0699     if(!visit(a_2)) return false;
0700     if(!visit(a_3)) return false;
0701     if(!visit(a_4)) return false;
0702     if(!visit(a_5)) return false;
0703     return true;
0704   }
0705   virtual bool func_6(const valop&,
0706                       const valop& a_1,const valop& a_2,const valop& a_3,
0707                       const valop& a_4,const valop& a_5,const valop& a_6) {
0708     if(!visit(a_1)) return false;
0709     if(!visit(a_2)) return false;
0710     if(!visit(a_3)) return false;
0711     if(!visit(a_4)) return false;
0712     if(!visit(a_5)) return false;
0713     if(!visit(a_6)) return false;
0714     return true;
0715   }
0716 public:
0717   get_named(){}
0718   virtual ~get_named() {}
0719 public:
0720   get_named(const get_named& a_from):valop_visitor(a_from){}
0721   get_named& operator=(const get_named&){return *this;}
0722 public:
0723   std::vector<valop*> m_nodes;
0724 };
0725 
0726 class get_funcs : public virtual valop_visitor {
0727 public:
0728   virtual bool binary(unsigned int,const valop& a_1,const valop& a_2) {
0729     if(!visit(a_1)) return false;
0730     if(!visit(a_2)) return false;
0731     return true; //continue searching
0732   }
0733 
0734   virtual bool unary(unsigned int,const valop& a_1) {
0735     if(!visit(a_1)) return false;
0736     return true;
0737   }
0738 
0739   virtual bool variable(unsigned int,const value&) {return true;}
0740   virtual bool option(const valop&) {return true;}
0741 
0742   virtual bool func_1(const valop& a_node,const valop& a_1) {
0743     m_nodes.push_back((valop*)&a_node);
0744     if(!visit(a_1)) return false;
0745     return true;
0746   }
0747 
0748   virtual bool func_2(const valop& a_node,const valop& a_1,const valop& a_2) {
0749     m_nodes.push_back((valop*)&a_node);
0750     if(!visit(a_1)) return false;
0751     if(!visit(a_2)) return false;
0752     return true;
0753   }
0754   virtual bool func_3(const valop& a_node,
0755                       const valop& a_1,const valop& a_2,const valop& a_3) {
0756     m_nodes.push_back((valop*)&a_node);
0757     if(!visit(a_1)) return false;
0758     if(!visit(a_2)) return false;
0759     if(!visit(a_3)) return false;
0760     return true;
0761   }
0762   virtual bool func_4(const valop& a_node,
0763                       const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4) {
0764     m_nodes.push_back((valop*)&a_node);
0765     if(!visit(a_1)) return false;
0766     if(!visit(a_2)) return false;
0767     if(!visit(a_3)) return false;
0768     if(!visit(a_4)) return false;
0769     return true;
0770   }
0771   virtual bool func_5(const valop& a_node,
0772                  const valop& a_1,const valop& a_2,const valop& a_3,const valop& a_4,const valop& a_5) {
0773     m_nodes.push_back((valop*)&a_node);
0774     if(!visit(a_1)) return false;
0775     if(!visit(a_2)) return false;
0776     if(!visit(a_3)) return false;
0777     if(!visit(a_4)) return false;
0778     if(!visit(a_5)) return false;
0779     return true;
0780   }
0781   virtual bool func_6(const valop& a_node,
0782                       const valop& a_1,const valop& a_2,const valop& a_3,
0783                       const valop& a_4,const valop& a_5,const valop& a_6) {
0784     m_nodes.push_back((valop*)&a_node);
0785     if(!visit(a_1)) return false;
0786     if(!visit(a_2)) return false;
0787     if(!visit(a_3)) return false;
0788     if(!visit(a_4)) return false;
0789     if(!visit(a_5)) return false;
0790     if(!visit(a_6)) return false;
0791     return true;
0792   }
0793 public:
0794   get_funcs(){}
0795   virtual ~get_funcs() {}
0796 public:
0797   get_funcs(const get_funcs& a_from):valop_visitor(a_from){}
0798   get_funcs& operator=(const get_funcs&){return *this;}
0799 public:
0800   std::vector<valop*> m_nodes;
0801 };
0802 
0803 }
0804 
0805 #endif