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

Generated on Thu Sep 29 20:01:14 2005 for libs11n-1.1.3-dev by  doxygen 1.4.1