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

Generated on Sun Apr 27 13:16:04 2008 for libs11n by  doxygen 1.5.3