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

functor.h

00001 #ifndef s11n_FUNCTOR_H_INCLUDED 00002 #define s11n_FUNCTOR_H_INCLUDED 1 00003 ///////////////////////////////////////////////////////////////////////// 00004 // functor.h: generic functors 00005 // Author: stephan beal <stephan@s11n.net> 00006 // License: Public Domain 00007 ///////////////////////////////////////////////////////////////////////// 00008 00009 namespace s11n 00010 { 00011 00012 // /** 00013 // Swiped from Alexandrescu: 00014 // http://www.cuj.com/experts/1810/ 00015 // */ 00016 // template <int v> 00017 // struct Int2Type 00018 // { 00019 // enum { value = v }; 00020 // }; 00021 00022 00023 00024 /** 00025 Deletes an object passed to it. 00026 00027 This type accepts non-pointer types for "destruction." This 00028 is a non-operation, and is supported to allow other 00029 template code to generically free objects without needing 00030 to know if they are pointers. This allows some 00031 formerly-non-consolidatable reference-vs-pointer-type code to 00032 share a single implementation, as "delete(myobj)" is not 00033 valid for non-pointer types, but object_deleter()(myobj) 00034 is. 00035 */ 00036 struct object_deleter 00037 { 00038 /** 00039 Deletes t. 00040 */ 00041 template <typename T> 00042 void operator()( const T * t ) const 00043 { 00044 // i don't fully understand why 00045 // delete( const T * ) is legal, 00046 // considering that it triggers a dtor, 00047 // and dtors are non-const. 00048 delete( t ); 00049 } 00050 /** 00051 Does nothing: is here to allow some 00052 reference-vs-pointer-type transparency. 00053 */ 00054 template <typename T> 00055 void operator()( const T & t ) const 00056 {} 00057 }; 00058 00059 00060 00061 /** 00062 object_reference_wrapper is a type for giving access 00063 to T objects via their dot operator, regardless of whether 00064 they are pointers or not. 00065 00066 Intended for use with value_types which come from, e.g., 00067 std::list, so objects of those types can be called using 00068 the same syntax regardless of whether they are pointer 00069 types or not. 00070 00071 e.g., assuming MyType might be a pointer or a reference, 00072 we can ignore that difference for call-syntax purposes 00073 with: 00074 <pre> 00075 object_reference_wrapper&lt;MyType&gt; wrap; 00076 wrap(myobj).memberfunc(); 00077 </pre> 00078 00079 or: 00080 00081 <pre> 00082 object_reference_wrapper&lt;MyType&gt; wrap(myobj); 00083 wrap().memberfunc(); 00084 </pre> 00085 */ 00086 template <typename T> 00087 struct object_reference_wrapper 00088 { 00089 typedef T value_type; 00090 typedef T base_value_type; 00091 object_reference_wrapper() : m_ptr(0) {} 00092 object_reference_wrapper( value_type &obj ) : m_ptr(&obj) {}; 00093 /** 00094 Sets this object's proxy object to t and returns t. 00095 */ 00096 base_value_type & operator()( value_type & t ) 00097 { 00098 this->m_ptr = &t; 00099 return t; 00100 } 00101 /** 00102 Returns this object's wrapped object. 00103 00104 ACHTUNG: this function WILL Cause Grief if it is called 00105 on a default-constructed version of this object: you must 00106 set this object's wrapped value using the ctor (or via 00107 copying) before calling this. 00108 */ 00109 base_value_type & operator()() const { return *(this->m_ptr); } 00110 00111 /** 00112 Returns true if this object is wrapping a non-0 object, else 00113 false. 00114 */ 00115 bool good() const 00116 { 00117 return 0 != this->m_ptr; 00118 } 00119 00120 private: 00121 value_type * m_ptr; 00122 }; 00123 00124 /** 00125 A specialization to wrap pointers to (T *) such that they 00126 can be accessed, via this wrapper, using a dot instead of 00127 <tt>-&gt;</tt>. 00128 */ 00129 template <typename T> 00130 struct object_reference_wrapper<T *> 00131 { 00132 typedef T * value_type; 00133 typedef T base_value_type; 00134 object_reference_wrapper() : m_ptr(0) {} 00135 object_reference_wrapper( value_type & obj ) : m_ptr(obj) {}; 00136 /** Sets this object's proxied object to t and Returns t. */ 00137 base_value_type & operator()( value_type & t ) 00138 { 00139 this->m_ptr = t; 00140 return *t; 00141 } 00142 /** Returns this object's wrapped object. 00143 00144 ACHTUNG: this function WILL Cause Grief if it is 00145 called on a default-constructed version of this 00146 object: you must set this object's wrapped value 00147 using the ctor, operator(T), or via copying this 00148 object from a properly-initialized one before 00149 calling this. 00150 */ 00151 base_value_type & operator()() const { return *(this->m_ptr); } 00152 private: 00153 base_value_type * m_ptr; 00154 }; 00155 00156 00157 /** 00158 const_object_reference_wrapper is identical in usage to 00159 object_reference_wrapper, except that it deals with const 00160 objects. It is a separate functor to avoid ambiguity and 00161 some impossible overloads. 00162 */ 00163 template <typename T> 00164 struct const_object_reference_wrapper 00165 { 00166 typedef T value_type; 00167 typedef T base_value_type; 00168 const_object_reference_wrapper() : m_ptr(0) {} 00169 const_object_reference_wrapper( const value_type &obj ) : m_ptr(&obj) {}; 00170 /** 00171 Sets this object's proxied obj to t and returns t. 00172 */ 00173 const base_value_type & operator()( const value_type & t ) 00174 { 00175 this->m_ptr = t; 00176 return t; 00177 } 00178 /** 00179 Returns this object's wrapped object. 00180 00181 ACHTUNG: this function WILL Cause Grief if it is 00182 called on a default-constructed version of this 00183 object: you must set this object's wrapped value 00184 using the ctor, operator(T), or via copying this 00185 object from a properly-initialized one before 00186 calling this. 00187 */ 00188 const base_value_type & operator()() const { return *this->m_ptr; } 00189 private: 00190 const value_type * m_ptr; 00191 }; 00192 00193 /** 00194 A specialization to wrap pointers to (T *) such that they 00195 can be accessed, via this wrapper, using a dot instead of 00196 <tt>-&gt;</tt>. 00197 */ 00198 template <typename T> 00199 struct const_object_reference_wrapper<T *> 00200 { 00201 typedef T * value_type; 00202 typedef T base_value_type; 00203 const_object_reference_wrapper() : m_ptr(0) {} 00204 const_object_reference_wrapper( const value_type & obj ) : m_ptr(obj) {}; 00205 /** Returns (*t). */ 00206 const base_value_type & operator()( value_type & t ) 00207 { 00208 this->m_ptr = t; 00209 return *t; 00210 } 00211 /** Returns this object's wrapped object. */ 00212 const base_value_type & operator()() const { return *(this->m_ptr); } 00213 private: 00214 const base_value_type * m_ptr; 00215 }; 00216 00217 /** 00218 A convenience function to return an 00219 object_reference_wrapper for t. 00220 */ 00221 template <typename T> 00222 object_reference_wrapper<T> 00223 reference_wrapper( T & t ) 00224 { 00225 return object_reference_wrapper<T>( t ); 00226 } 00227 00228 /** 00229 A convenience function to return an 00230 empty object_reference_wrapper. 00231 */ 00232 template <typename T> 00233 object_reference_wrapper<T> 00234 reference_wrapper() 00235 { 00236 return object_reference_wrapper<T>(); 00237 } 00238 00239 /** 00240 A convenience function to return a 00241 const_reference_wrapper wrapping t. 00242 */ 00243 template <typename T> 00244 const_object_reference_wrapper<T> 00245 const_reference_wrapper( const T & t ) 00246 { 00247 return const_object_reference_wrapper<T>( t ); 00248 } 00249 00250 /** 00251 A convenience function to return an 00252 empty const_reference_wrapper. 00253 */ 00254 template <typename T> 00255 const_object_reference_wrapper<T> 00256 const_reference_wrapper() 00257 { 00258 return const_object_reference_wrapper<T>(); 00259 } 00260 00261 00262 /** 00263 A functor allowing pairs of PODs and pointers to be 00264 mixed together in any combination and be deallocated in a 00265 uniform way. Admitedly, it's a waste of time for value types, 00266 but the point is a single functor which can work for all 00267 pair types. 00268 00269 sample: 00270 00271 std::for_each( map.begin(), map.end(), pair_entry_deallocator() ); 00272 00273 */ 00274 struct pair_entry_deallocator 00275 { 00276 /** 00277 Deallocates p.first and p.second. PairType must not 00278 be a pointer type. 00279 */ 00280 template <typename PairType> 00281 void operator()( PairType & p ) const 00282 { 00283 object_deleter od; 00284 od( p.first ); 00285 od( p.second ); 00286 } 00287 }; 00288 00289 00290 /** 00291 child_pointer_deep_copier is a functor to deep-copy 00292 a list of pointers into another list. Designed for 00293 use with std::for_each and the like. 00294 00295 ListType must support: 00296 00297 <code>push_back( value_type * )</code>. 00298 00299 ACHTUNG: This is only useful for non-polymorphic 00300 copying. 00301 00302 It might be interesting to note that copying 00303 S11N_NS::data_node objects this way is 00304 "pseudo-polymorphic" - the copy itself is 00305 monomorphic but the data needed to deserialize the 00306 proper type from the node is maintained. 00307 */ 00308 template <typename ListType> 00309 class child_pointer_deep_copier 00310 { 00311 private: 00312 template <typename T> struct PtrStrip { typedef T type; }; 00313 template <typename T> struct PtrStrip<T *> { typedef T type; }; 00314 public: 00315 typedef ListType list_type; 00316 typedef typename ListType::value_type full_value_type; 00317 typedef typename PtrStrip<full_value_type>::type value_type; // that is, list_type::value_type, minus any pointer part. 00318 /** 00319 Target list must outlive this object. 00320 */ 00321 child_pointer_deep_copier( list_type & target ) : m_childs(&target) 00322 {} 00323 00324 /** 00325 Inserts a copy of p into this object's list and returns true. 00326 00327 Returns true if p is successfully copied. 00328 00329 If an exception thrown while copying this function has 00330 no effect, and the target node is not modified. 00331 00332 The target node takes ownership of the new copy of p. 00333 */ 00334 bool operator()( const value_type * p ) 00335 { 00336 if( ! this->m_childs || ! p ) return false; 00337 value_type * cp = 0; 00338 try 00339 { 00340 cp = new value_type( *p ); // todo: polymorphic cloning! 00341 if( ! cp ) return false; 00342 } 00343 catch(...) { 00344 delete( cp ); // i honestly don't know if i need this here :/ 00345 return false; 00346 } 00347 this->m_childs->push_back( cp ); 00348 00349 return true; 00350 } 00351 private: 00352 list_type * m_childs; 00353 }; 00354 00355 00356 00357 /** 00358 For each item in [first,last), copies the item to OutputIt 00359 if pred(*item) returns true. 00360 00361 Copied from: 00362 00363 http://www.bauklimatik-dresden.de/privat/nicolai/html/en/cpp.html 00364 */ 00365 00366 template <typename InputIt, typename OutputIt, typename Predicate> 00367 OutputIt copy_if (InputIt first, 00368 InputIt last, 00369 OutputIt result, 00370 Predicate pred) 00371 { 00372 while (first != last) 00373 { 00374 if (pred(*first)) *result++ = *first; 00375 ++first; 00376 } 00377 return result; 00378 } 00379 00380 /** 00381 Helper to avoid using bind1st/bind2nd. 00382 */ 00383 template <typename ComparedType> 00384 struct equal_to 00385 { 00386 typedef ComparedType compared_type; 00387 explicit equal_to( const compared_type & d ) : m_data(d) 00388 {} 00389 00390 /** 00391 Returns true if p compares equal to the value 00392 passed to this object's ctor. 00393 */ 00394 void operator()( const compared_type & p ) 00395 { 00396 return p == this->m_data; 00397 } 00398 private: 00399 compared_type m_data; 00400 }; 00401 00402 /** 00403 Functor to return true if given NameableT objects match a 00404 certain name. NameableT must support: 00405 00406 std::string name() const; 00407 00408 This class is admitedly to avoid the use of bind1st/bind2nd 00409 :/. 00410 */ 00411 template <typename NameableT> 00412 struct same_name 00413 { 00414 // maintenance note: same_name<> functor is in the algos header 00415 // because that's where it's used, and i don't want this header 00416 // to depend on the functors header. 00417 // i really want this class in data_node_functor.h, 00418 // but that introduces other deps on that file which i don't want. 00419 typedef NameableT nameable_type; 00420 explicit same_name( const std::string & n ) : m_name(n) 00421 {} 00422 00423 bool operator()( const nameable_type * x ) const 00424 { 00425 if( ! x ) return false; 00426 return x->name() == this->m_name; 00427 } 00428 private: 00429 std::string m_name; 00430 }; 00431 00432 00433 } // namespace s11n 00434 00435 #endif // s11n_FUNCTOR_H_INCLUDED

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