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 //     Convenience function to return reference_f<T>(ref).
00112 //     Added in 1.1.3.
00113 //         Removed in 1.3.1 (it's unused)
00114 //  */
00115 //  template <typename T>
00116 //  inline reference_f<T> ref( T & ref )
00117 //  {
00118 //      return reference_f<T>(ref);
00119 //  }
00120 
00121 
00122     /**
00123        Pointer equivalent of reference_base_f.
00124 
00125        Added in 1.1.3.
00126 
00127        T may be const or not, but should not have a pointer
00128        qualification. Specializations of pointer_f take care of
00129        getting rid of the extra const/pointer/reference
00130        qualifiers.
00131     */
00132     template <typename T>
00133     struct pointer_base_f
00134     {
00135         /** Same as T, possibly const-qualified. */
00136         typedef T type;
00137         type * value;
00138         explicit pointer_base_f( type * _ref ) : value(_ref)
00139         {}
00140         explicit pointer_base_f( type & _ref ) : value(&_ref)
00141         {}
00142         /**
00143            Returns a [const] pointer to the object this one
00144            refers to.
00145         */
00146         inline type * operator()() const
00147         {
00148             return this->value;
00149         }
00150 
00151         /** For convention's sake... */
00152         inline type * get() const
00153         {
00154             return this->value;
00155         }
00156 
00157         inline type * operator->() const
00158         {
00159             return this->value;
00160         }
00161 
00162         inline bool empty() const
00163         {
00164             return 0 != this->value;
00165         }
00166     };
00167 
00168     /**
00169        Pointer equivalent of reference_f.
00170        Added in 1.1.3.
00171     */
00172     template <typename T>
00173     struct pointer_f : pointer_base_f<T>
00174     {
00175         typedef typename pointer_base_f<T>::type type;
00176         explicit pointer_f( type & _ref ) : pointer_base_f<T>(&_ref)
00177         {}
00178         explicit pointer_f( type * _ref ) : pointer_base_f<T>(_ref)
00179         {}
00180     };
00181 
00182     /**
00183        Pointer equivalent of reference_f.
00184        Added in 1.1.3.
00185     */
00186     template <typename T>
00187     struct pointer_f<T const> : pointer_base_f<T const>
00188     {
00189         typedef typename pointer_base_f<T const>::type type;
00190         explicit pointer_f( type & _ref ) : pointer_base_f<T const>(&_ref)
00191         {}
00192         explicit pointer_f( type * _ref ) : pointer_base_f<T const>(_ref)
00193         {}
00194 
00195     };
00196 
00197     /**
00198        Pointer equivalent of reference_f.
00199        Added in 1.1.3.
00200     */
00201     template <typename T>
00202     struct pointer_f<T *> : pointer_base_f<T>
00203     {
00204         typedef typename pointer_base_f<T>::type type;
00205         explicit pointer_f( type * _ref ) : pointer_base_f<T>(_ref)
00206         {}
00207         explicit pointer_f( type & _ref ) : pointer_base_f<T>(&_ref)
00208         {}
00209     };
00210 
00211     /**
00212        Pointer equivalent of reference_f.
00213        Added in 1.1.3.
00214     */
00215     template <typename T>
00216     struct pointer_f<T const *> : pointer_base_f<T const>
00217     {
00218         typedef typename pointer_base_f<T const>::type type;
00219         explicit pointer_f( type * _ref ) : pointer_base_f<T const>(_ref)
00220         {}
00221         explicit pointer_f( type & _ref ) : pointer_base_f<T const>(&_ref)
00222         {}
00223     };
00224 
00225 //  /** Returns pointer_f<T>(v). */
00226 //  template <typename T>
00227 //  inline pointer_f<T> pointer( typename type_traits<T>::type & v )
00228 //  {
00229 //      return pointer_f<T>(v);
00230 //  }
00231 
00232 //      template <typename T>
00233 //      inline pointer_f<T> pointer( typename type_traits<T>::type * v )
00234 //      {
00235 //          return pointer_f<T>(v);
00236 //      }
00237 
00238 //      template <typename T>
00239 //      inline pointer_f<T const> pointer( typename type_traits<T const>::type const & v )
00240 //      {
00241 //          return pointer_f<T const>(v);
00242 //      }
00243 
00244 //      template <typename T>
00245 //      inline pointer_f<T const> pointer( typename type_traits<T const>::type const * v )
00246 //      {
00247 //          return pointer_f<T const>(v);
00248 //      }
00249 
00250 
00251     /**
00252        Holds a value. For use in template metaprogramming.
00253 
00254        Added in 1.1.3.
00255     */
00256     template <typename T>
00257     struct value_f
00258     {
00259         typedef T type;
00260         type value;
00261         value_f( type const & _ref ) : value(_ref)
00262         {}
00263 
00264         /** Returns a copy of this->value. */
00265         inline operator T() const
00266         {
00267             return this->value;
00268         }
00269 
00270         /** Returns a copy of this->value. */
00271         inline type operator()() const
00272         {
00273             return this->value;
00274         }
00275     };
00276 
00277     /** Quasi-bogus specialization. */
00278     template <typename T>
00279     struct value_f<T const> : value_f<T> {};
00280 
00281     /** Quasi-bogus specialization. */
00282     template <typename T>
00283     struct value_f<T &> : value_f<T> {};
00284 
00285     /** Quasi-bogus specialization. */
00286     template <typename T>
00287     struct value_f<T const &> : value_f<T> {};
00288 
00289 
00290     /** Returns value_f<T>(v). */
00291     template <typename T>
00292     inline value_f<T> val( const T & v )
00293     {
00294         return value_f<T>(v);
00295     }
00296 
00297 
00298 
00299     /**
00300        A functor which simply forwards its arguments to
00301        s11n::serialize().
00302 
00303        Added in 1.1.3.
00304     */
00305     struct serialize_binary_f : serialize_binary_f_tag
00306     {
00307         template <typename NT, typename ST>
00308         inline bool operator()( NT & dest, const ST & src ) const
00309         {
00310             return serialize<NT,ST>( dest, src );
00311         }
00312     };
00313 
00314     /**
00315        A functor which simply forwards its arguments to
00316        s11n::deserialize().
00317 
00318        Added in 1.1.3.
00319     */
00320     struct deserialize_binary_f : deserialize_binary_f_tag
00321     {
00322         template <typename NT, typename ST>
00323         inline bool operator()( const NT & src, ST & dest ) const
00324         {
00325             return deserialize<NT,ST>( src, dest );
00326         }
00327     };
00328 
00329 
00330     /**
00331        Conforms to serialize_nullary_f_tag expectations
00332        and converts a serialize_binary_f_tag type to
00333        serialize_nullary_f_tag type.
00334 
00335        BinaryFunctorT must comply to serialize_binary_f_tag's
00336        expectations.
00337 
00338        Added in 1.1.3.
00339     */
00340     template <typename NodeType,typename SerializableT, typename BinaryFunctorT = serialize_binary_f>
00341     struct serialize_nullary_f : serialize_nullary_f_tag
00342     {
00343         reference_f<NodeType> node;
00344         reference_f<SerializableT const> serializable;
00345         BinaryFunctorT functor;
00346         /**
00347            Functionally identical to the 3-arg ctor with a default-constructed
00348            BinaryFunctorT as the third argument.
00349         */
00350         serialize_nullary_f( NodeType & n, SerializableT const & s )
00351             : node(n), serializable(s), functor()
00352         {
00353         }
00354 
00355         /**
00356            Sets up for a call to f(n,s).
00357 
00358            n and s must both outlive this object. Even though s is a
00359            const ref, we do not copy it. We expect s to stay valid.
00360         */
00361         serialize_nullary_f( NodeType & n, SerializableT const & s, BinaryFunctorT const & f )
00362             : node(n), serializable(s), functor(f)
00363         {
00364         }
00365         /** Returns this->functor( this->node, this->serializable ). */
00366         inline bool operator()() const
00367         {
00368             return this->functor( this->node(), this->serializable() );
00369         }
00370     };
00371 
00372     /**
00373        Returns serialize_nullary_f<NodeType,SerializableT,BinaryFunctorT>( n, s, f ).
00374     */
00375     template <typename NodeType,typename SerializableT, typename BinaryFunctorT>
00376     inline serialize_nullary_f<NodeType,SerializableT,BinaryFunctorT>
00377     ser_nullary_f( NodeType & n, SerializableT const & s, BinaryFunctorT const & f )
00378     {
00379         return serialize_nullary_f<NodeType,SerializableT,BinaryFunctorT>( n, s, f );
00380     }
00381 
00382     /**
00383        Returns serialize_nullary_f<NodeType,SerializableT>( n, s ).
00384     */
00385     template <typename NodeType,typename SerializableT>
00386     inline serialize_nullary_f<NodeType,SerializableT>
00387     ser_nullary_f( NodeType & n, SerializableT const & s )
00388     {
00389         return serialize_nullary_f<NodeType,SerializableT>( n, s );
00390     }
00391 
00392     /**
00393        Converts an S-Node to a unary functor taking a Serializable
00394        argument.
00395 
00396        BinaryFunctorT must comply to serialize_binary_f_tag.
00397     */
00398     template <typename NodeType, typename BinaryFunctorT = serialize_binary_f>
00399     struct node_to_serialize_unary_f : serialize_unary_serializable_f_tag
00400     {
00401         //typedef NodeType type;
00402         reference_f<NodeType> node;
00403         BinaryFunctorT functor;
00404         node_to_serialize_unary_f( NodeType & n ) : node(n), functor() {}
00405         node_to_serialize_unary_f( NodeType & n, BinaryFunctorT const & f ) : node(n), functor(f) {}
00406 
00407         template <typename SerT>
00408         inline bool operator()( const SerT & src ) const
00409         {
00410             return this->functor( this->node(), src );
00411         }
00412     };
00413 
00414     /**
00415        Returns node_to_serialize_unary_f<NodeType,BinaryFunctorT>(n,f).
00416     */
00417     template <typename NodeType, typename BinaryFunctorT>
00418     node_to_serialize_unary_f<NodeType,BinaryFunctorT>
00419     node_to_ser_unary_f( NodeType & n, BinaryFunctorT f )
00420     {
00421         return node_to_serialize_unary_f<NodeType,BinaryFunctorT>(n,f);
00422     }
00423 
00424     /**
00425        Returns node_to_serialize_unary_f<NodeType>(n).
00426     */
00427     template <typename NodeType>
00428     node_to_serialize_unary_f<NodeType>
00429     node_to_ser_unary_f( NodeType & n )
00430     {
00431         return node_to_serialize_unary_f<NodeType>(n);
00432     }
00433 
00434 
00435     /**
00436        Converts an S-Node to a unary functor taking a Serializable
00437        argument.
00438 
00439        BinaryFunctorT must comply to deserialize_binary_f_tag.
00440     */
00441     template <typename NodeType, typename BinaryFunctorT = deserialize_binary_f>
00442     struct node_to_deserialize_unary_f : deserialize_unary_serializable_f_tag
00443     {
00444         //typedef NodeType type;
00445         reference_f<NodeType const> node;
00446         BinaryFunctorT functor;
00447         node_to_deserialize_unary_f( NodeType const & n ) : node(n), functor() {}
00448         node_to_deserialize_unary_f( NodeType const & n, BinaryFunctorT const & f ) : node(n), functor(f) {}
00449         template <typename SerT>
00450         inline bool operator()( SerT & dest ) const
00451         {
00452             return this->functor( this->node(), dest );
00453         }
00454     };
00455 
00456     /**
00457        Returns node_to_deserialize_unary_f<NodeType,BinaryFunctorT>(n,f).
00458     */
00459     template <typename NodeType, typename BinaryFunctorT>
00460     node_to_deserialize_unary_f<NodeType,BinaryFunctorT>
00461     node_to_deser_unary_f( NodeType const & n, BinaryFunctorT const & f )
00462     {
00463         return node_to_deserialize_unary_f<NodeType,BinaryFunctorT>(n,f);
00464     }
00465 
00466     /**
00467        Returns node_to_deserialize_unary_f<NodeType>(n).
00468     */
00469     template <typename NodeType>
00470     inline node_to_deserialize_unary_f<NodeType>
00471     node_to_deser_unary_f( NodeType const & n )
00472     {
00473         return node_to_deserialize_unary_f<NodeType>(n);
00474     }
00475 
00476 
00477     /**
00478        Converts a Serializable to a type compliant with
00479        serialize_unary_node_f_tag.
00480 
00481        BinaryFunctorT must comply to serialize_binary_f_tag.
00482 
00483        Added in 1.1.3.
00484     */
00485     template <typename SerT, typename BinaryFunctorT = serialize_binary_f>
00486     struct serializable_to_serialize_unary_f : serialize_unary_node_f_tag
00487     {
00488         typedef SerT type;
00489         reference_f<SerT const> serializable;
00490         BinaryFunctorT functor;
00491         serializable_to_serialize_unary_f( SerT const & n ) : serializable(n), functor() {}
00492         serializable_to_serialize_unary_f( SerT const & n, BinaryFunctorT const & f ) : serializable(n), functor(f) {}
00493 
00494         template <typename NodeT>
00495         inline bool operator()( NodeT & dest ) const
00496         {
00497             return this->functor( dest, this->serializable() );
00498         }
00499     };
00500 
00501     /**
00502        Returns serializable_to_serialize_unary_f<SerT,BinaryFunctorT>( s, f ).
00503     */
00504     template <typename SerT, typename BinaryFunctorT>
00505     inline serializable_to_serialize_unary_f<SerT,BinaryFunctorT>
00506     ser_to_ser_unary_f( SerT const & s, BinaryFunctorT const & f )
00507     {
00508         return serializable_to_serialize_unary_f<SerT,BinaryFunctorT>( s, f );
00509     }
00510 
00511     /**
00512        Returns serializable_to_serialize_unary_f<SerT>( s ).
00513     */
00514     template <typename SerT>
00515     inline serializable_to_serialize_unary_f<SerT>
00516     ser_to_ser_unary_f( SerT const & s)
00517     {
00518         return serializable_to_serialize_unary_f<SerT>( s );
00519     }
00520     
00521 
00522     /**
00523        Converts a Serializable to a type compliant with
00524        deserialize_unary_node_f_tag.
00525 
00526        BinaryFunctorT must comply to deserialize_binary_f_tag.
00527 
00528        Added in 1.1.3.
00529     */
00530     template <typename SerT, typename BinaryFunctorT = deserialize_binary_f>
00531     struct serializable_to_deserialize_unary_f : deserialize_unary_node_f_tag
00532     {
00533         typedef SerT type;
00534         reference_f<SerT> serializable;
00535         BinaryFunctorT functor;
00536         serializable_to_deserialize_unary_f( SerT & n ) : serializable(n), functor() {}
00537         serializable_to_deserialize_unary_f( SerT & n, BinaryFunctorT const & f ) : serializable(n), functor(f) {}
00538 
00539         template <typename NodeT>
00540         inline bool operator()( NodeT const & src ) const
00541         {
00542             return this->functor( src, this->serializable() );
00543         }
00544     };
00545 
00546     /**
00547        Returns serializable_to_deserialize_unary_f<SerT,BinaryFunctorT>( s, f ).
00548     */
00549     template <typename SerT, typename BinaryFunctorT>
00550     inline serializable_to_deserialize_unary_f<SerT,BinaryFunctorT>
00551     ser_to_deser_unary_f( SerT & s, BinaryFunctorT const & f )
00552     {
00553         return serializable_to_deserialize_unary_f<SerT,BinaryFunctorT>( s, f );
00554     }
00555 
00556     /**
00557        Returns serializable_to_deserialize_unary_f<SerT>( s ).
00558     */
00559     template <typename SerT>
00560     inline serializable_to_deserialize_unary_f<SerT>
00561     ser_to_deser_unary_f( SerT const & s)
00562     {
00563         return serializable_to_deserialize_unary_f<SerT>( s );
00564     }
00565 
00566 
00567 
00568     /**
00569        Conforms to deserialize_nullary_f_tag expectations
00570        and converts a deserialize_binary_f_tag type to
00571        deserialize_nullary_f_tag type.
00572 
00573        BinaryFunctorT must comply to deserialize_binary_f_tag's
00574        expectations.
00575 
00576        Under NO circumstances may you pass TEMPORARY as a NodeType
00577        argument to one of the ctors. This is strictly illegal, as
00578        we hold a reference to the object.
00579 
00580        Added in 1.1.3.
00581     */
00582     template <typename NodeType,typename DeserializableT, typename BinaryFunctorT = deserialize_binary_f>
00583     struct deserialize_nullary_f : deserialize_nullary_f_tag
00584     {
00585         reference_f<NodeType const> node;
00586         reference_f<DeserializableT> serializable;
00587         BinaryFunctorT functor;
00588         deserialize_nullary_f( NodeType const & n, DeserializableT & s )
00589             : node(n), serializable(s), functor()
00590         {
00591         }
00592 
00593         deserialize_nullary_f( NodeType const & n, DeserializableT & s, BinaryFunctorT const & f )
00594             : node(n), serializable(s), functor(f)
00595         {
00596         }
00597 
00598         /**
00599            Returns this->functor( this->node, this->serializable ).
00600         */
00601         inline bool operator()() const
00602         {
00603             return this->functor( this->node(), this->serializable() );
00604         }
00605     };
00606 
00607     /**
00608        Returns deserialize_nullary_f<NodeType,DeserializableT,BinaryFunctorT>( n, s, f ).
00609     */
00610     template <typename NodeType,typename DeserializableT, typename BinaryFunctorT>
00611     inline deserialize_nullary_f<NodeType,DeserializableT,BinaryFunctorT>
00612     deser_nullary_f( NodeType const & n, DeserializableT & s, BinaryFunctorT const & f )
00613     {
00614         return deserialize_nullary_f<NodeType,DeserializableT,BinaryFunctorT>( n, s, f );
00615     }
00616 
00617     /**
00618        Returns deserialize_nullary_f<NodeType,DeserializableT>( n, s );
00619     */
00620     template <typename NodeType,typename DeserializableT>
00621     inline deserialize_nullary_f<NodeType,DeserializableT>
00622     deser_nullary_f( NodeType const & n, DeserializableT & s )
00623     {
00624         return deserialize_nullary_f<NodeType,DeserializableT>( n, s );
00625     }
00626 
00627 
00628 
00629     /**
00630        Experimental. Added in 1.1.3.
00631 
00632        A Serializable functor intended for some metaprogramming
00633        experimentation, to allow lazy s11n of a Serializable.
00634 
00635        BinaryFunctorT requires this signature:
00636 
00637        bool operator()( NodeType & dest, const SerializableT & src )
00638      */
00639     template <typename SerializableT, typename BinaryFunctorT = serialize_binary_f>
00640     struct serializable_f : serialize_unary_node_f_tag
00641     {
00642         typedef SerializableT const type;
00643         reference_f<type> reference;
00644         BinaryFunctorT functor;
00645 
00646         /**
00647            Sets this->reference(_ref).
00648          */
00649         explicit serializable_f( type & _ref ) : reference(_ref), functor()
00650         {
00651         }
00652 
00653         serializable_f( type & _ref, BinaryFunctorT f ) : reference(_ref), functor(f)
00654         {
00655         }
00656 
00657         /**
00658            Returns serialize( dest, this->ref ).
00659 
00660            Calling after this->ref has been destroyed
00661            yields undefined behaviour.
00662         */
00663         template <typename NodeType>
00664         inline bool operator()( NodeType & dest ) const
00665         {
00666             return this->functor( dest, this->reference() );
00667         }
00668 
00669         /** Retyurns a const reference to this object's referenced Serializable. */
00670         inline type & operator()() const
00671         {
00672             return this->reference();
00673         }
00674     };
00675 
00676     /**
00677        Experimental. Added in 1.1.3.
00678 
00679        Returns serializable_f<SerializableT>( ref ).
00680 
00681        ref must outlive the object returned by this function!
00682     */
00683     template <typename SerializableT>
00684     inline serializable_f<SerializableT>
00685     ser_f( SerializableT const & ref )
00686     {
00687         return serializable_f<SerializableT>( ref );
00688     }
00689 
00690     /**
00691        Experimental. Added in 1.1.3.
00692 
00693        Returns serializable_f<SerializableT,BinaryFunctorT>( ref, f ).
00694 
00695        ref must outlive the object returned by this function!
00696     */
00697     template <typename SerializableT,typename BinaryFunctorT>
00698     inline serializable_f<SerializableT,BinaryFunctorT>
00699     ser_f( SerializableT const & ref, BinaryFunctorT f )
00700     {
00701         return serializable_f<SerializableT,BinaryFunctorT>( ref, f );
00702     }
00703 
00704     /**
00705        Experimental. Added in 1.1.3.
00706 
00707        A Serializable functor intended for some metaprogramming
00708        experimentation, to allow lazy de-s11n of a Serializable.
00709 
00710        BinaryFunctorT requires this signature:
00711 
00712        bool operator()( const NodeType & src, SerializableT & dest )
00713 
00714     */
00715     template <typename DeserializableT, typename BinaryFunctorT = deserialize_binary_f>
00716     struct deserializable_f : deserialize_unary_node_f_tag
00717     {
00718         //typedef deserializable_f<DeserializableT,BinaryFunctorT> type;
00719         typedef DeserializableT type;
00720         reference_f<type> reference;
00721         BinaryFunctorT functor;
00722 
00723         /**
00724            Sets this->ref = _ref.
00725          */
00726         explicit deserializable_f( type & _ref ) : reference(_ref),functor()
00727         {
00728         }
00729 
00730         deserializable_f( type & _ref, BinaryFunctorT f ) : reference(_ref),functor(f)
00731         {
00732         }
00733         /**
00734            Returns deserialize( src, this->ref ).
00735 
00736            Calling after this->ref has been destroyed
00737            yields undefined behaviour.
00738          */
00739         template <typename NodeType>
00740         inline bool operator()( const NodeType & src ) const
00741         {
00742             return this->functor( src, this->reference() );
00743         }
00744 
00745         /** Retyurns a reference to this object's referenced Serializable. */
00746         inline type & operator()() const
00747         {
00748             return this->reference();
00749         }
00750     };
00751 
00752 
00753     /**
00754        Added in 1.1.3.
00755 
00756        Returns deserializable_f<DeserializableT>( ref ).
00757 
00758        ref must outlive the object returned by this function!
00759     */
00760     template <typename DeserializableT>
00761     inline deserializable_f<DeserializableT>
00762     deser_f( DeserializableT & ref )
00763     {
00764         return deserializable_f<DeserializableT>( ref );
00765     }
00766 
00767     /**
00768        Added in 1.1.3.
00769 
00770        Returns deserializable_f<DeserializableT,BinaryFunctorT>( ref, f ).
00771 
00772        ref must outlive the object returned by this function!
00773     */
00774     template <typename DeserializableT,typename BinaryFunctorT>
00775     inline deserializable_f<DeserializableT,BinaryFunctorT>
00776     deser_f( DeserializableT & ref, BinaryFunctorT f )
00777     {
00778         return deserializable_f<DeserializableT,BinaryFunctorT>( ref, f );
00779     }
00780 
00781     /**
00782        A functor to allow us to easily walk a list of S-Nodes and
00783        deserialize each one into a target container.
00784 
00785 
00786        The optional BinaryFunctorT defines the functor to use
00787        to deserialize each object. The default simply routes
00788        through the s11n::deserialize() API.
00789 
00790        SerializableType is unforuntately required: we can't
00791        derive it from the output iterator.
00792 
00793        SerializableType MAY NOT yet be pointer-qualified. That's on
00794        the to-fix list somewhere. It would inherently cause a leak
00795        or be very incorrect in some uses, though, like using an
00796        ostream_iterator(). It could be made to function, but would not
00797        be leak-proof.
00798 
00799        Also, we create and copy SerializableTypes here, so that
00800        type should be cheap to do that with. Note that only
00801        monomorphic Serializables are properly handled by this
00802        type!
00803 
00804        BinaryFunctorT must conform to the interface defined by
00805        deserialize_binary_f.
00806 
00807        Example, assuming NTR is a node_traits type:
00808 
00809        \code
00810        std::vector<MyType> myvector;
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_binary_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_binary_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             Detail::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_binary_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             Detail::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_binary_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_binary_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 Wed Jun 4 21:44:19 2008 for libs11n by  doxygen 1.5.3