Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members

abstract_creator.h

00001 #ifndef s11n_ABSTRACT_CREATOR_H_INCLUDED 00002 #define s11n_ABSTRACT_CREATOR_H_INCLUDED 1 00003 00004 //////////////////////////////////////////////////////////////////////// 00005 // abstract_creatore.h: 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 <cassert> 00013 #ifdef NDEBUG 00014 # undef NDEBUG // force assert() 00015 #endif 00016 00017 #include <string> 00018 #include "s11n_core.h" // classload 00019 #include <s11n/class_name.h> 00020 00021 namespace s11n 00022 { 00023 00024 /** 00025 abstract_creator is a helper to avoid some code having to 00026 know if a type is created on a stack or the heap. This 00027 makes some template code easier to write, as it avoids 00028 syntax errors when trying something like: 00029 00030 <pre> 00031 if( object type is a pointer type ) delete(object); 00032 else { ... } 00033 </pre> 00034 00035 This implementation creates items the stack via the default 00036 ctor. If instantiated with (T *) a pointer/heap-based 00037 specialization is activated instead. 00038 00039 Designed for use with, e.g., ListType::value_type, which 00040 will may be, e.g., either T or (T *). 00041 00042 These objects contain no state information. 00043 */ 00044 template <typename T> 00045 struct abstract_creator 00046 { 00047 /** Same as (T). */ 00048 typedef T value_type; 00049 00050 /** Same as (T). */ 00051 typedef T base_value_type; 00052 00053 /** 00054 This implementation does nothing and 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 static bool create( value_type & v, 00061 const std::string & = std::string() ) 00062 { 00063 return true; 00064 } 00065 00066 /** 00067 Assigs lhs to rhs and true. 00068 */ 00069 static void assign( value_type &lhs, const value_type & rhs ) 00070 { 00071 lhs = rhs; 00072 return; 00073 } 00074 00075 /** 00076 Returns a copy of. 00077 */ 00078 static value_type copy( const value_type & rhs ) 00079 { 00080 return rhs; 00081 } 00082 00083 /** 00084 Does nothing in this specialization. Specializations 00085 which allocate resources are expected to release them here. 00086 00087 Note that release() exists because using a static boolean 00088 to flag a clean-up mode won't work: 00089 00090 <pre> 00091 typedef double T; 00092 T val; 00093 if( val is a pointer type ) { delete( val ); } 00094 else ... 00095 </pre> 00096 00097 That will only work when T is actually a pointer type. 00098 Thus the following workaround: 00099 00100 <pre> 00101 typedef [some type] T; 00102 T val; 00103 typedef abstract_creator&lt;T&gt; AC; 00104 assert( AC::create(val) ); // fine for (T) or (T *) 00105 ... use val ... 00106 AC::release(val); // deletes pointers. No-op for value types 00107 </pre> 00108 That works with pointers or non-pointers, and simply does nothing 00109 for non-pointers. 00110 00111 See object_reference_wrapper for a type which can wrap 00112 function calls to objects using the dot notation, 00113 regardless of their pointerness. 00114 */ 00115 static void release( value_type & ) 00116 { 00117 return; 00118 } 00119 00120 }; // abstract_creator<T> 00121 00122 /** 00123 A specialization of abstract_creator to create objects on 00124 the heap, using the s11n classloader. 00125 */ 00126 template <typename T> 00127 struct abstract_creator<T *> 00128 { 00129 /** Same as (T *). */ 00130 typedef T * value_type; 00131 00132 /** Same as (T). */ 00133 typedef T base_value_type; 00134 00135 /** 00136 Tries to create a value_type object, 00137 using classload&lt;base_value_type&gt;( key ) 00138 to create it. v is assigned to it's value, which 00139 may be 0. Returns true if an object is created, 00140 else false. 00141 00142 The caller owns the returned object. 00143 00144 Maintenance note: new classloader registrations may 00145 need to be installed as new types show up, 00146 especially for streamables/PODs (because those 00147 aren't normally registered as classes), or this 00148 function won't handle them. In s11n this 00149 registration is handled by most of the various 00150 proxy installation macros. 00151 */ 00152 static bool create( value_type & v, 00153 const std::string & implclass = std::string() /* guess! */ ) 00154 { 00155 const std::string key = 00156 (! implclass.empty()) 00157 ? implclass 00158 : ::classname<value_type>(); 00159 00160 v = classload<base_value_type>( key ); 00161 //CERR << "create("<<key<<")=" <<std::hex<<v <<"\n"; 00162 return 0 != &v; 00163 } 00164 00165 /** 00166 Creates a MONOMORPHIC copy of rhs and returns it. 00167 00168 This copy is only useful for non-polymorphic 00169 types. 00170 */ 00171 static value_type copy( const value_type & rhs ) 00172 { 00173 return new base_value_type(rhs); 00174 } 00175 00176 /** 00177 Returns rhs. 00178 */ 00179 static void assign( value_type &lhs, const value_type & rhs ) 00180 { 00181 lhs = rhs; 00182 return; 00183 } 00184 00185 00186 /** 00187 Deletes v and assigns it to 0. 00188 */ 00189 static void release( value_type & v ) 00190 { 00191 //CERR << "release(" << std::hex<<v<<")\n"; 00192 delete( v ); 00193 v = 0; 00194 } 00195 }; // abstract_creator<T *> 00196 00197 00198 } // namespace 00199 00200 #endif // s11n_ABSTRACT_CREATOR_H_INCLUDED 00201

Generated on Tue Jul 20 10:46:47 2004 for s11n by doxygen 1.3.7