functional.hpp

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

Generated on Sun Apr 27 11:46:48 2008 for libs11n-1.2.6 by  doxygen 1.5.3