abstract_creator.hpp

Go to the documentation of this file.
00001 #ifndef s11n_ABSTRACT_CREATOR_H_INCLUDED
00002 #define s11n_ABSTRACT_CREATOR_H_INCLUDED 1
00003 
00004 ////////////////////////////////////////////////////////////////////////
00005 // abstract_creatore.hpp:
00006 // Defines a difficult-to-describe class. See the docs.
00007 //
00008 //    Author: stephan beal <stephan@s11n.net>
00009 //    License: Public Domain
00010 ////////////////////////////////////////////////////////////////////////
00011 
00012 #include <string>
00013 #include "classload.hpp" // classloader-related funcs
00014 #include <s11n.net/s11n/traits.hpp> // s11n_traits
00015 
00016 namespace s11n { namespace Private {
00017 
00018 
00019         /**
00020            abstract_creator is an internal helper to avoid some code
00021            having to know if a type is created on a stack or the
00022            heap. This makes some template code easier to write, as it
00023            avoids syntax errors when trying something like:
00024 
00025 <pre>
00026 if( object type is a pointer type ) delete(object);
00027 else { ... }
00028 </pre>
00029 
00030            This implementation creates items the stack via the default
00031            ctor. If instantiated with (T *) a pointer/heap-based
00032            specialization is activated instead.
00033 
00034            Designed for use with, e.g., ListType<T>, for which T
00035            may be either T or (T *).
00036 
00037            These objects contain no state information.
00038 
00039        The member function release() was removed in s11n 1.1.3,
00040        as it was potentially dangerous. s11n_traits::cleanup_functor
00041        replaces that functionality and does so correctly.
00042         */
00043         template <typename T>
00044         struct abstract_creator
00045         {
00046                 /** Same as (T). */
00047                 typedef T value_type;
00048 
00049                 /** Same as (T). */
00050                 typedef T base_value_type;
00051 
00052                 /**
00053                    This implementation assigns v to value_type() and
00054                    returns true.
00055 
00056                    The string argument is bogus for this implementation,
00057                    and is used by the pointer specialization to implement
00058                    polymorphic classloading of value_type.
00059 
00060                    Historical note: before s11n release 0.9.17 this function
00061                    incorrectly did nothing. While this works for many
00062                    cases, it caused a subtle, hard-to-track bug in
00063                    s11n::list::deserialize_list(), in which a deserialized
00064                    list was re-used when the function was called recursively.
00065                    Many thanks to Patrick Lin for reporting that problem.
00066 
00067                 */
00068                 static bool create( value_type & v,
00069                                     const std::string & /* implclass */  = std::string()  ) throw()
00070                 {
00071                         // if( 0 ) CERR << "create(&) implclass="<<implclass<<": initializing @" <<std::hex<<&v <<"\n";
00072             try
00073             {
00074                 v = value_type();
00075             }
00076             catch(...)
00077             {
00078                 return false;
00079             }
00080                         return true;
00081                 }
00082 
00083         }; // abstract_creator<T>
00084 
00085         /**
00086            A specialization of abstract_creator to create objects on
00087            the heap, using the s11n::cl API.
00088         */
00089         template <typename T>
00090         struct abstract_creator<T *>
00091         {
00092                 /** Same as (T *). */
00093                 typedef T * value_type;
00094  
00095                /** Same as (T). */
00096                 typedef T base_value_type;
00097 
00098                 /**
00099                    Tries to create a value_type object,
00100                    using classload&lt;base_value_type&gt;( key )
00101                    to create it. v is assigned to it's value, which
00102                    may be 0. Returns true if an object is created,
00103                    else false.
00104 
00105                    If the call succeeds, the caller owns the memory
00106                    pointed to by v.
00107 
00108            If implclass is NOT passed then it must guess and
00109            for polymorphic types it is likely to guess
00110            incorrectly. It relies on
00111            s11n_traits<base_value_type>::class_name(v)
00112            returning a valid value, which is normally only
00113            useful for monomorphic types and base-most
00114            Serializables in a registered hierarchy (which are,
00115            for s11n purposes, the same thing).
00116 
00117                    Maintenance note: new classloader registrations may
00118                    need to be installed as new types show up,
00119                    especially for streamables/PODs (because those
00120                    aren't normally registered as classes), or this
00121                    function won't handle them. In s11n this
00122                    registration is handled by most of the various
00123                    proxy installation macros. See the headers under
00124            s11n.net/s11n/proxy/pod_*.hpp for examples.
00125                 */
00126                 static bool create(  value_type & v,
00127                                      const std::string & implclass = std::string() /* guess! */  ) throw()
00128                 {
00129             try
00130             {
00131                 typedef s11n_traits<base_value_type> STR;
00132                 const std::string key = 
00133                     (! implclass.empty())
00134                     ? implclass
00135                     : STR::class_name(v); // reminder: v is a ref to a pointer!
00136                 v = ::s11n::cl::classload<base_value_type>( key );
00137                 // if( 0 ) CERR << "create(*) implclass=["<<key<<"] allocated @" <<std::hex<<&v <<"\n";
00138             }
00139             catch(...)
00140             {
00141                 return false;
00142             }
00143                         return 0 != &v;
00144                 }
00145         }; // abstract_creator<T *>
00146 
00147 
00148 } } // namespaces
00149 
00150 #endif // s11n_ABSTRACT_CREATOR_H_INCLUDED
00151 

Generated on Sat Mar 20 12:29:24 2010 for libs11n-1.2.10 by  doxygen 1.6.1