Back to index

scribus-ng  1.3.4.dfsg+svn20071115
simple_actions.h
Go to the documentation of this file.
00001 /*
00002  *  simple_actions.h
00003  *  
00004  *
00005  *  Created by Andreas Vox on 02.06.06.
00006  *  Copyright 2006 under GPL2. All rights reserved.
00007  *
00008  */
00009 
00010 
00011 
00012 #ifndef SIMPLE_ACTIONS_H
00013 #define SIMPLE_ACTIONS_H
00014 
00015 #include "actions.h"
00016 /*****
00017 
00018     Defines the following actions:
00019 
00020     Factory<D>( fun )                               - -> D
00021     Factory<D>()                                    - -> D
00022     Prototype<D>( data )                            - -> D
00023     Top<O>( 3 )                                     O x x x -> O x x x O
00024     Getter<O,D>( fun )                              O -> O D
00025     Setter<O,D>( fun )                              O D -> O D
00026     SetterWithConversion<O,D,S>( fun )              O S -> O S
00027     SetAttribute<O,D>( fun, name, default)          O -> O
00028     SetAttribute<O,D>( fun, name)                   O -> O
00029     SetAttributeWithConversion<O,D>( f, n, c, def)  O -> O
00030     SetAttributeWithConversion<O,D>( f, n, convert) O -> O
00031     SetAttributes<O>( fun )                         O -> O
00032     SetText<O,D>( fun )                             O -> O
00033     AddText<O,D>( fun )                             O -> O
00034     Transform<D,E> ( fun )                          D -> E
00035     *TransformLater<D,E> ( fun )                     D -> E
00036     IdRef<O>()                                      O -> O
00037     Lookup<D>( name )                               - -> D
00038     PatchIdRefAttribute<O,D>( fun, name)            O -> O
00039     Result<O>()                                     O -> O
00040 
00041 *****/
00042 
00043 
00044 namespace desaxe {
00045 
00046        using namespace desaxe;
00047        
00052 template<class Obj_Type>
00053 class Factory_body : public Generator_body<Obj_Type>
00054 {
00055 public:
00056        typedef Obj_Type* (*FunType)();
00057        
00058        Factory_body() 
00059        : create_(NULL) 
00060     {}
00061        
00062        Factory_body(FunType create) 
00063        : create_(create) 
00064     {}
00065        
00066        void begin(const Xml_string&, Xml_attr)
00067     { 
00068               this->dig->push(create_? create_() : new Obj_Type()); 
00069     }  
00070 private:
00071     Obj_Type* (*create_)();
00072 };
00073 
00074 template <class Type>
00075 struct  Factory : public MakeGenerator<Factory_body<Type>, Type, typename Factory_body<Type>::FunType> 
00076 {
00077        Factory(typename Factory_body<Type>::FunType create)
00078        : MakeGenerator<Factory_body<Type>, Type, typename Factory_body<Type>::FunType>(create) {} 
00079 
00080        Factory()
00081        : MakeGenerator<Factory_body<Type>, Type, typename Factory_body<Type>::FunType>() {} 
00082 };
00083 
00084 
00088 template<class Obj_Type>
00089 class FactoryWithArgs_body : public Generator_body<Obj_Type>
00090 {
00091 public:
00092        typedef Obj_Type* (*FunType)(const Xml_string&, Xml_attr);
00093        
00094        FactoryWithArgs_body(FunType create) 
00095               : create_(create) 
00096     {}
00097        
00098        void begin(const Xml_string& name, Xml_attr attr)
00099     { 
00100               this->dig->push(create_(name, attr)); 
00101     }  
00102 private:
00103               Obj_Type* (*create_)(const Xml_string&, Xml_attr);
00104 };
00105 
00106 template <class Type>
00107 struct  FactoryWithArgs : public MakeGenerator<FactoryWithArgs_body<Type>, Type, typename FactoryWithArgs_body<Type>::FunType> 
00108 {
00109        FactoryWithArgs(typename FactoryWithArgs_body<Type>::FunType create)
00110        : MakeGenerator<FactoryWithArgs_body<Type>, Type, typename FactoryWithArgs_body<Type>::FunType>::MakeGenerator(create) {} 
00111 };
00112 
00113 
00118 template<class Obj_Type>
00119 class FactoryWithName_body : public Generator_body<Obj_Type>
00120 {
00121 public:
00122        typedef Obj_Type* (*FunType)(const Xml_string&);
00123        
00124        FactoryWithName_body() 
00125        : create_(NULL) 
00126        {}
00127        
00128        FactoryWithName_body(FunType create) 
00129        : create_(create) 
00130        {}
00131        
00132        void begin(const Xml_string& tag, Xml_attr)
00133        { 
00134               this->dig->push(create_? create_(tag) : new Obj_Type(tag)); 
00135        }      
00136 private:
00137        FunType create_;
00138 };
00139 
00140 template <class Type>
00141 struct  FactoryWithName : public MakeGenerator<FactoryWithName_body<Type>, Type, typename FactoryWithName_body<Type>::FunType> 
00142 { 
00143        FactoryWithName()
00144        : MakeGenerator<FactoryWithName_body<Type>, Type, typename FactoryWithName_body<Type>::FunType>::MakeGenerator() {} 
00145 
00146        FactoryWithName(typename FactoryWithName_body<Type>::FunType create)
00147        : MakeGenerator<FactoryWithName_body<Type>, Type, typename FactoryWithName_body<Type>::FunType>::MakeGenerator(create) {} 
00148 };
00149 
00150 
00154 template<class Obj_Type>
00155 class Prototype_body : public Generator_body<Obj_Type>
00156 {
00157 public:
00158        Prototype_body(const Obj_Type& proto) 
00159        : proto_(new Obj_Type(proto)) 
00160        {}
00161        
00162        ~Prototype_body() 
00163        { 
00164               delete proto_; 
00165        }
00166        
00167        void begin(const Xml_string&, Xml_attr)
00168        {
00169               this->dig->push(new Obj_Type(proto_));
00170        }
00171 private:
00172        const Obj_Type* proto_;
00173 };
00174 
00175 
00176 template <class Type>
00177 struct  Prototype : public MakeGenerator<Prototype_body<Type>, Type, const Type&> 
00178 {
00179        Prototype(const Type& def)
00180        : MakeGenerator<Prototype_body<Type>, Type, const Type&>::MakeGenerator(def) {}
00181 };
00182 
00183 
00184 
00188 template<class Obj_Type>
00189 class Top_body : public Generator_body<Obj_Type>
00190 {
00191 public:
00192        Top_body(unsigned int n) 
00193        : distance(n) 
00194        {}
00195               
00196        void begin(const Xml_string&, Xml_attr)
00197        {
00198               this->dig->push(this->dig->template top<Obj_Type>(distance));
00199        }
00200 private:
00201        unsigned int distance;
00202 };
00203 
00204 
00205 template <class Type>
00206 struct  Top : public MakeGenerator<Top_body<Type>, Type, unsigned int> 
00207 {
00208        Top(unsigned int distance)
00209        : MakeGenerator<Top_body<Type>, Type, unsigned int>::MakeGenerator(distance) {}
00210        Top()
00211        : MakeGenerator<Top_body<Type>, Type, unsigned int>::MakeGenerator(0) {}
00212 };
00213 
00214 
00215 
00220 template<class Obj_Type, class Data_Type>
00221 class Getter_body : public Generator_body<Data_Type>
00222 {
00223 public:
00224        typedef const Data_Type& (Obj_Type::*FunType)();
00225        
00226        Getter_body(FunType get) 
00227        : get_(get)
00228        {}
00229        
00230        void begin(const Xml_string&, Xml_attr)
00231        {
00232               Obj_Type* obj = this->dig->template top<Obj_Type>(1);
00233               Data_Type* data = (obj->*get_)();
00234               this->dig->push(data);
00235        }
00236 private:
00237        FunType get_; 
00238 };
00239 
00240 
00241 template <class Type, class Data>
00242 struct  Getter : public MakeGenerator<Getter_body<Type, Data>, Data, typename Getter_body<Type, Data>::FunType> 
00243 {
00244        Getter(typename Getter_body<Type, Data>::FunType get)
00245        : MakeGenerator<Getter_body<Type, Data>, Data, typename Getter_body<Type, Data>::FunType>::MakeGenerator(get) {} 
00246 };
00247 
00248 
00252 template<class Obj_Type, class Data_Type, class Store_Type>
00253 class SetterP_body : public Action_body 
00254 {
00255 public:
00256        typedef void (Obj_Type::*FunType)(Data_Type*);
00257        
00258        SetterP_body(FunType set) 
00259        : set_(set) 
00260        {}
00261        
00262        void end(const Xml_string&)
00263        { 
00264               Store_Type* data = this->dig->template top<Store_Type>(); 
00265               Obj_Type* obj = this->dig->template top<Obj_Type>(1);
00266 #ifdef DESAXE_DEBUG
00267               std::cerr << "setter(ptr): " << obj << " .= " << data << "\n";
00268 #endif
00269               (obj->*set_)( data ); 
00270        }      
00271 private:
00272        FunType set_;
00273 };
00274 
00275 
00276 template <class Type, class Data, class Store = Data>
00277 struct  SetterP : public MakeAction<SetterP_body<Type, Data, Store>, typename SetterP_body<Type, Data, Store>::FunType> 
00278 {
00279        SetterP(typename SetterP_body<Type, Data, Store>::FunType set)
00280        : MakeAction<SetterP_body<Type, Data, Store>, typename SetterP_body<Type, Data, Store>::FunType>(set) {} 
00281 };
00282 
00283 
00287 template<class Obj_Type, class Data_Type>
00288 class Setter_body : public Action_body 
00289 {
00290 public:
00291        typedef void (Obj_Type::*FunType)(Data_Type);
00292        
00293        Setter_body(FunType set) 
00294        : set_(set) 
00295        {}
00296        
00297        void end(const Xml_string&)
00298        { 
00299               Data_Type* data = this->dig->template top<Data_Type>(); 
00300               Obj_Type* obj = this->dig->template top<Obj_Type>(1);
00301 #ifdef DESAXE_DEBUG
00302               std::cerr << "setter: " << obj << " .= *(" << data << ")\n";
00303 #endif
00304               (obj->*set_)( *data ); 
00305        }      
00306 private:
00307        FunType set_;
00308 };
00309 
00310 
00311 template <class Type, class Data>
00312 struct  Setter : public MakeAction<Setter_body<Type, Data>, typename Setter_body<Type, Data>::FunType> 
00313 {
00314        Setter(typename Setter_body<Type, Data>::FunType set)
00315        : MakeAction<Setter_body<Type, Data>, typename Setter_body<Type, Data>::FunType>(set) {} 
00316 };
00317 
00318 
00322 template<class Obj_Type, class Data_Type, class Store_Type>
00323 class SetterWithConversion_body : public Action_body 
00324 {
00325 public:
00326        typedef void (Obj_Type::*FunType)(Data_Type);
00327        typedef Data_Type (*ConvType)(Store_Type);
00328        
00329        SetterWithConversion_body(FunType set, ConvType conv) 
00330               : set_(set), conv_(conv)
00331        {}
00332        
00333        void end(const Xml_string&)
00334        { 
00335               Store_Type* data = this->dig->template top<Store_Type>(); 
00336               Obj_Type* obj = this->dig->template top<Obj_Type>(1);
00337 #ifdef DESAXE_DEBUG
00338               std::cerr << "setter: " << obj << " .= " << conv_ << "(*" << data << ")\n";
00339 #endif
00340               if (conv_)
00341                      (obj->*set_)( conv_(*data) );
00342               else
00343                      (obj->*set_)( static_cast<Data_Type>(*data) ); 
00344        }      
00345 private:
00346               FunType set_;
00347        ConvType conv_;
00348 };
00349 
00350 
00351 template <class Type, class Data, class Store>
00352 struct  SetterWithConversion : public MakeAction<SetterWithConversion_body<Type, Data, Store>, typename SetterWithConversion_body<Type, Data, Store>::FunType, typename SetterWithConversion_body<Type, Data, Store>::ConvType> 
00353 {
00354        typedef SetterWithConversion_body<Type, Data, Store> BodyType;
00355        SetterWithConversion(typename SetterWithConversion_body<Type, Data, Store>::FunType set)
00356        : MakeAction<SetterWithConversion_body<Type, Data, Store>, typename SetterWithConversion_body<Type, Data, Store>::FunType, typename SetterWithConversion_body<Type, Data, Store>::ConvType>(set, NULL) {} 
00357        SetterWithConversion(typename BodyType::FunType set, typename SetterWithConversion_body<Type, Data, Store>::ConvType conv)
00358        : MakeAction<SetterWithConversion_body<Type, Data, Store>, typename SetterWithConversion_body<Type, Data, Store>::FunType, typename SetterWithConversion_body<Type, Data, Store>::ConvType>(set, conv) {} 
00359 };
00360 
00361 
00365 template<class Obj_Type>
00366 class SetAttributes_body : public Action_body
00367 {
00368 public:
00369        typedef void (Obj_Type::*FunType)(const Xml_string&, const Xml_string&) ;
00370        
00371        SetAttributes_body(FunType set) : set_(set) 
00372        {}
00373        
00374        void begin(const Xml_string&, Xml_attr attr)
00375        {
00376               Obj_Type* obj = this->dig->template top<Obj_Type>();
00377               Xml_attr::iterator it;
00378               for(it=attr.begin(); it != attr.end(); ++it)
00379                      (obj->*set_)( Xml_key(it), Xml_data(it) ); 
00380        }      
00381 private:
00382        FunType set_;
00383 };
00384 
00385 
00386 template <class Type>
00387 struct  SetAttributes : public MakeAction<SetAttributes_body<Type>, typename SetAttributes_body<Type>::FunType> 
00388 {
00389        SetAttributes(typename SetAttributes_body<Type>::FunType set)
00390        : MakeAction<SetAttributes_body<Type>, typename SetAttributes_body<Type>::FunType>(set) {} 
00391 };
00392 
00393 
00394 
00399 template<class Obj_Type, class Data_Type>
00400 class SetAttribute_body : public Action_body
00401 {
00402 public:
00403        typedef void (Obj_Type::*FunType)(Data_Type) ;
00404        
00405        SetAttribute_body(FunType set, const Xml_string& name) 
00406               : set_(set), name_(name), default_(), hasDefault_(false)
00407        {}
00408        
00409        SetAttribute_body(FunType set, const Xml_string& name, Data_Type deflt) 
00410               : set_(set), name_(name), default_(deflt), hasDefault_(true)
00411        {}
00412               
00413        void begin(const Xml_string&, Xml_attr attr)
00414        {
00415               Obj_Type* obj = this->dig->template top<Obj_Type>();
00416               Xml_attr::iterator it = attr.find(name_);
00417               if (it != attr.end() )
00418                      (obj->*set_)( Data_Type(Xml_data(it)) );
00419               else if (hasDefault_)
00420                      (obj->*set_)( default_ );                 
00421        }      
00422 private:
00423        FunType set_;
00424        Xml_string name_;
00425        Data_Type default_;
00426        bool hasDefault_;
00427 };
00428 
00429 
00430 template <class Type, class Data>
00431 struct  SetAttribute : public MakeAction<SetAttribute_body<Type,Data>, typename SetAttribute_body<Type,Data>::FunType, const Xml_string&, Data> 
00432 {
00433        SetAttribute(typename SetAttribute_body<Type,Data>::FunType set, const Xml_string& name)
00434        : MakeAction<SetAttribute_body<Type,Data>, typename SetAttribute_body<Type,Data>::FunType, const Xml_string&, Data>(set,name) {} 
00435 
00436        SetAttribute(typename SetAttribute_body<Type,Data>::FunType set, const Xml_string& name, Data deflt)
00437        : MakeAction<SetAttribute_body<Type,Data>, typename SetAttribute_body<Type,Data>::FunType, const Xml_string&, Data>(set,name,deflt) {} 
00438 };
00439 
00440 
00441 
00446 template<class Obj_Type, class Data_Type>
00447 class SetAttributeWithConversion_body : public Action_body
00448 {
00449 public:
00450        typedef void (Obj_Type::*FunType)(Data_Type) ;
00451        typedef Data_Type (*ConvType)(const Xml_string&);
00452        
00453        SetAttributeWithConversion_body(FunType set, const Xml_string& name, ConvType conv) 
00454               : set_(set), name_(name), conv_(conv), default_(), hasDefault_(false)
00455        {}
00456        
00457        SetAttributeWithConversion_body(FunType set, const Xml_string& name, ConvType conv, Data_Type deflt) 
00458               : set_(set), name_(name), conv_(conv), default_(deflt), hasDefault_(true)
00459        {}
00460        
00461        void begin(const Xml_string&, Xml_attr attr)
00462        {
00463               Obj_Type* obj = this->dig->template top<Obj_Type>();
00464               Xml_attr::iterator it = attr.find(name_);
00465               if (it != attr.end() && conv_)
00466                      (obj->*set_)( conv_(Xml_data(it)) );
00467               else if (hasDefault_)
00468                      (obj->*set_)( default_ );                 
00469        }      
00470 private:
00471        FunType set_;
00472        Xml_string name_;
00473        ConvType conv_;
00474        Data_Type default_;
00475        bool hasDefault_;
00476 };
00477 
00478 
00479 template <class Type, class Data>
00480 struct  SetAttributeWithConversion : public MakeAction<SetAttributeWithConversion_body<Type,Data>, typename SetAttributeWithConversion_body<Type,Data>::FunType, const Xml_string&, typename SetAttributeWithConversion_body<Type,Data>::ConvType, Data> 
00481 {      
00482        typedef SetAttributeWithConversion_body<Type,Data> BodyType;
00483        
00484        SetAttributeWithConversion(typename BodyType::FunType set, const Xml_string& name, typename BodyType::ConvType conv)
00485        : MakeAction<BodyType, typename BodyType::FunType, const Xml_string&, typename BodyType::ConvType, Data>(set,name,conv) {} 
00486        
00487        SetAttributeWithConversion(typename BodyType::FunType set, const Xml_string& name, typename BodyType::ConvType conv, Data deflt)
00488        : MakeAction<BodyType, typename BodyType::FunType, const Xml_string&, typename BodyType::ConvType, Data>(set,name,conv,deflt) {} 
00489 };
00490 
00491 
00492 
00497 template<class Obj_Type>
00498 class AddText_body : public Action_body
00499 {
00500 public:
00501        typedef void (Obj_Type::*FunType)(const Xml_string&);
00502        
00503        AddText_body(FunType add) : addT(add) 
00504        {}
00505        
00506        void chars(const Xml_string& txt)
00507        {
00508               Obj_Type* obj = this->dig->template top<Obj_Type>();
00509               (obj->*addT)( txt ); 
00510        }      
00511 private:
00512        FunType addT;
00513 };
00514 
00515 
00516 
00517 template <class Type>
00518 struct  AddText : public MakeAction<AddText_body<Type>, typename AddText_body<Type>::FunType> 
00519 {
00520        AddText(typename AddText_body<Type>::FunType set)
00521        : MakeAction<AddText_body<Type>, typename AddText_body<Type>::FunType>(set) {} 
00522 };
00523 
00524 
00525 
00526 
00533 template<class Obj_Type>
00534 class SetText_body : public Action_body
00535 {
00536 public:
00537        typedef void (Obj_Type::*FunType)(const Xml_string&);
00538        
00539        SetText_body(FunType set) : setT(set) 
00540        {}
00541        
00542        void begin(const Xml_string&, Xml_attr)
00543        {
00544               txt = "";
00545        }
00546        
00547        void chars(const Xml_string& chunk)
00548        {
00549               txt += chunk;
00550        }
00551        
00552        void end(const Xml_string& tag)
00553        {
00554               Obj_Type* obj = this->dig->template top<Obj_Type>();
00555               (obj->*setT)( txt ); 
00556        }      
00557        
00558 private:
00559        FunType setT;
00560        Xml_string txt;
00561 };
00562 
00563 
00564 
00565 template <class Type>
00566 struct  SetText : public MakeAction<SetText_body<Type>, typename SetText_body<Type>::FunType> 
00567 {
00568        typedef SetText_body<Type> BodyType;
00569        SetText(typename BodyType::FunType set)
00570        : MakeAction<BodyType, typename BodyType::FunType>(set) {} 
00571 };
00572 
00573 
00574 
00575 
00576 template<class Obj_Type>
00577 class Store_body : public Action_body
00578 {
00579 public:
00580        Store_body(const Xml_string& name) : m_name(name) {}
00581        
00582        void begin(const Xml_string& tag, Xml_attr attr)
00583        {
00584               Obj_Type* obj = this->dig->template top<Obj_Type>();
00585 //            qDebug(QString("Store: %1 <- %2").arg(tag).arg(typeid(obj).name()));
00586               this->dig->template store<Obj_Type>(m_name, obj);
00587        }
00588 
00589 private:
00590        Xml_string m_name;
00591 };
00592 
00593 
00594 template <class Type>
00595 struct  Store : public MakeAction<Store_body<Type>, const Xml_string& > 
00596 {
00597        Store(const Xml_string& name) : MakeAction<Store_body<Type>, const Xml_string& >(name) {}
00598 };
00599 
00600 
00601 
00613 template<class Obj_Type>
00614 class IdRef_body : public Action_body
00615 {
00616 public:
00617        IdRef_body() : stack() {}
00618        
00619        void begin(const Xml_string&, Xml_attr attr)
00620        {
00621               Obj_Type* obj = this->dig->template top<Obj_Type>();
00622               Mode mode;
00623               Xml_attr::iterator it = attr.find("id");
00624               if (it != attr.end())
00625               {
00626                      mode.ID = attr["id"];
00627                      mode.isIdRef = false;
00628               }
00629               else {
00630                      Xml_attr::iterator it = attr.find("idref");
00631                      if (it != attr.end())
00632                      {
00633                             mode.ID = attr["idref"];
00634                             mode.isIdRef = true;
00635                      }
00636                      else {
00637                             mode.ID = "";
00638                             mode.isIdRef = false;
00639                      }
00640               }
00641               if (mode.ID != "")
00642               {
00643                      Obj_Type* storedObj = this->dig->template lookup<Obj_Type>(mode.ID);
00644                      if ( !storedObj )
00645                      {
00646                             this->dig->store(mode.ID, obj);
00647                      }
00648                      else if ( !mode.isIdRef )
00649                      {
00650                             delete (this->dig->template top<Obj_Type>());
00651                             this->dig->pop();
00652                             this->dig->push(this->dig->template lookup<Obj_Type>(mode.ID));
00653                      }
00654                      else
00655                      {
00656                             // NYI: set trigger
00657                      }
00658               }
00659               stack.push_back(mode);
00660               
00661        }
00662        void end(const Xml_string&)
00663        {
00664               Mode mode = stack.back();
00665               stack.pop_back();
00666               if (mode.isIdRef)
00667               {
00668                      delete (this->dig->template top<Obj_Type>());
00669                      this->dig->pop();
00670                      this->dig->push(this->dig->template lookup<Obj_Type>(mode.ID));
00671                      // NYI reset trigger
00672               }
00673        }
00674 private:
00675        struct Mode { Xml_string ID; bool isIdRef; };
00676        std::vector<Mode> stack;
00677 };
00678 
00679 
00680 template <class Type>
00681 struct  IdRef : public MakeAction<IdRef_body<Type> > 
00682 {};
00683 
00684 
00690 template<class Data_Type>
00691 class Lookup_body : public Generator_body<Data_Type>
00692 {
00693 public:
00694        Lookup_body(const Xml_string& ID) 
00695               : ID_(ID)
00696        {}
00697        
00698        void begin(const Xml_string&, Xml_attr)
00699        {
00700               Data_Type* data = this->dig->template lookup<Data_Type>(ID_);
00701               this->dig->push(data);
00702        }
00703 private:
00704        Xml_string ID_;      
00705 };
00706 
00707 
00708 template <class Data>
00709 struct  Lookup : public MakeGenerator<Lookup_body<Data>, const Xml_string&> 
00710 {
00711        Lookup(Xml_string ID)
00712        : MakeGenerator<Lookup_body<Data>, const Xml_string&>::MakeGenerator(ID) {} 
00713 };
00714 
00715 
00716 
00720 template<class Obj_Type, class Arg_Type>
00721 class Transform_body : public Action_body 
00722 {
00723 public:
00724        typedef Obj_Type (*FunType)(const Arg_Type&);
00725        
00726        Transform_body(FunType fun) 
00727               : fun_(fun), stack()
00728        {}
00729        
00730        void begin(const Xml_string&, Xml_attr)
00731        { 
00732               Cell cell;
00733               cell.arg = this->dig->template top<Arg_Type>(); 
00734               cell.obj = fun_(*cell.arg);
00735 #ifdef DESAXE_DEBUG
00736               std::cerr << "transform: " << cell.arg << " -> " << cell.obj << ")\n";
00737 #endif
00738               stack.push_back(cell);
00739               this->dig->pop();
00740               this->dig->push(&cell.obj); 
00741        }      
00742 
00743        void end(const Xml_string&)
00744        {
00745               Cell cell = stack.back();
00746               stack.pop_back();
00747               this->dig->pop();
00748               this->dig->push(cell.arg); 
00749        }
00750 private:
00751               FunType fun_;
00752        struct Cell { Arg_Type* arg; Obj_Type obj; }; 
00753        std::vector<Cell> stack;
00754 };
00755 
00756 
00757 template <class Type, class Arg>
00758 struct  Transform : public MakeAction<Transform_body<Type, Arg>, typename Transform_body<Type, Arg>::FunType> 
00759 {
00760        typedef Transform_body<Type, Arg> BodyType;
00761        Transform(typename BodyType::FunType f) : MakeAction<BodyType, typename BodyType::FunType>(f) {} 
00762 };
00763 
00764 
00765 
00766 
00767 template<class Obj_Type, class Data_Type>
00768 class PatchIdRefAttribute_body : public Action_body
00769 {
00770 public:
00771        typedef void (Obj_Type::*FunType)(Data_Type*) ;
00772        
00773        PatchIdRefAttribute_body(FunType set, const Xml_string& name) 
00774               : set_(set), name_(name)
00775        {}
00776        
00777        void begin(const Xml_string&, Xml_attr attr)
00778        {
00779               Xml_attr::iterator it = attr.find(name_);
00780               if (it != attr.end())
00781               {
00782                      Obj_Type* obj = this->dig->template top<Obj_Type>();
00783                      this->dig->template patchInvoke<Obj_Type,Data_Type>(Xml_data(it), obj, set_);
00784               }
00785        }      
00786 private:
00787        FunType set_;
00788        Xml_string name_;
00789 };
00790 
00791 
00792 template <class Type, class Data>
00793 struct  PatchIdRefAttribute : public MakeAction<PatchIdRefAttribute_body<Type,Data>, typename PatchIdRefAttribute_body<Type,Data>::FunType, const Xml_string&> 
00794 {
00795        typedef PatchIdRefAttribute_body<Type,Data> BodyType;
00796        PatchIdRefAttribute(typename BodyType::FunType set, const Xml_string& name)
00797        : MakeAction<BodyType, typename BodyType::FunType, const Xml_string&>(set,name) {} 
00798 };
00799 
00800 
00801 
00802 
00806 template<class Data_Type>
00807 class Result_body : public Action_body 
00808 {
00809 public:
00810        Result_body() 
00811        {}
00812        
00813        void end(const Xml_string&)
00814        { 
00815               this->dig->setResult(dig->template top<Data_Type>());
00816        }
00817 };
00818 
00819 
00820 
00821 template <class Data>
00822 struct  Result : public MakeAction<Result_body<Data> > {};
00823 
00824 
00825 } // namespace
00826 
00827 #endif