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

functional.hpp

Go to the documentation of this file.
00001 #ifndef s11n_net_s11n_1_1_FUNCTIONAL_HPP_INCLUDED
00002 #define s11n_net_s11n_1_1_FUNCTIONAL_HPP_INCLUDED 1
00003 // Experimental code for s11n, with an emphasis on the "mental" part.
00004 // Here be beg, borrow, and steal many ideas from metatemplate and
00005 // functional libraries, like Boost.MPL.
00006 
00007 #include <s11n.net/s11n/tags.hpp>
00008 
00009 namespace s11n {
00010 
00011     /**
00012        Holds a [const] reference to an object. For use in template
00013        metaprogramming. Don't use this type directly: it is intended
00014        to be subclassed by reference_f<> types.
00015 
00016        T must not be pointer-qualified. Const is fine.
00017 
00018        Added in 1.1.3.
00019 
00020        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                 serializable_type dest;
00846                 if( this->functor( *src, dest ) )
00847                 {
00848                     *(iterator++) = dest;
00849                     return true;
00850                 }
00851             }
00852             return false;
00853         }
00854     };
00855 
00856     /**
00857        Convenience function returning:
00858 
00859        deserialize_to_output_iter_f<SerializableType,OutIterator,BinaryFunctorT>( target, f )
00860     */
00861     template <typename SerializableType,typename OutIterator, typename BinaryFunctorT>
00862     inline deserialize_to_output_iter_f<SerializableType,OutIterator,BinaryFunctorT>
00863     deser_to_outiter_f( OutIterator target, BinaryFunctorT f )
00864     {
00865         return deserialize_to_output_iter_f<SerializableType,OutIterator,BinaryFunctorT>( target, f );
00866     }
00867 
00868     /**
00869        Convenience function returning:
00870 
00871        deserialize_to_output_iter_f<SerializableType,OutIterator>( target )
00872     */
00873     template <typename SerializableType, typename OutIterator>
00874     inline deserialize_to_output_iter_f<SerializableType,OutIterator>
00875     deser_to_outiter_f( OutIterator target )
00876     {
00877         return deserialize_to_output_iter_f<SerializableType,OutIterator>( target );
00878     }
00879 
00880 
00881     /**
00882        Experimental. Added in 1.1.3.
00883 
00884        BinaryFunctorT must have:
00885 
00886        bool operator()( NodeType & dest, const SerializableT & src )
00887 
00888     */
00889     template <typename BinaryFunctorT = serialize_f>
00890     struct serialize_to_subnode_f : serialize_binary_f_tag
00891     {
00892         //typedef serialize_to_subnode_f<BinaryFunctorT> type;
00893         std::string name;
00894         BinaryFunctorT functor;
00895 
00896 
00897         /**
00898         */
00899         serialize_to_subnode_f( const std::string & subnodename, BinaryFunctorT f )
00900             : name(subnodename),functor(f)
00901         {
00902         }
00903 
00904         /**
00905         */
00906         explicit serialize_to_subnode_f( const std::string & subnodename )
00907             : name(subnodename),functor()
00908         {
00909         }
00910 
00911         /**
00912            Creates a NodeType names this->name and calls
00913            this->functor( child, src ). If the functor fails,
00914            the child is deleted and dest is unmodified, else
00915            ownership of the child is transfered to dest, via
00916            node_traits<NodeType>::children(dest).push_back(child).
00917 
00918            Returns true on success, false on failure.
00919         */
00920         template <typename NodeType, typename SerializableT>
00921         inline bool operator()( NodeType & dest, SerializableT const & src ) const
00922         {
00923             typedef node_traits<NodeType> NTR;
00924             std::auto_ptr<NodeType> nap( NTR::create( this->name ) );
00925             return this->functor( *nap, src )
00926                 ? (NTR::children(dest).push_back( nap.release() ),true)
00927                 : false;
00928         }
00929 
00930     };
00931 
00932 
00933 
00934     /**
00935        Returns serialize_to_subnode_f<>( subnodename ).
00936 
00937        Added in 1.1.3.
00938     */
00939     inline serialize_to_subnode_f<>
00940     ser_to_subnode_f( const std::string & subnodename )
00941     {
00942         return serialize_to_subnode_f<>( subnodename );
00943     }
00944 
00945     /**
00946        Returns serialize_to_subnode_f<BinaryFunctorT>( subnodename, f ).
00947 
00948        Added in 1.1.3.
00949     */
00950     template <typename BinaryFunctorT>
00951     inline serialize_to_subnode_f<BinaryFunctorT>
00952     ser_to_subnode_f( const std::string & subnodename, BinaryFunctorT f )
00953     {
00954         return serialize_to_subnode_f<BinaryFunctorT>( subnodename, f );
00955     }
00956 
00957     
00958 
00959     /**
00960        Experimental. Added in 1.1.3.
00961 
00962        BinaryFunctorT must have:
00963 
00964        bool operator()( NodeType & dest, const SerializableT & src )
00965 
00966     */
00967     template <typename NodeType, typename BinaryFunctorT = serialize_f>
00968     struct serialize_to_subnode_unary_f : serialize_unary_serializable_f_tag
00969     {
00970         //typedef serialize_to_subnode_unary_f<NodeType,BinaryFunctorT> type;
00971         reference_f<NodeType> node;
00972         std::string name;
00973         BinaryFunctorT functor;
00974 
00975         /**
00976         */
00977         serialize_to_subnode_unary_f( NodeType & parent, const std::string & subnodename )
00978             : node(parent), name(subnodename),functor()
00979         {
00980         }
00981 
00982         /**
00983         */
00984         serialize_to_subnode_unary_f( NodeType & parent, const std::string & subnodename, BinaryFunctorT f )
00985             : node(parent), name(subnodename),functor(f)
00986         {
00987         }
00988 
00989         /**
00990            Creates a NodeType named this->name and calls
00991            this->functor( child, src ). If the functor fails,
00992            the child is deleted and dest is unmodified, else
00993            ownership of the child is transfered to dest, via
00994            node_traits<NodeType>::children(this->node()).push_back(child).
00995 
00996            Returns true on success, false on failure.
00997            
00998         */
00999         template <typename SerializableT>
01000         bool operator()( SerializableT const & src ) const
01001         {
01002             typedef node_traits<NodeType> NTR;
01003             std::auto_ptr<NodeType> nap( NTR::create( this->name ) );
01004             if( this->functor( *nap, src ) )
01005             {
01006                 NTR::children(this->node()).push_back( nap.release() );
01007             }
01008             return 0 == nap.get();
01009         }
01010     };
01011 
01012 
01013     /**
01014        Returns serialize_to_subnode_f<NodeType>( parent, subnodename ).
01015 
01016        Example:
01017        <pre>
01018        std::for_each( vec.begin(),
01019                   vec.end(),
01020                   ser_to_subnode_unary_f( mynode, "child" )
01021                 );
01022        </pre>
01023 
01024        Added in 1.1.3.
01025     */
01026     template <typename NodeType>
01027     inline serialize_to_subnode_unary_f<NodeType>
01028     ser_to_subnode_unary_f( NodeType & parent, const std::string & subnodename )
01029     {
01030         return serialize_to_subnode_unary_f<NodeType>( parent, subnodename );
01031     }
01032 
01033     /**
01034        Returns serialize_to_subnode_unary_f<NodeType,BinaryFunctorT>( parent, subnodename, f ).
01035 
01036        Example:
01037 
01038        <pre>
01039        std::for_each( vec.begin(),
01040                vec.end(),
01041                ser_to_subnode_f( mynode, "child", my_serialize_to_subnode_unary_functor() )
01042                );
01043        </pre>
01044 
01045        Added in 1.1.3.
01046     */
01047     template <typename NodeType, typename BinaryFunctorT>
01048     inline serialize_to_subnode_unary_f<NodeType,BinaryFunctorT>
01049     ser_to_subnode_unary_f( NodeType & parent, const std::string & subnodename, BinaryFunctorT f )
01050     {
01051         return serialize_to_subnode_unary_f<NodeType,BinaryFunctorT>( parent, subnodename, f );
01052     }
01053 
01054 
01055 
01056     /**
01057        
01058 
01059        BinaryFunctorT requires this signature:
01060 
01061        bool operator()( const NodeType & src, const std::string & subnodename, SerializableT & dest )
01062 
01063        Added in 1.1.3.
01064     */
01065     template <typename BinaryFunctorT = deserialize_f>
01066     struct deserialize_from_subnode_f : deserialize_binary_f_tag
01067     {
01068         //typedef deserialize_from_subnode_f<BinaryFunctorT> type;
01069         std::string name;
01070         BinaryFunctorT functor;
01071         deserialize_from_subnode_f( const std::string & subnodename )
01072             : name(subnodename),functor()
01073         {
01074         }
01075 
01076         deserialize_from_subnode_f( const std::string & subnodename, BinaryFunctorT f )
01077             : name(subnodename),functor(f)
01078         {
01079         }
01080 
01081         /**
01082            Searches for the first child in src named this->name. If it succeeds,
01083            it returns the result of this->functor( child, dest ), else it returns
01084            false.
01085         */
01086         template <typename NodeType, typename SerializableT>
01087         inline bool operator()( NodeType const & src, SerializableT & dest ) const
01088         {
01089             const NodeType * ch = ::s11n::find_child_by_name( src, this->name );
01090             return ch
01091                 ? this->functor( *ch, dest )
01092                 : false;
01093         }
01094     };
01095 
01096 
01097     /**
01098        Returns deserialize_from_subnode_f<>( parent, subnodename ).
01099 
01100        Added in 1.1.3.
01101     */
01102     inline deserialize_from_subnode_f<>
01103     deser_from_subnode_f( const std::string & subnodename )
01104     {
01105         return deserialize_from_subnode_f<>( subnodename );
01106     }
01107     /**
01108        Returns deserialize_from_subnode_f<BinaryFunctorT>( parent, subnodename, f ).
01109 
01110        Added in 1.1.3.
01111     */
01112     template <typename BinaryFunctorT>
01113     inline deserialize_from_subnode_f<BinaryFunctorT>
01114     deser_from_subnode_f( const std::string & subnodename, BinaryFunctorT f )
01115     {
01116         return deserialize_from_subnode_f<BinaryFunctorT>( subnodename, f );
01117     }
01118 
01119     /**
01120        BinaryFunctorT requires this signature:
01121 
01122        bool operator()( const NodeType & src, const std::string & subnodename, SerializableT & dest )
01123 
01124        Added in 1.1.3.
01125     */
01126     template <typename NodeType, typename BinaryFunctorT = deserialize_f>
01127     struct deserialize_from_subnode_unary_f : deserialize_unary_serializable_f_tag
01128     {
01129         //typedef deserialize_from_subnode_unary_f<NodeType,BinaryFunctorT> type;
01130         reference_f<NodeType const> node;
01131         std::string name;
01132         BinaryFunctorT functor;
01133         deserialize_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename )
01134             : node(parent), name(subnodename),functor()
01135         {
01136         }
01137 
01138         deserialize_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename, BinaryFunctorT f )
01139             : node(parent), name(subnodename),functor(f)
01140         {
01141         }
01142 
01143         /**
01144            Searches for the first child in this->node() named this->name. If it succeeds,
01145            it returns the result of this->functor( child, dest ), else it returns
01146            false.
01147         */
01148         template <typename SerializableT>
01149         inline bool operator()( SerializableT & dest ) const
01150         {
01151             const NodeType * ch = ::s11n::find_child_by_name( this->node(), this->name );
01152             return ch
01153                 ? this->functor( *ch, dest )
01154                 : false;
01155         }
01156     };
01157 
01158 
01159     /**
01160        Returns deserialize_from_subnode_unary_f<NodeType>( parent, subnodename ).
01161 
01162        Added in 1.1.3.
01163     */
01164     template <typename NodeType>
01165     inline deserialize_from_subnode_unary_f<NodeType>
01166     deser_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename )
01167     {
01168         return deserialize_from_subnode_unary_f<NodeType>( parent, subnodename );
01169     }
01170     /**
01171        Experimental. Added in 1.1.3.
01172 
01173        Returns deserialize_from_subnode_unary_f<NodeType,BinaryFunctorT>( parent, subnodename, f ).
01174     */
01175     template <typename NodeType, typename BinaryFunctorT>
01176     inline deserialize_from_subnode_unary_f<NodeType,BinaryFunctorT>
01177     deser_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename, BinaryFunctorT f )
01178     {
01179         return deserialize_from_subnode_unary_f<NodeType,BinaryFunctorT>( parent, subnodename, f );
01180     }
01181 
01182 
01183 
01184 
01185     /**
01186        Functor implementing AND logic and between two functors,
01187        which are expected to return values convertable to bool.
01188     */
01189     struct logical_and_binary_f
01190     {
01191         template <typename F1, typename F2>
01192         inline bool operator()( F1 const & f1, F2 const & f2 ) const
01193         {
01194             return f1() && f2();
01195         }
01196     };
01197 
01198     /**
01199        Functor implementing AND logic and between two functors,
01200        which are expected to return values convertable to bool.
01201     */
01202     template <typename F1>
01203     struct logical_and_unary_f
01204     {
01205         F1 functor;
01206         logical_and_unary_f( F1 const & f ) : functor(f)
01207         {}
01208         template <typename F2>
01209         inline bool operator()( F2 const & f2 ) const
01210         {
01211             return this->functor() && f2();
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     template <typename F1, typename F2>
01220     struct logical_and_nullary_f
01221     {
01222         F1 functor1;
01223         F2 functor2;
01224         logical_and_nullary_f( F1 const & f1, F2 const & f2 ) : functor1(f1), functor2(f2)
01225         {}
01226         inline bool operator()() const
01227         {
01228             return this->functor1() && this->functor2();
01229         }
01230     };
01231 
01232 
01233     /**
01234        Returns logical_and_nullary<F1,F2>(f1,f2).
01235     */
01236     template <typename F1, typename F2>
01237     inline logical_and_nullary_f<F1,F2>
01238     logical_and( F1 const & f1, F2 const & f2 )
01239     {
01240         return logical_and_nullary_f<F1,F2>(f1,f2);
01241     }
01242 
01243     /**
01244        Returns logical_and_unary<F1>(f1).
01245     */
01246     template <typename F1>
01247     inline logical_and_unary_f<F1>
01248     logical_and( F1 const & f1 )
01249     {
01250         return logical_and_unary_f<F1>(f1);
01251     }
01252 
01253     /**
01254        Returns logical_and_binary().
01255     */
01256     inline logical_and_binary_f
01257     logical_and()
01258     {
01259         return logical_and_binary_f();
01260     }
01261 
01262 
01263 
01264 
01265 } // namespace s11n
01266 
01267 
01268 #endif // s11n_net_s11n_1_1_FUNCTIONAL_HPP_INCLUDED

Generated on Sun Dec 18 18:38:02 2005 for libs11n-1.2.2 by  doxygen 1.4.4