Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | 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 Thu Jun 16 16:18:12 2005 for s11n by  doxygen 1.4.3-20050530