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

property_server.h

00001 #ifndef s11n_PROPERTY_SERVER_H_INCLUDED 00002 #define s11n_PROPERTY_SERVER_H_INCLUDED 1 00003 #include <string> 00004 00005 #include <s11n/to_string.h> // to/from_string() 00006 #include <s11n/phoenix.h> // phoenix class 00007 00008 namespace s11n { 00009 00010 /** 00011 property_server is an experimental class for tying 00012 arbitrary properties to arbitrary objects. It supports, as 00013 values, any data types which are i/ostreamable using their 00014 <code> >>istream</code> or <code>ostream<< </code> 00015 operators. 00016 00017 License: Do As You Damned Well Please 00018 Author: stephan@s11n.net 00019 00020 */ 00021 00022 template <typename ContextType, typename ObjIDType = ContextType *, typename KeyType = std::string> 00023 class property_server 00024 { 00025 public: 00026 /** 00027 The "sharing context" used by this type. 00028 */ 00029 typedef ContextType context_type; 00030 00031 /** The type used to key objects to their properties. */ 00032 typedef ObjIDType object_id_type; 00033 00034 /** The key type used for properties. */ 00035 typedef KeyType key_type; 00036 00037 /** The underlying data store for properties. */ 00038 typedef std::map<key_type,std::string> property_map_type; 00039 00040 00041 /** 00042 Sets the property key to val for objid. 00043 */ 00044 template <typename ValueType> 00045 static void set( const object_id_type objid, const key_type & key, const ValueType & val ) 00046 { 00047 object_map()[objid][key] = s11n::to_string( val ); 00048 } 00049 00050 /** 00051 Returns the property key for objid. If there is an error 00052 converting the value to ValueType, or if the property does 00053 not exist, defaultval is returned. This can be used to 00054 implement custom error handling by passing a known-invalid 00055 value as defaultval and interpretting it as an error 00056 value. If there is *no* known-invalid combinations then you 00057 can check twice with two different defaulvals. If 00058 defaultval is returned both times then there is definately 00059 an error, because valid data would only be interpretted one 00060 way and you've checked against two different defaultvals. 00061 */ 00062 template <typename ValueType> 00063 static ValueType get( const object_id_type objid, const key_type & key, const ValueType & defaultval ) 00064 { 00065 typename object_map_type::const_iterator it = object_map().find( objid ); 00066 if( object_map().end() == it ) return defaultval; 00067 const property_map_type & pmap = it.second; 00068 typename property_map_type::const_iterator pit = pmap.find( key ); 00069 if( pmap.end() == pit ) return defaultval; 00070 return s11n::from_string<ValueType>( pit.second, defaultval ); 00071 } 00072 00073 /** 00074 Removes the given property from the given object. 00075 */ 00076 static void unset( const object_id_type objid, const key_type & key ) 00077 { 00078 typename object_map_type::const_iterator it = object_map().find( objid ); 00079 if( object_map().end() == it ) return; 00080 const property_map_type & pmap = it.second; 00081 typename property_map_type::const_iterator pit = pmap.find( key ); 00082 if( pmap.end() == pit ) return; 00083 pmap.erase( pit ); 00084 } 00085 00086 /** 00087 Removes the property map for objid, freeing up any 00088 resources it consumed. 00089 */ 00090 static void clear( const object_id_type objid ) 00091 { 00092 typename object_map_type::iterator it = object_map().find( objid ); 00093 if( object_map().end() == it ) return; 00094 object_map().erase( it ); 00095 } 00096 00097 /** Removes all properties for all objects. */ 00098 static void clear_all() 00099 { 00100 object_map().clear(); 00101 } 00102 00103 // typedef void (change_listener_callback)( object_id_type, const key_type key & ); 00104 // void add_change_listener( change_listener_callback cb ); 00105 00106 /** 00107 Returns a pointer to the given object's property map, or 0 00108 if no properties have been set for the object (or if 00109 clear(objid) has been called). 00110 00111 The caller does not own the returned pointer and (ideally) 00112 should not modify the map directly (prefer get() and 00113 set()). It is provided here primarily for serialization 00114 purposes: so the map can be saved and loaded using 00115 arbitrary serialization techniques. 00116 */ 00117 static property_map_type * get_map( const object_id_type objid ) 00118 { 00119 typename object_map_type::iterator it = object_map().find( objid ); 00120 if( object_map().end() == it ) return 0; 00121 property_map_type * pm = & ((*it).second); 00122 return pm; 00123 } 00124 00125 private: 00126 typedef property_server< ContextType, ObjIDType > this_type; 00127 typedef std::map<object_id_type,property_map_type> object_map_type; 00128 00129 static object_map_type & object_map() 00130 { 00131 return s11n::phoenix<object_map_type,this_type>::instance(); 00132 } 00133 00134 }; 00135 00136 } // namespace s11n_s11n 00137 00138 #endif // PROPERTY_SERVER_H_INCLUDED

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