Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

functional.hpp

Go to the documentation of this file.
00001 #ifndef s11n_net_s11n_1_1_FUNCTIONAL_HPP_INCLUDED
00002 #define s11n_net_s11n_1_1_FUNCTIONAL_HPP_INCLUDED 1
00003 // Experimental code for s11n, with an emphasis on the "mental" part.
00004 // Here be beg, borrow, and steal many ideas from metatemplate and
00005 // functional libraries, like Boost.MPL.
00006 
00007 #include <s11n.net/s11n/tags.hpp>
00008 
00009 namespace s11n {
00010 
00011     /**
00012        Holds a [const] reference to an object. For use in template
00013        metaprogramming. Don't use this type directly: it is intended
00014        to be subclassed by reference_f<> types.
00015 
00016        T must not be pointer-qualified. Const is fine.
00017 
00018        Added in 1.1.3.
00019     */
00020     template <typename T>
00021     struct reference_base_f
00022     {
00023         typedef T type;
00024         type & value;
00025         explicit reference_base_f( type & _ref ) : value(_ref)
00026         {}
00027 
00028         /**
00029            Returns a copy of the object this one refers to.
00030         */
00031         inline operator T() const
00032         {
00033             return this->value;
00034         }
00035 
00036         /**
00037            Returns a [const] reference to the object this one
00038            refers to.
00039         */
00040         inline type & operator()() const
00041         {
00042             return this->value;
00043         }
00044 
00045     };
00046 
00047     /**
00048        Holds a reference to an object. For use in template
00049        metaprogramming.
00050 
00051        Added in 1.1.3.
00052     */
00053     template <typename T>
00054     struct reference_f : reference_base_f<T>
00055     {
00056         typedef typename reference_base_f<T>::type type;
00057         explicit reference_f( type & _ref ) : reference_base_f<T>(_ref)
00058         {}
00059 
00060         template <typename X>
00061         inline const reference_f & operator=( const X & val ) const
00062         {
00063             this->value = val;
00064             return *this;
00065         }
00066     };
00067 
00068     /**
00069        Holds a const reference to an object. For use in template
00070        metaprogramming.
00071 
00072        Added in 1.1.3.
00073     */
00074     template <typename T>
00075     struct reference_f<T const> : reference_base_f<T const>
00076     {
00077         typedef typename reference_base_f<T const>::type type;
00078         explicit reference_f( type & _ref ) : reference_base_f<T const>(_ref)
00079         {}
00080     };
00081 
00082     /**
00083        Added in 1.1.3.
00084     */
00085     template <typename T>
00086     struct reference_f<T *> : reference_base_f<T>
00087     {
00088         /** _ref must not be 0. */
00089         typedef typename reference_base_f<T>::type type;
00090         explicit reference_f( type * _ref ) : reference_base_f<T>(*_ref)
00091         {}
00092     };
00093 
00094     /**
00095        Added in 1.1.3.
00096     */
00097     template <typename T>
00098     struct reference_f<T const *> : reference_base_f<T const>
00099     {
00100         /** _ref must not be 0. */
00101         typedef typename reference_base_f<T const>::type type;
00102         explicit reference_f( type * _ref ) : reference_base_f<T const>(*_ref)
00103         {}
00104     };
00105 
00106 
00107     /**
00108        Convenience function to return reference_f<T>(ref).
00109 
00110        Added in 1.1.3.
00111     */
00112     template <typename T>
00113     inline reference_f<T> ref( T & ref )
00114     {
00115         return reference_f<T>(ref);
00116     }
00117 
00118 
00119     /**
00120        Pointer equivalent of reference_base_f.
00121 
00122        Added in 1.1.3.
00123 
00124        T may be const or not, but should not have a pointer
00125        qualification. Specializations of pointer_f take care of
00126        getting rid of the extra const/pointer/reference
00127        qualifiers.
00128     */
00129     template <typename T>
00130     struct pointer_base_f
00131     {
00132         /** Same as T, possibly const-qualified. */
00133         typedef T type;
00134         type * value;
00135         explicit pointer_base_f( type * _ref ) : value(_ref)
00136         {}
00137         explicit pointer_base_f( type & _ref ) : value(&_ref)
00138         {}
00139         /**
00140            Returns a [const] pointer to the object this one
00141            refers to.
00142         */
00143         inline type * operator()() const
00144         {
00145             return this->value;
00146         }
00147 
00148         /** For convention's sake... */
00149         inline type * get() const
00150         {
00151             return this->value;
00152         }
00153 
00154         inline type * operator->() const
00155         {
00156             return this->value;
00157         }
00158 
00159         inline bool empty() const
00160         {
00161             return 0 != this->value;
00162         }
00163     };
00164 
00165     /**
00166        Pointer equivalent of reference_f.
00167        Added in 1.1.3.
00168     */
00169     template <typename T>
00170     struct pointer_f : pointer_base_f<T>
00171     {
00172         typedef typename pointer_base_f<T>::type type;
00173         explicit pointer_f( type & _ref ) : pointer_base_f<T>(&_ref)
00174         {}
00175         explicit pointer_f( type * _ref ) : pointer_base_f<T>(_ref)
00176         {}
00177     };
00178 
00179     /**
00180        Pointer equivalent of reference_f.
00181        Added in 1.1.3.
00182     */
00183     template <typename T>
00184     struct pointer_f<T const> : pointer_base_f<T const>
00185     {
00186         typedef typename pointer_base_f<T const>::type type;
00187         explicit pointer_f( type & _ref ) : pointer_base_f<T const>(&_ref)
00188         {}
00189         explicit pointer_f( type * _ref ) : pointer_base_f<T const>(_ref)
00190         {}
00191 
00192     };
00193 
00194     /**
00195        Pointer equivalent of reference_f.
00196        Added in 1.1.3.
00197     */
00198     template <typename T>
00199     struct pointer_f<T *> : pointer_base_f<T>
00200     {
00201         typedef typename pointer_base_f<T>::type type;
00202         explicit pointer_f( type * _ref ) : pointer_base_f<T>(_ref)
00203         {}
00204         explicit pointer_f( type & _ref ) : pointer_base_f<T>(&_ref)
00205         {}
00206     };
00207 
00208     /**
00209        Pointer equivalent of reference_f.
00210        Added in 1.1.3.
00211     */
00212     template <typename T>
00213     struct pointer_f<T const *> : pointer_base_f<T const>
00214     {
00215         typedef typename pointer_base_f<T const>::type type;
00216         explicit pointer_f( type * _ref ) : pointer_base_f<T const>(_ref)
00217         {}
00218         explicit pointer_f( type & _ref ) : pointer_base_f<T const>(&_ref)
00219         {}
00220     };
00221 
00222 //  /** Returns pointer_f<T>(v). */
00223 //  template <typename T>
00224 //  inline pointer_f<T> pointer( typename type_traits<T>::type & v )
00225 //  {
00226 //      return pointer_f<T>(v);
00227 //  }
00228 
00229 //      template <typename T>
00230 //      inline pointer_f<T> pointer( typename type_traits<T>::type * v )
00231 //      {
00232 //          return pointer_f<T>(v);
00233 //      }
00234 
00235 //      template <typename T>
00236 //      inline pointer_f<T const> pointer( typename type_traits<T const>::type const & v )
00237 //      {
00238 //          return pointer_f<T const>(v);
00239 //      }
00240 
00241 //      template <typename T>
00242 //      inline pointer_f<T const> pointer( typename type_traits<T const>::type const * v )
00243 //      {
00244 //          return pointer_f<T const>(v);
00245 //      }
00246 
00247 
00248     /**
00249        Holds a value. For use in template metaprogramming.
00250 
00251        Added in 1.1.3.
00252     */
00253     template <typename T>
00254     struct value_f
00255     {
00256         typedef T type;
00257         type value;
00258         value_f( type const & _ref ) : value(_ref)
00259         {}
00260 
00261         /** Returns a copy of this->value. */
00262         inline operator T() const
00263         {
00264             return this->value;
00265         }
00266 
00267         /** Returns a copy of this->value. */
00268         inline type operator()() const
00269         {
00270             return this->value;
00271         }
00272     };
00273 
00274     /** Quasi-bogus specialization. */
00275     template <typename T>
00276     struct value_f<T const> : value_f<T> {};
00277 
00278     /** Quasi-bogus specialization. */
00279     template <typename T>
00280     struct value_f<T &> : value_f<T> {};
00281 
00282     /** Quasi-bogus specialization. */
00283     template <typename T>
00284     struct value_f<T const &> : value_f<T> {};
00285 
00286 
00287     /** Returns value_f<T>(v). */
00288     template <typename T>
00289     inline value_f<T> val( const T & v )
00290     {
00291         return value_f<T>(v);
00292     }
00293 
00294 
00295 
00296     /**
00297        A functor which simply forwards its arguments to
00298        s11n::serialize().
00299 
00300        Added in 1.1.3.
00301     */
00302     struct serialize_f : serialize_binary_f_tag
00303     {
00304         template <typename NT, typename ST>
00305         inline bool operator()( NT & dest, const ST & src ) const
00306         {
00307             return serialize<NT,ST>( dest, src );
00308         }
00309     };
00310 
00311     /**
00312        A functor which simply forwards its arguments to
00313        s11n::deserialize().
00314 
00315        Added in 1.1.3.
00316     */
00317     struct deserialize_f : deserialize_binary_f_tag
00318     {
00319         template <typename NT, typename ST>
00320         inline bool operator()( const NT & src, ST & dest ) const
00321         {
00322             return deserialize<NT,ST>( src, dest );
00323         }
00324     };
00325 
00326 
00327     /**
00328        Conforms to serialize_nullary_f_tag expectations
00329        and converts a serialize_binary_f_tag type to
00330        serialize_nullary_f_tag type.
00331 
00332        BinaryFunctorT must comply to serialize_binary_f_tag's
00333        expectations.
00334 
00335        Under NO circumstances may you pass TEMPORARY as a SerializableT
00336        argument to one of the ctors. This is strictly illegal, as
00337        we hold a reference to the object.
00338 
00339        Added in 1.1.3.
00340     */
00341     template <typename NodeType,typename SerializableT, typename BinaryFunctorT = serialize_f>
00342     struct serialize_nullary_f : serialize_nullary_f_tag
00343     {
00344         reference_f<NodeType> node;
00345         reference_f<SerializableT const> serializable;
00346         BinaryFunctorT functor;
00347         serialize_nullary_f( NodeType & n, SerializableT const & s )
00348             : node(n), serializable(s), functor()
00349         {
00350         }
00351 
00352         serialize_nullary_f( NodeType & n, SerializableT const & s, BinaryFunctorT const & f ): node(n), serializable(s), functor(f)
00353         {
00354         }
00355         /** Returns this->functor( this->node, this->serializable ). */
00356         inline bool operator()() const
00357         {
00358             return this->functor( this->node(), this->serializable() );
00359         }
00360     };
00361 
00362     /**
00363        Returns serialize_nullary_f<NodeType,SerializableT,BinaryFunctorT>( n, s, f ).
00364     */
00365     template <typename NodeType,typename SerializableT, typename BinaryFunctorT>
00366     inline serialize_nullary_f<NodeType,SerializableT,BinaryFunctorT>
00367     ser_nullary_f( NodeType & n, SerializableT const & s, BinaryFunctorT const & f )
00368     {
00369         return serialize_nullary_f<NodeType,SerializableT,BinaryFunctorT>( n, s, f );
00370     }
00371 
00372     /**
00373        Returns serialize_nullary_f<NodeType,SerializableT>( n, s ).
00374     */
00375     template <typename NodeType,typename SerializableT>
00376     inline serialize_nullary_f<NodeType,SerializableT>
00377     ser_nullary_f( NodeType & n, SerializableT const & s )
00378     {
00379         return serialize_nullary_f<NodeType,SerializableT>( n, s );
00380     }
00381 
00382     /**
00383        Converts an S-Node to a unary functor taking a Serializable
00384        argument.
00385 
00386        BinaryFunctorT must comply to serialize_binary_f_tag.
00387     */
00388     template <typename NodeType, typename BinaryFunctorT = serialize_f>
00389     struct node_to_serialize_unary_f : serialize_unary_serializable_f_tag
00390     {
00391         //typedef NodeType type;
00392         reference_f<NodeType> node;
00393         BinaryFunctorT functor;
00394         node_to_serialize_unary_f( NodeType & n ) : node(n), functor() {}
00395         node_to_serialize_unary_f( NodeType & n, BinaryFunctorT const & f ) : node(n), functor(f) {}
00396 
00397         template <typename SerT>
00398         inline bool operator()( const SerT & src ) const
00399         {
00400             return this->functor( this->node(), src );
00401         }
00402     };
00403 
00404     /**
00405        Returns node_to_serialize_unary_f<NodeType,BinaryFunctorT>(n,f).
00406     */
00407     template <typename NodeType, typename BinaryFunctorT>
00408     node_to_serialize_unary_f<NodeType,BinaryFunctorT>
00409     node_to_ser_unary_f( NodeType & n, BinaryFunctorT f )
00410     {
00411         return node_to_serialize_unary_f<NodeType,BinaryFunctorT>(n,f);
00412     }
00413 
00414     /**
00415        Returns node_to_serialize_unary_f<NodeType>(n).
00416     */
00417     template <typename NodeType>
00418     node_to_serialize_unary_f<NodeType>
00419     node_to_ser_unary_f( NodeType & n )
00420     {
00421         return node_to_serialize_unary_f<NodeType>(n);
00422     }
00423 
00424 
00425     /**
00426        Converts an S-Node to a unary functor taking a Serializable
00427        argument.
00428 
00429        BinaryFunctorT must comply to deserialize_binary_f_tag.
00430     */
00431     template <typename NodeType, typename BinaryFunctorT = deserialize_f>
00432     struct node_to_deserialize_unary_f : deserialize_unary_serializable_f_tag
00433     {
00434         //typedef NodeType type;
00435         reference_f<NodeType const> node;
00436         BinaryFunctorT functor;
00437         node_to_deserialize_unary_f( NodeType const & n ) : node(n), functor() {}
00438         node_to_deserialize_unary_f( NodeType const & n, BinaryFunctorT const & f ) : node(n), functor(f) {}
00439         template <typename SerT>
00440         inline bool operator()( SerT & dest ) const
00441         {
00442             return this->functor( this->node(), dest );
00443         }
00444     };
00445 
00446     /**
00447        Returns node_to_deserialize_unary_f<NodeType,BinaryFunctorT>(n,f).
00448     */
00449     template <typename NodeType, typename BinaryFunctorT>
00450     node_to_deserialize_unary_f<NodeType,BinaryFunctorT>
00451     node_to_deser_unary_f( NodeType const & n, BinaryFunctorT const & f )
00452     {
00453         return node_to_deserialize_unary_f<NodeType,BinaryFunctorT>(n,f);
00454     }
00455 
00456     /**
00457        Returns node_to_deserialize_unary_f<NodeType>(n).
00458     */
00459     template <typename NodeType>
00460     inline node_to_deserialize_unary_f<NodeType>
00461     node_to_deser_unary_f( NodeType const & n )
00462     {
00463         return node_to_deserialize_unary_f<NodeType>(n);
00464     }
00465 
00466 
00467     /**
00468        Converts a Serializable to a type compliant with
00469        serialize_unary_node_f_tag.
00470 
00471        BinaryFunctorT must comply to serialize_binary_f_tag.
00472 
00473        Added in 1.1.3.
00474     */
00475     template <typename SerT, typename BinaryFunctorT = serialize_f>
00476     struct serializable_to_serialize_unary_f : serialize_unary_node_f_tag
00477     {
00478         typedef SerT type;
00479         reference_f<SerT const> serializable;
00480         BinaryFunctorT functor;
00481         serializable_to_serialize_unary_f( SerT const & n ) : serializable(n), functor() {}
00482         serializable_to_serialize_unary_f( SerT const & n, BinaryFunctorT const & f ) : serializable(n), functor(f) {}
00483 
00484         template <typename NodeT>
00485         inline bool operator()( NodeT & dest ) const
00486         {
00487             return this->functor( dest, this->serializable() );
00488         }
00489     };
00490 
00491     /**
00492        Returns serializable_to_serialize_unary_f<SerT,BinaryFunctorT>( s, f ).
00493     */
00494     template <typename SerT, typename BinaryFunctorT>
00495     inline serializable_to_serialize_unary_f<SerT,BinaryFunctorT>
00496     ser_to_ser_unary_f( SerT const & s, BinaryFunctorT const & f )
00497     {
00498         return serializable_to_serialize_unary_f<SerT,BinaryFunctorT>( s, f );
00499     }
00500 
00501     /**
00502        Returns serializable_to_serialize_unary_f<SerT>( s ).
00503     */
00504     template <typename SerT>
00505     inline serializable_to_serialize_unary_f<SerT>
00506     ser_to_ser_unary_f( SerT const & s)
00507     {
00508         return serializable_to_serialize_unary_f<SerT>( s );
00509     }
00510     
00511 
00512     /**
00513        Converts a Serializable to a type compliant with
00514        deserialize_unary_node_f_tag.
00515 
00516        BinaryFunctorT must comply to deserialize_binary_f_tag.
00517 
00518        Added in 1.1.3.
00519     */
00520     template <typename SerT, typename BinaryFunctorT = deserialize_f>
00521     struct serializable_to_deserialize_unary_f : deserialize_unary_node_f_tag
00522     {
00523         typedef SerT type;
00524         reference_f<SerT> serializable;
00525         BinaryFunctorT functor;
00526         serializable_to_deserialize_unary_f( SerT & n ) : serializable(n), functor() {}
00527         serializable_to_deserialize_unary_f( SerT & n, BinaryFunctorT const & f ) : serializable(n), functor(f) {}
00528 
00529         template <typename NodeT>
00530         inline bool operator()( NodeT const & src ) const
00531         {
00532             return this->functor( src, this->serializable() );
00533         }
00534     };
00535 
00536     /**
00537        Returns serializable_to_deserialize_unary_f<SerT,BinaryFunctorT>( s, f ).
00538     */
00539     template <typename SerT, typename BinaryFunctorT>
00540     inline serializable_to_deserialize_unary_f<SerT,BinaryFunctorT>
00541     ser_to_deser_unary_f( SerT & s, BinaryFunctorT const & f )
00542     {
00543         return serializable_to_deserialize_unary_f<SerT,BinaryFunctorT>( s, f );
00544     }
00545 
00546     /**
00547        Returns serializable_to_deserialize_unary_f<SerT>( s ).
00548     */
00549     template <typename SerT>
00550     inline serializable_to_deserialize_unary_f<SerT>
00551     ser_to_deser_unary_f( SerT const & s)
00552     {
00553         return serializable_to_deserialize_unary_f<SerT>( s );
00554     }
00555 
00556 
00557 
00558     /**
00559        Conforms to deserialize_nullary_f_tag expectations
00560        and converts a deserialize_binary_f_tag type to
00561        deserialize_nullary_f_tag type.
00562 
00563        BinaryFunctorT must comply to deserialize_binary_f_tag's
00564        expectations.
00565 
00566        Under NO circumstances may you pass TEMPORARY as a NodeType
00567        argument to one of the ctors. This is strictly illegal, as
00568        we hold a reference to the object.
00569 
00570        Added in 1.1.3.
00571     */
00572     template <typename NodeType,typename DeserializableT, typename BinaryFunctorT = deserialize_f>
00573     struct deserialize_nullary_f : deserialize_nullary_f_tag
00574     {
00575         reference_f<NodeType const> node;
00576         reference_f<DeserializableT> serializable;
00577         BinaryFunctorT functor;
00578         deserialize_nullary_f( NodeType const & n, DeserializableT & s )
00579             : node(n), serializable(s), functor()
00580         {
00581         }
00582 
00583         deserialize_nullary_f( NodeType const & n, DeserializableT & s, BinaryFunctorT const & f )
00584             : node(n), serializable(s), functor(f)
00585         {
00586         }
00587 
00588         /**
00589            Returns this->functor( this->node, this->serializable ).
00590         */
00591         inline bool operator()() const
00592         {
00593             return this->functor( this->node(), this->serializable() );
00594         }
00595     };
00596 
00597     /**
00598        Returns deserialize_nullary_f<NodeType,DeserializableT,BinaryFunctorT>( n, s, f ).
00599     */
00600     template <typename NodeType,typename DeserializableT, typename BinaryFunctorT>
00601     inline deserialize_nullary_f<NodeType,DeserializableT,BinaryFunctorT>
00602     deser_nullary_f( NodeType const & n, DeserializableT & s, BinaryFunctorT const & f )
00603     {
00604         return deserialize_nullary_f<NodeType,DeserializableT,BinaryFunctorT>( n, s, f );
00605     }
00606 
00607     /**
00608        Returns deserialize_nullary_f<NodeType,DeserializableT>( n, s );
00609     */
00610     template <typename NodeType,typename DeserializableT>
00611     inline deserialize_nullary_f<NodeType,DeserializableT>
00612     deser_nullary_f( NodeType const & n, DeserializableT & s )
00613     {
00614         return deserialize_nullary_f<NodeType,DeserializableT>( n, s );
00615     }
00616 
00617 
00618 
00619     /**
00620        Experimental. Added in 1.1.3.
00621 
00622        A Serializable functor intended for some metaprogramming
00623        experimentation, to allow lazy s11n of a Serializable.
00624 
00625        BinaryFunctorT requires this signature:
00626 
00627        bool operator()( NodeType & dest, const SerializableT & src )
00628      */
00629     template <typename SerializableT, typename BinaryFunctorT = serialize_f>
00630     struct serializable_f : serialize_unary_node_f_tag
00631     {
00632         typedef SerializableT const type;
00633         reference_f<type> reference;
00634         BinaryFunctorT functor;
00635 
00636         /**
00637            Sets this->reference(_ref).
00638          */
00639         explicit serializable_f( type & _ref ) : reference(_ref), functor()
00640         {
00641         }
00642 
00643         serializable_f( type & _ref, BinaryFunctorT f ) : reference(_ref), functor(f)
00644         {
00645         }
00646 
00647         /**
00648            Returns serialize( dest, this->ref ).
00649 
00650            Calling after this->ref has been destroyed
00651            yields undefined behaviour.
00652         */
00653         template <typename NodeType>
00654         inline bool operator()( NodeType & dest ) const
00655         {
00656             return this->functor( dest, this->reference() );
00657         }
00658 
00659         /** Retyurns a const reference to this object's referenced Serializable. */
00660         inline type & operator()() const
00661         {
00662             return this->reference();
00663         }
00664     };
00665 
00666     /**
00667        Experimental. Added in 1.1.3.
00668 
00669        Returns serializable_f<SerializableT>( ref ).
00670 
00671        ref must outlive the object returned by this function!
00672     */
00673     template <typename SerializableT>
00674     inline serializable_f<SerializableT>
00675     ser_f( SerializableT const & ref )
00676     {
00677         return serializable_f<SerializableT>( ref );
00678     }
00679 
00680     /**
00681        Experimental. Added in 1.1.3.
00682 
00683        Returns serializable_f<SerializableT,BinaryFunctorT>( ref, f ).
00684 
00685        ref must outlive the object returned by this function!
00686     */
00687     template <typename SerializableT,typename BinaryFunctorT>
00688     inline serializable_f<SerializableT,BinaryFunctorT>
00689     ser_f( SerializableT const & ref, BinaryFunctorT f )
00690     {
00691         return serializable_f<SerializableT,BinaryFunctorT>( ref, f );
00692     }
00693 
00694     /**
00695        Experimental. Added in 1.1.3.
00696 
00697        A Serializable functor intended for some metaprogramming
00698        experimentation, to allow lazy de-s11n of a Serializable.
00699 
00700        BinaryFunctorT requires this signature:
00701 
00702        bool operator()( const NodeType & src, SerializableT & dest )
00703 
00704     */
00705     template <typename DeserializableT, typename BinaryFunctorT = deserialize_f>
00706     struct deserializable_f : deserialize_unary_node_f_tag
00707     {
00708         //typedef deserializable_f<DeserializableT,BinaryFunctorT> type;
00709         typedef DeserializableT type;
00710         reference_f<type> reference;
00711         BinaryFunctorT functor;
00712 
00713         /**
00714            Sets this->ref = _ref.
00715          */
00716         explicit deserializable_f( type & _ref ) : reference(_ref),functor()
00717         {
00718         }
00719 
00720         deserializable_f( type & _ref, BinaryFunctorT f ) : reference(_ref),functor(f)
00721         {
00722         }
00723         /**
00724            Returns deserialize( src, this->ref ).
00725 
00726            Calling after this->ref has been destroyed
00727            yields undefined behaviour.
00728          */
00729         template <typename NodeType>
00730         inline bool operator()( const NodeType & src ) const
00731         {
00732             return this->functor( src, this->reference() );
00733         }
00734 
00735         /** Retyurns a reference to this object's referenced Serializable. */
00736         inline type & operator()() const
00737         {
00738             return this->reference();
00739         }
00740     };
00741 
00742 
00743     /**
00744        Added in 1.1.3.
00745 
00746        Returns deserializable_f<DeserializableT>( ref ).
00747 
00748        ref must outlive the object returned by this function!
00749     */
00750     template <typename DeserializableT>
00751     inline deserializable_f<DeserializableT>
00752     deser_f( DeserializableT & ref )
00753     {
00754         return deserializable_f<DeserializableT>( ref );
00755     }
00756 
00757     /**
00758        Added in 1.1.3.
00759 
00760        Returns deserializable_f<DeserializableT,BinaryFunctorT>( ref, f ).
00761 
00762        ref must outlive the object returned by this function!
00763     */
00764     template <typename DeserializableT,typename BinaryFunctorT>
00765     inline deserializable_f<DeserializableT,BinaryFunctorT>
00766     deser_f( DeserializableT & ref, BinaryFunctorT f )
00767     {
00768         return deserializable_f<DeserializableT,BinaryFunctorT>( ref, f );
00769     }
00770 
00771     /**
00772        A functor to allow us to easily walk a list of S-Nodes and
00773        deserialize each one into a target container.
00774 
00775 
00776        The optional BinaryFunctorT defines the functor to use
00777        to deserialize each object. The default simply routes
00778        through the s11n::deserialize() API.
00779 
00780        SerializableType is unforuntately required: we can't
00781        derive it from the output iterator.
00782 
00783        SerializableType MAY NOT yet be pointer-qualified. That's on
00784        the to-fix list somewhere. It would inherently cause a leak
00785        or be very incorrect in some uses, though, like using an
00786        ostream_iterator(). It could be made to function, but would not
00787        be leak-proof.
00788 
00789        Also, we create and copy SerializableTypes here, so that type
00790        should be cheap to do that with.
00791 
00792        BinaryFunctorT must conform to the interface defined by
00793        deserialize_f.
00794 
00795        Example, assuming NTR is a node_traits type:
00796 
00797        <pre>
00798        std::for_each( NTR::children(node).begin(),
00799                   NTR::children(node).end(),
00800                   deser_to_outiter_f<MyType>( std::back_inserter(myvector) ) );
00801        </pre>
00802     */
00803     template <typename SerializableType, typename OutIterator, typename BinaryFunctorT = deserialize_f>
00804     struct deserialize_to_output_iter_f
00805     {
00806         // typedef deserialize_to_output_iter_f<SerializableType,OutIterator,BinaryFunctorT> type;
00807         typedef OutIterator type;
00808         type iterator;
00809         BinaryFunctorT functor;
00810         typedef SerializableType serializable_type;
00811         // typedef typename std::iterator_traits<OutIterator>::value_type serializable_type;
00812         // ^^^ why is this void?
00813 
00814         /**
00815            Sets this object's output iterator.
00816         */
00817         explicit deserialize_to_output_iter_f( type target ) : iterator(target), functor()
00818         {}
00819 
00820         /**
00821            Sets this object's output iterator and copies the
00822            given functor.
00823         */
00824         deserialize_to_output_iter_f( type target, BinaryFunctorT f ) : iterator(target), functor(f)
00825         {}
00826 
00827         /**
00828            Creates a new object of serializable_type and deserializes it.
00829            On success iterator is assigned and incremented and true is returned.
00830            On error false is returned or an exception is propagated.
00831 
00832            If src is (!src), false is returned.
00833 
00834            Note that the odd pointerness of the argument is because
00835            node children lists contain pointers and are const
00836            in a deserialize context.
00837         */
00838         template <typename NodeType>
00839         bool operator()( NodeType * const & src )
00840         {
00841             if( src )
00842             {
00843                 serializable_type dest;
00844                 if( this->functor( *src, dest ) )
00845                 {
00846                     *(iterator++) = dest;
00847                     return true;
00848                 }
00849             }
00850             return false;
00851         }
00852     };
00853 
00854     /**
00855        Convenience function returning:
00856 
00857        deserialize_to_output_iter_f<SerializableType,OutIterator,BinaryFunctorT>( target, f )
00858     */
00859     template <typename SerializableType,typename OutIterator, typename BinaryFunctorT>
00860     inline deserialize_to_output_iter_f<SerializableType,OutIterator,BinaryFunctorT>
00861     deser_to_outiter_f( OutIterator target, BinaryFunctorT f )
00862     {
00863         return deserialize_to_output_iter_f<SerializableType,OutIterator,BinaryFunctorT>( target, f );
00864     }
00865 
00866     /**
00867        Convenience function returning:
00868 
00869        deserialize_to_output_iter_f<SerializableType,OutIterator>( target )
00870     */
00871     template <typename SerializableType, typename OutIterator>
00872     inline deserialize_to_output_iter_f<SerializableType,OutIterator>
00873     deser_to_outiter_f( OutIterator target )
00874     {
00875         return deserialize_to_output_iter_f<SerializableType,OutIterator>( target );
00876     }
00877 
00878 
00879     /**
00880        Experimental. Added in 1.1.3.
00881 
00882        BinaryFunctorT must have:
00883 
00884        bool operator()( NodeType & dest, const SerializableT & src )
00885 
00886     */
00887     template <typename BinaryFunctorT = serialize_f>
00888     struct serialize_to_subnode_f : serialize_binary_f_tag
00889     {
00890         //typedef serialize_to_subnode_f<BinaryFunctorT> type;
00891         std::string name;
00892         BinaryFunctorT functor;
00893 
00894 
00895         /**
00896         */
00897         serialize_to_subnode_f( const std::string & subnodename, BinaryFunctorT f )
00898             : name(subnodename),functor(f)
00899         {
00900         }
00901 
00902         /**
00903         */
00904         explicit serialize_to_subnode_f( const std::string & subnodename )
00905             : name(subnodename),functor()
00906         {
00907         }
00908 
00909         /**
00910            Creates a NodeType names this->name and calls
00911            this->functor( child, src ). If the functor fails,
00912            the child is deleted and dest is unmodified, else
00913            ownership of the child is transfered to dest, via
00914            node_traits<NodeType>::children(dest).push_back(child).
00915 
00916            Returns true on success, false on failure.
00917         */
00918         template <typename NodeType, typename SerializableT>
00919         inline bool operator()( NodeType & dest, SerializableT const & src ) const
00920         {
00921             typedef node_traits<NodeType> NTR;
00922             std::auto_ptr<NodeType> nap( NTR::create( this->name ) );
00923             return this->functor( *nap, src )
00924                 ? (NTR::children(dest).push_back( nap.release() ),true)
00925                 : false;
00926         }
00927 
00928     };
00929 
00930 
00931 
00932     /**
00933        Returns serialize_to_subnode_f<>( subnodename ).
00934 
00935        Added in 1.1.3.
00936     */
00937     inline serialize_to_subnode_f<>
00938     ser_to_subnode_f( const std::string & subnodename )
00939     {
00940         return serialize_to_subnode_f<>( subnodename );
00941     }
00942 
00943     /**
00944        Returns serialize_to_subnode_f<BinaryFunctorT>( subnodename, f ).
00945 
00946        Added in 1.1.3.
00947     */
00948     template <typename BinaryFunctorT>
00949     inline serialize_to_subnode_f<BinaryFunctorT>
00950     ser_to_subnode_f( const std::string & subnodename, BinaryFunctorT f )
00951     {
00952         return serialize_to_subnode_f<BinaryFunctorT>( subnodename, f );
00953     }
00954 
00955     
00956 
00957     /**
00958        Experimental. Added in 1.1.3.
00959 
00960        BinaryFunctorT must have:
00961 
00962        bool operator()( NodeType & dest, const SerializableT & src )
00963 
00964     */
00965     template <typename NodeType, typename BinaryFunctorT = serialize_f>
00966     struct serialize_to_subnode_unary_f : serialize_unary_serializable_f_tag
00967     {
00968         //typedef serialize_to_subnode_unary_f<NodeType,BinaryFunctorT> type;
00969         reference_f<NodeType> node;
00970         std::string name;
00971         BinaryFunctorT functor;
00972 
00973         /**
00974         */
00975         serialize_to_subnode_unary_f( NodeType & parent, const std::string & subnodename )
00976             : node(parent), name(subnodename),functor()
00977         {
00978         }
00979 
00980         /**
00981         */
00982         serialize_to_subnode_unary_f( NodeType & parent, const std::string & subnodename, BinaryFunctorT f )
00983             : node(parent), name(subnodename),functor(f)
00984         {
00985         }
00986 
00987         /**
00988            Creates a NodeType named this->name and calls
00989            this->functor( child, src ). If the functor fails,
00990            the child is deleted and dest is unmodified, else
00991            ownership of the child is transfered to dest, via
00992            node_traits<NodeType>::children(this->node()).push_back(child).
00993 
00994            Returns true on success, false on failure.
00995            
00996         */
00997         template <typename SerializableT>
00998         bool operator()( SerializableT const & src ) const
00999         {
01000             typedef node_traits<NodeType> NTR;
01001             std::auto_ptr<NodeType> nap( NTR::create( this->name ) );
01002             if( this->functor( *nap, src ) )
01003             {
01004                 NTR::children(this->node()).push_back( nap.release() );
01005             }
01006             return 0 == nap.get();
01007         }
01008     };
01009 
01010 
01011     /**
01012        Returns serialize_to_subnode_f<NodeType>( parent, subnodename ).
01013 
01014        Example:
01015        <pre>
01016        std::for_each( vec.begin(),
01017                   vec.end(),
01018                   ser_to_subnode_unary_f( mynode, "child" )
01019                 );
01020        </pre>
01021 
01022        Added in 1.1.3.
01023     */
01024     template <typename NodeType>
01025     inline serialize_to_subnode_unary_f<NodeType>
01026     ser_to_subnode_unary_f( NodeType & parent, const std::string & subnodename )
01027     {
01028         return serialize_to_subnode_unary_f<NodeType>( parent, subnodename );
01029     }
01030 
01031     /**
01032        Returns serialize_to_subnode_unary_f<NodeType,BinaryFunctorT>( parent, subnodename, f ).
01033 
01034        Example:
01035 
01036        <pre>
01037        std::for_each( vec.begin(),
01038                vec.end(),
01039                ser_to_subnode_f( mynode, "child", my_serialize_to_subnode_unary_functor() )
01040                );
01041        </pre>
01042 
01043        Added in 1.1.3.
01044     */
01045     template <typename NodeType, typename BinaryFunctorT>
01046     inline serialize_to_subnode_unary_f<NodeType,BinaryFunctorT>
01047     ser_to_subnode_unary_f( NodeType & parent, const std::string & subnodename, BinaryFunctorT f )
01048     {
01049         return serialize_to_subnode_unary_f<NodeType,BinaryFunctorT>( parent, subnodename, f );
01050     }
01051 
01052 
01053 
01054     /**
01055        
01056 
01057        BinaryFunctorT requires this signature:
01058 
01059        bool operator()( const NodeType & src, const std::string & subnodename, SerializableT & dest )
01060 
01061        Added in 1.1.3.
01062     */
01063     template <typename BinaryFunctorT = deserialize_f>
01064     struct deserialize_from_subnode_f : deserialize_binary_f_tag
01065     {
01066         //typedef deserialize_from_subnode_f<BinaryFunctorT> type;
01067         std::string name;
01068         BinaryFunctorT functor;
01069         deserialize_from_subnode_f( const std::string & subnodename )
01070             : name(subnodename),functor()
01071         {
01072         }
01073 
01074         deserialize_from_subnode_f( const std::string & subnodename, BinaryFunctorT f )
01075             : name(subnodename),functor(f)
01076         {
01077         }
01078 
01079         /**
01080            Searches for the first child in src named this->name. If it succeeds,
01081            it returns the result of this->functor( child, dest ), else it returns
01082            false.
01083         */
01084         template <typename NodeType, typename SerializableT>
01085         inline bool operator()( NodeType const & src, SerializableT & dest ) const
01086         {
01087             const NodeType * ch = ::s11n::find_child_by_name( src, this->name );
01088             return ch
01089                 ? this->functor( *ch, dest )
01090                 : false;
01091         }
01092     };
01093 
01094 
01095     /**
01096        Returns deserialize_from_subnode_f<>( parent, subnodename ).
01097 
01098        Added in 1.1.3.
01099     */
01100     inline deserialize_from_subnode_f<>
01101     deser_from_subnode_f( const std::string & subnodename )
01102     {
01103         return deserialize_from_subnode_f<>( subnodename );
01104     }
01105     /**
01106        Returns deserialize_from_subnode_f<BinaryFunctorT>( parent, subnodename, f ).
01107 
01108        Added in 1.1.3.
01109     */
01110     template <typename BinaryFunctorT>
01111     inline deserialize_from_subnode_f<BinaryFunctorT>
01112     deser_from_subnode_f( const std::string & subnodename, BinaryFunctorT f )
01113     {
01114         return deserialize_from_subnode_f<BinaryFunctorT>( subnodename, f );
01115     }
01116 
01117     /**
01118        BinaryFunctorT requires this signature:
01119 
01120        bool operator()( const NodeType & src, const std::string & subnodename, SerializableT & dest )
01121 
01122        Added in 1.1.3.
01123     */
01124     template <typename NodeType, typename BinaryFunctorT = deserialize_f>
01125     struct deserialize_from_subnode_unary_f : deserialize_unary_serializable_f_tag
01126     {
01127         //typedef deserialize_from_subnode_unary_f<NodeType,BinaryFunctorT> type;
01128         reference_f<NodeType const> node;
01129         std::string name;
01130         BinaryFunctorT functor;
01131         deserialize_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename )
01132             : node(parent), name(subnodename),functor()
01133         {
01134         }
01135 
01136         deserialize_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename, BinaryFunctorT f )
01137             : node(parent), name(subnodename),functor(f)
01138         {
01139         }
01140 
01141         /**
01142            Searches for the first child in this->node() named this->name. If it succeeds,
01143            it returns the result of this->functor( child, dest ), else it returns
01144            false.
01145         */
01146         template <typename SerializableT>
01147         inline bool operator()( SerializableT & dest ) const
01148         {
01149             const NodeType * ch = ::s11n::find_child_by_name( this->node(), this->name );
01150             return ch
01151                 ? this->functor( *ch, dest )
01152                 : false;
01153         }
01154     };
01155 
01156 
01157     /**
01158        Returns deserialize_from_subnode_unary_f<NodeType>( parent, subnodename ).
01159 
01160        Added in 1.1.3.
01161     */
01162     template <typename NodeType>
01163     inline deserialize_from_subnode_unary_f<NodeType>
01164     deser_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename )
01165     {
01166         return deserialize_from_subnode_unary_f<NodeType>( parent, subnodename );
01167     }
01168     /**
01169        Experimental. Added in 1.1.3.
01170 
01171        Returns deserialize_from_subnode_unary_f<NodeType,BinaryFunctorT>( parent, subnodename, f ).
01172     */
01173     template <typename NodeType, typename BinaryFunctorT>
01174     inline deserialize_from_subnode_unary_f<NodeType,BinaryFunctorT>
01175     deser_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename, BinaryFunctorT f )
01176     {
01177         return deserialize_from_subnode_unary_f<NodeType,BinaryFunctorT>( parent, subnodename, f );
01178     }
01179 
01180 
01181 
01182 
01183     /**
01184        Functor implementing AND logic and between two functors,
01185        which are expected to return values convertable to bool.
01186     */
01187     struct logical_and_binary_f
01188     {
01189         template <typename F1, typename F2>
01190         inline bool operator()( F1 const & f1, F2 const & f2 ) const
01191         {
01192             return f1() && f2();
01193         }
01194     };
01195 
01196     /**
01197        Functor implementing AND logic and between two functors,
01198        which are expected to return values convertable to bool.
01199     */
01200     template <typename F1>
01201     struct logical_and_unary_f
01202     {
01203         F1 functor;
01204         logical_and_unary_f( F1 const & f ) : functor(f)
01205         {}
01206         template <typename F2>
01207         inline bool operator()( F2 const & f2 ) const
01208         {
01209             return this->functor() && f2();
01210         }
01211     };
01212 
01213     /**
01214        Functor implementing AND logic and between two functors,
01215        which are expected to return values convertable to bool.
01216     */
01217     template <typename F1, typename F2>
01218     struct logical_and_nullary_f
01219     {
01220         F1 functor1;
01221         F2 functor2;
01222         logical_and_nullary_f( F1 const & f1, F2 const & f2 ) : functor1(f1), functor2(f2)
01223         {}
01224         inline bool operator()() const
01225         {
01226             return this->functor1() && this->functor2();
01227         }
01228     };
01229 
01230 
01231     /**
01232        Returns logical_and_nullary<F1,F2>(f1,f2).
01233     */
01234     template <typename F1, typename F2>
01235     inline logical_and_nullary_f<F1,F2>
01236     logical_and( F1 const & f1, F2 const & f2 )
01237     {
01238         return logical_and_nullary_f<F1,F2>(f1,f2);
01239     }
01240 
01241     /**
01242        Returns logical_and_unary<F1>(f1).
01243     */
01244     template <typename F1>
01245     inline logical_and_unary_f<F1>
01246     logical_and( F1 const & f1 )
01247     {
01248         return logical_and_unary_f<F1>(f1);
01249     }
01250 
01251     /**
01252        Returns logical_and_binary().
01253     */
01254     inline logical_and_binary_f
01255     logical_and()
01256     {
01257         return logical_and_binary_f();
01258     }
01259 
01260 
01261 
01262 
01263 } // namespace s11n
01264 
01265 
01266 #endif // s11n_net_s11n_1_1_FUNCTIONAL_HPP_INCLUDED

Generated on Sat Dec 10 13:38:25 2005 for libs11n-1.2.1 by  doxygen 1.4.4