traits.hpp

Go to the documentation of this file.
00001 #ifndef s11n_S11N_TRAITS_HPP_INCLUDED
00002 #define s11n_S11N_TRAITS_HPP_INCLUDED 1
00003 
00004 
00005 #include <vector>
00006 #include <map>
00007 
00008 #include <s11n.net/s11n/classload.hpp> // default classloader/factory implementation.
00009 #include <s11n.net/s11n/export.hpp> // S11N_EXPORT_API
00010 #include <s11n.net/s11n/type_traits.hpp>
00011 
00012 namespace s11n {
00013 
00014     /**
00015        node_traits encapsulates information relevant to Data
00016        Nodes, much in the same way that std::char_traits
00017        encapsulates character type information.
00018        
00019        The default implementation works with
00020        s11n::s11n_node or API-compatible
00021        types. Specializations may be defined to work with
00022        other node types.
00023        
00024        By using node_traits, instead of directly accessing a
00025        Node's API, client code may remain blissfully ignorant of
00026        the underlying node type.
00027 
00028        All API docs for this class which do not explicitely say
00029        "this implementation" (or similar) apply to all
00030        specializations of this type. They act as the "requirements
00031        document" for implementors of specializations.
00032 
00033        Changes from 1.0.x to 1.1.x:
00034 
00035        - Removed begin() and end(), because they are just as
00036        easily accessed via children().begin/end(), and it was not
00037        easy to remember if they returned iterators to the children
00038        or the properties.
00039 
00040        - Removed iterator typedefs, as they are (almost) as easily
00041        accessed via the appropriate container's typedefs. Again, this
00042        was to avoid confusion between the properties and children
00043        iterator types.
00044     */
00045     template <typename NodeT>
00046     struct S11N_EXPORT_API node_traits
00047     {
00048     public:
00049     /**
00050        The same as NodeT.
00051     */
00052     typedef NodeT node_type;
00053 
00054     /**
00055        The type uses to store properties for node_type
00056        objects.
00057     */
00058     typedef typename node_type::map_type property_map_type;
00059 
00060 
00061     /**
00062        The type used to store children of node_type
00063        objects.
00064     */
00065     typedef typename node_type::child_list_type child_list_type;
00066 
00067 
00068 
00069 
00070     /**
00071        Returns a new node_type. The caller owns the
00072        returned pointer.
00073 
00074        It is illegal for this function to return 0. If it
00075        cannot create a node for some reason, it must throw
00076        an exception.
00077     */
00078     static node_type * create()
00079     {
00080         return new node_type;
00081     }
00082 
00083     /**
00084        Returns a new node_type with the given name. The
00085        caller owns the returned pointer.
00086 
00087        See create() for the no-null-return rule.
00088     */
00089     static node_type * create( const std::string & nodename )
00090     {
00091         node_type * n = create();
00092         name( *n, nodename );
00093         return n;
00094     }
00095 
00096 
00097     /**
00098        Sets the property key to the given value in
00099        the given node.
00100 
00101        ValueT must support complementary ostream<< and
00102        istream>> operators.
00103     */
00104     template <typename ValueT>
00105     static void set( node_type & node,
00106              const std::string & key,
00107              const ValueT & value )
00108     {
00109         node.set( key, value );
00110     }
00111 
00112     /**
00113        Unsets (removes) the given property from node. It
00114        is not an error to unset an non-existing key.
00115     */
00116     static void unset( node_type & node,
00117                const std::string & key )
00118     {
00119         node.unset( key );
00120     }
00121 
00122     /**
00123        Returns true if node contains a property
00124        named key, else returns false.
00125     */
00126     static bool is_set( const node_type & node,
00127                 const std::string & key )
00128     {
00129         return node.is_set( key );
00130     }
00131 
00132 
00133     /**
00134        Returns an immutable reference to the node's map of properties.
00135     */
00136     static const property_map_type & properties( const node_type & node )
00137     {
00138         return node.properties();
00139     }
00140 
00141     /**
00142        Returns a mutable reference to the node's map of properties.
00143     */
00144     static property_map_type & properties( node_type & node )
00145     {
00146         return node.properties();
00147     }
00148 
00149     /**
00150        Returns the value of the property with the given
00151        key, or default_value if that property does not
00152        exist or cannot be lexically cast to type ValueT.
00153 
00154        ValueT must support complementary ostream<< and
00155        istream>> operators.
00156     */
00157     template <typename ValueT>
00158     static ValueT
00159     get( const node_type & node,
00160          const std::string & key,
00161          const ValueT & default_value )
00162     {
00163         return node.template get<ValueT>( key, default_value );
00164     }
00165 
00166     /**
00167        Returns a mutable list of children
00168        belonging to node.
00169     */
00170     static child_list_type & children( node_type & node )
00171     {
00172         return node.children();
00173     }
00174 
00175     /**
00176        Returns an immutable list of children
00177        belonging to node.
00178     */
00179     static const child_list_type & children( const node_type & node )
00180     {
00181         return node.children();
00182     }
00183 
00184     /**
00185        Sets the class name of the type for which node
00186        holds serialized data.
00187     */
00188     static void class_name( node_type & node, const std::string & classname )
00189     {
00190         node.class_name( classname );
00191     }
00192 
00193 
00194     /**
00195        Returns the class name of the type for which node
00196        holds serialized data.
00197     */
00198     static std::string class_name( const node_type & node )
00199     {
00200         return node.class_name();
00201     }
00202 
00203     /**
00204        Sets node's name. See the s11n lib manual for what
00205        conventions to follow. In short: the "variable name"
00206        rules from most programming languages are a good
00207        guideline.
00208     */
00209     static void name( node_type & node, const std::string & name )
00210     {
00211         node.name( name );
00212     }
00213 
00214 
00215     /**
00216        Returns node's name.
00217     */
00218     static std::string name( const node_type & node )
00219     {
00220         return node.name();
00221     }
00222 
00223     /**
00224        Removes all children and properties from node,
00225        freeing up their resources. Whether the node's
00226        name() and class_name() are cleared is
00227        implementation-defined. In practice, those are
00228        overwritten by algos as needed, so it has not been
00229        a concern.
00230     */
00231     static void clear( node_type & node )
00232     {
00233         node.clear();
00234     }
00235 
00236     /**
00237        Returns true if this object has no properties
00238        and no children. The name() and class_name()
00239        are *not* considered.
00240 
00241        Added in version 1.1.3.
00242     */
00243     static bool empty( const node_type & node )
00244     {
00245         return node.empty();
00246     }
00247 
00248     /**
00249        Swaps all publically-visible internal state of lhs
00250        with that of rhs. This includes:
00251 
00252        - class_name()
00253 
00254        - name()
00255 
00256        - children()
00257 
00258        - properties()
00259 
00260        Added in version 1.1.3.
00261     */
00262     static void swap( node_type & lhs, node_type & rhs )
00263     {
00264         return lhs.swap( rhs );
00265     }
00266 
00267     }; // end node_traits<>
00268 
00269 
00270     //  /**
00271     //     An unfortunate necessity.
00272     //  */
00273     //         template <typename NodeT>
00274     //         struct S11N_EXPORT_API node_traits<NodeT const> : node_traits<NodeT> {};
00275 
00276 
00277     /**
00278        A default serialization proxy, which simply
00279        forwards de/serialize calls to an interface
00280        implemented as two overloaded member functions
00281        SerializableType::operator()( NodeT ).
00282     */
00283     struct S11N_EXPORT_API default_serialize_functor
00284     {
00285     /**
00286        Serialize src to dest using src.operator()( dest ).
00287 
00288        The serialize operator must look like:
00289 
00290        bool operator()( NodeT & ) const;
00291 
00292        It may be virtual or a function template.
00293     */
00294     template <typename NodeT, typename SerializableType>
00295     bool operator()( NodeT & dest, const SerializableType & src ) const
00296     {
00297         return src.operator()( dest );
00298     }
00299 
00300     /**
00301        Deserialize dest from src using dest.operator()( src ).
00302 
00303        The deserialize operator must look like:
00304 
00305        bool operator()( const NodeT & );
00306 
00307        It may be virtual or a function template.
00308     */
00309     template <typename NodeT, typename DeserializableType>
00310     bool operator()( const NodeT & src, DeserializableType & dest ) const
00311     {
00312         return dest.operator()( src );
00313     }
00314     };
00315 
00316 
00317     /**
00318        A default implementation for
00319        s11n_traits::cleanup_functor. Compatible implementations
00320        and specializations must follow the conventions defined for
00321        this class.
00322 
00323        This implementation is only suitable for cleaning up types
00324        which manage any child pointers which are assigned to them
00325        during deserialization. For example, std:: containers do
00326        not own their pointers, and therefor require a
00327        specialization of this type to clean them up.
00328 
00329        SerializableType must be a Serializable and may be
00330        pointer-qualified.
00331 
00332        The library manual goes into more detail about what this
00333        type is for.
00334 
00335        The operations of this class are declared as throw() because
00336        of their logical role in the destruction process, and destructors
00337        are not generally allowed to throw.
00338     */
00339     template <typename SerializableType>
00340     struct default_cleanup_functor
00341     {
00342     typedef typename type_traits<SerializableType>::type serializable_type;
00343 
00344     /**
00345        Default implementation does nothing, though we
00346        should arguably assign to a default-constructed
00347        object.
00348 
00349        Specializations must do any cleanup they need to
00350        here. For example, container specializations must
00351        a) deallocate any heap-based entries and b) empty
00352        the list. Specializations are free to do a
00353        default-assign, as mentioned above, but are not
00354        required to. Specializations for containers must
00355        recursively use s11n_trait::cleanup_functor for
00356        the contained types, to ensure that they can properly
00357        clean up containers holding other containers.
00358     */
00359     void operator()( serializable_type & ) const throw()
00360     {
00361     }
00362 
00363     };
00364 
00365     /**
00366        s11n_traits encapsulates information about what
00367        type(s) are responsible for handling de/serialize
00368        operations for a given type, plus the factory for
00369        that type. It should be specialized to define
00370        various aspects of serialization for a given type.
00371 
00372        The interface shown here is the bare minimum which
00373        s11n_traits specializations must implement.
00374        Specializations may optionally add to the
00375        interface, but client code is discouraged from
00376        relying on any extensions.
00377 
00378        This type is stateless, and specializations are
00379        expected to be stateless (at least, they will
00380        be treated as if they are).
00381 
00382        Client code is not expected to need to use this
00383        type directly, except for purposes of plugging in
00384        their types into the s11n framework. More
00385        specifically, it is not expected that Serializables
00386        will use this type.
00387 
00388        Parameterized on:
00389 
00390        SerializableT: the base-most Serializable
00391        type. This is the base-most point of reference for
00392        classloading and "template typing". Subclasses of
00393        SerializableT are assumed to be handleable via the
00394        same de/serialize interface as SerializableT.
00395 
00396        InterfaceType is the base Serializable interface which
00397        SerializableT is assumed to subclass. The default is
00398        SerializableT. This type is required for cases where
00399        SerializableT wants to register with multiple Serializable
00400        interfaces.
00401 
00402        Changes from 1.0.x to 1.1.x:
00403 
00404        - Added class_name() member to replace the ::classname()
00405        family of code in 1.1.0.
00406 
00407        - cleanup_functor added in 1.1.3.
00408 
00409        - InterfaceType added in 1.2.7/1.3.1.
00410     */
00411 
00412     template <typename SerializableT, typename InterfaceType = SerializableT>
00413     struct S11N_EXPORT_API s11n_traits
00414     {
00415     /**
00416        The s11n framework instantiates an s11n_traits
00417        object at some points to allow the traits object
00418        to do things like factory registration.
00419     */
00420     s11n_traits(){}
00421     ~s11n_traits(){}
00422 
00423     /**
00424        The InterfaceType. Added in 1.3.1. This is needed
00425        for cases where a Serializable wants to be registered
00426        with several Serializable interfaces. If we don't
00427        have this key then ODR violations happen on the second
00428        and subsequent registration.
00429     */
00430     typedef InterfaceType serializable_interface_type;
00431 
00432     /**
00433        The type of object we want to [de]serialize.
00434     */
00435     typedef SerializableT serializable_type;
00436 
00437     /**
00438        Type which will be used to instantiate new objects
00439        of serializable_type. It must implement:
00440 
00441        serializable_type * operator()( const std::string & classname ) const;
00442 
00443        It is expected to return, polymorphically if
00444        possible, a new serializable_type on success or 0
00445        on failure.
00446 
00447        The default factory_type works with types
00448        registered via the s11n::cl::classload()
00449        family of functions.
00450     */
00451     typedef ::s11n::cl::object_factory<serializable_interface_type> factory_type;
00452 
00453     /**
00454        Functor type implementing serialize code.
00455 
00456        Must implement:
00457 
00458        bool operator()( SomeNodeType & dest, const base_type & src ) const;
00459 
00460     */
00461     typedef ::s11n::default_serialize_functor serialize_functor;
00462 
00463     /**
00464        Functor type implementing deserialize code.
00465 
00466        Must implement:
00467 
00468        bool operator()( const SomeNodeType & src, base_type & dest ) const;
00469     */
00470     typedef ::s11n::default_serialize_functor deserialize_functor;
00471 
00472     /**
00473        This type is used to clean up a partial deserialized object
00474        on error. If this functor, and all specializations it calls,
00475        do their part, we can make much better exception guarantees,
00476        theoretically avoiding any leaks due to exceptions thrown
00477        during deserialization.
00478 
00479        cleanup_functor must follow the conventions laid out by
00480        s11n::default_cleanup_functor<serializable_type>.
00481     */
00482     typedef ::s11n::default_cleanup_functor<serializable_type> cleanup_functor;
00483 
00484     /**
00485        As of s11n 1.1, specializations must define the
00486        class_name() function. This implementation returns
00487        a useless, unspecified class name. Specializations
00488        must return the class name of serializable_type,
00489        preferably polymorphically (polymorphic naming is
00490        unfortunately not possible without some client-side
00491        help).
00492 
00493        instance_hint is a HINT to this class as to the
00494        actual instance we want the name for, and may be
00495        0. It is provided so that class hierarchies which
00496        have virtual functions like className() can make
00497        those available to the core library via s11n_traits
00498        specializations.
00499 
00500        Specializations MUST accept 0 as a valid
00501        instance_hint value are are NEVER REQUIRED to pay
00502        any attention to instance_hint. The default
00503        implementation does nothing with it.
00504 
00505        Design notes:
00506 
00507        - It really should take a default value of 0 for
00508        instance_hint, but the idea of relying on a default
00509        value, considering things like how template
00510        specializations should define them and subclassing
00511        (though that is not an issue *here*), gives me the
00512        willies. Too much room for error there.
00513 
00514        - Also, we could probably argue that it should
00515        return a const string.
00516 
00517        - We could argue that it should return an empty string
00518        instead of a useless one. i don't want to to generate
00519        output which might break parsers, though.
00520            
00521     */
00522     static const std::string class_name( const serializable_type * /* instance_hint */ )
00523     {
00524         return "unknown";
00525     }
00526 
00527     }; // end s11n_traits<>
00528 
00529 //     template <typename SerializableT>
00530 //     struct S11N_EXPORT_API s11n_traits<SerializableT> : s11n_traits<SerializableT,SerializableT>
00531 //     {};
00532 
00533 
00534     /**
00535        A general specialization to treat (T*) as (T) for s11n_traits
00536        purposes. This is necessary for some template argument resolution
00537        to work as desired.
00538 
00539        Added in 1.1.3.
00540     */
00541     template <typename T>
00542     struct S11N_EXPORT_API s11n_traits<T *> : public s11n_traits<T> {};
00543 
00544 
00545 }  // namespace s11n
00546 
00547 
00548 #endif // s11n_S11N_TRAITS_HPP_INCLUDED

Generated on Wed Jun 4 21:45:46 2008 for libs11n-1.2.7 by  doxygen 1.5.3