PLearn 0.1
ObjectGraphIterator.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // ObjectGraphIterator.h
00004 //
00005 // Copyright (C) 2005 Nicolas Chapados 
00006 // 
00007 // Redistribution and use in source and binary forms, with or without
00008 // modification, are permitted provided that the following conditions are met:
00009 // 
00010 //  1. Redistributions of source code must retain the above copyright
00011 //     notice, this list of conditions and the following disclaimer.
00012 // 
00013 //  2. Redistributions in binary form must reproduce the above copyright
00014 //     notice, this list of conditions and the following disclaimer in the
00015 //     documentation and/or other materials provided with the distribution.
00016 // 
00017 //  3. The name of the authors may not be used to endorse or promote
00018 //     products derived from this software without specific prior written
00019 //     permission.
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031 // 
00032 // This file is part of the PLearn library. For more information on the PLearn
00033 // library, go to the PLearn Web site at www.plearn.org
00034 
00035 /* *******************************************************      
00036    * $Id: .pyskeleton_header 544 2003-09-01 00:05:31Z plearner $ 
00037    ******************************************************* */
00038 
00039 // Authors: Nicolas Chapados
00040 
00044 #ifndef ObjectGraphIterator_INC
00045 #define ObjectGraphIterator_INC
00046 
00047 // From C++ stdlib
00048 #include <string>
00049 #include <vector>
00050 #include <utility>
00051 
00052 // From boost
00053 #include <boost/call_traits.hpp>
00054 
00055 // From PLearn
00056 #include <plearn/base/OptionBase.h>
00057 
00058 
00059 namespace PLearn {
00060 
00061 // Forward-declare
00062 class Object;
00063 
00064 
00065 //######################  CLASS  OBJECTOPTIONSITERATOR  #######################
00066 
00078 class ObjectOptionsIterator
00079 {
00080 public:
00082     ObjectOptionsIterator();
00083 
00098     ObjectOptionsIterator(const Object* root,
00099                           bool ignore_nontraversable = false,
00100                           bool skip_nulls = true);
00101 
00102     // Default assignment, copy constructor, destructor
00103 
00105     bool operator==(const ObjectOptionsIterator& rhs) const;
00106 
00108     bool operator!=(const ObjectOptionsIterator& rhs) const
00109     {
00110         return ! (*this == rhs);
00111     }
00112 
00115     const Object* operator*() const;
00116 
00125     string getCurrentOptionName() const;
00126 
00131     OptionBase::flag_t getCurrentOptionFlags() const;
00132     
00133     // Go to next object or "invalid" state if end of iteration
00134     const ObjectOptionsIterator& operator++();
00135 
00138     ObjectOptionsIterator operator++(int)
00139     {
00140         ObjectOptionsIterator old(*this);
00141         ++(*this);
00142         return old;
00143     }
00144 
00145 protected:
00146     bool m_invalid;                          
00147     bool m_ignore_nontraversable;            
00148     bool m_skip_nulls;                       
00149     const Object* m_object;                  
00150     const OptionList* m_options;             
00151     int m_cur_option;                        
00152     int m_cur_index;                         
00153 
00154     int m_max_index;                         
00155 
00156 };
00157 
00158 
00159 //#######################  CLASS  OBJECTGRAPHITERATOR  ########################
00160 
00184 class ObjectGraphIterator
00185 {
00186 public:
00192     enum TraversalType {
00193         BreadthOrder          = 1,
00194         DepthPreOrder         = 2,
00195         ReversedBreadthOrder  = 64 | 1,
00196         ReversedDepthPreOrder = 64 | 2
00197     };
00198 
00201     static const int Reversed = 64;
00202 
00209     static const int IgnoreNonTraversable = 128;
00210 
00211 
00212 public:
00214     ObjectGraphIterator();
00215     
00229     ObjectGraphIterator(const Object* root, TraversalType tt = DepthPreOrder,
00230                         bool compute_optnames = false,
00231                         const std::string& base_class_filter = "");
00232     
00233     // Default assignment, copy constructor, destructor
00234 
00236     bool invalid() const
00237     {
00238         return m_it == m_end;
00239     }
00240     
00242     bool operator==(const ObjectGraphIterator& rhs) const;
00243 
00245     bool operator!=(const ObjectGraphIterator& rhs) const
00246     {
00247         return ! (*this == rhs);
00248     }
00249 
00252     const Object* operator*() const
00253     {
00254         PLASSERT( !invalid() );
00255         return m_it->first;
00256     }
00257 
00262     const string& getCurrentOptionName() const
00263     {
00264         PLASSERT( !invalid() );
00265         return m_it->second;
00266     }
00267     
00269     const ObjectGraphIterator& operator++();
00270 
00273     ObjectGraphIterator operator++(int)
00274     {
00275         ObjectGraphIterator old(*this);
00276         ++(*this);
00277         return old;
00278     }
00279 
00280 protected:
00283     void buildTraversalGraph(const Object* root, TraversalType tt,
00284                              bool compute_optnames);
00285 
00286 protected:
00287     typedef pair<const Object*, string> ObjectAndName;
00288     typedef std::vector<ObjectAndName> ObjectList;
00289     typedef bool (*ISA)(const Object*);
00290     
00291     ObjectList m_object_list;                
00292     ObjectList::iterator m_it;               
00293     ObjectList::iterator m_end;              
00294     ISA m_isa_tester;                        
00295 };
00296 
00297 
00298 //#####  Broadcast  ###########################################################
00299 
00317 // Zero argument, const
00318 template <class T, class U>
00319 void memfun_broadcast(const Object* o, U (T::*func)() const,
00320                       ObjectGraphIterator::TraversalType tt = ObjectGraphIterator::DepthPreOrder)
00321 {
00322     ObjectGraphIterator grit(o, tt, false, T::_classname_()), grend;
00323     for ( ; grit != grend ; ++grit)
00324         if (const T* t = dynamic_cast<const T*>(*grit))
00325             (t->*func)();
00326 }
00327 
00328 
00329 // Zero argument, non-const
00330 template <class T, class U>
00331 void memfun_broadcast(Object* o, U (T::*func)(),
00332                       ObjectGraphIterator::TraversalType tt = ObjectGraphIterator::DepthPreOrder)
00333 {
00334     ObjectGraphIterator grit(o, tt, false, T::_classname_()), grend;
00335     for ( ; grit != grend ; ++grit)
00336         if (T* t = const_cast<T*>(dynamic_cast<const T*>(*grit)))
00337             (t->*func)();
00338 }
00339 
00340 
00341 // One argument, const
00342 template <class T, class U, class V>
00343 void memfun_broadcast(const Object* o, U (T::*func)(V) const,
00344                       typename boost::call_traits<V>::param_type arg1,
00345                       ObjectGraphIterator::TraversalType tt = ObjectGraphIterator::DepthPreOrder)
00346 {
00347     ObjectGraphIterator grit(o, tt, false, T::_classname_()), grend;
00348     for ( ; grit != grend ; ++grit)
00349         if (const T* t = dynamic_cast<const T*>(*grit))
00350             (t->*func)(arg1);
00351 }
00352 
00353 
00354 // One argument, non-const
00355 template <class T, class U, class V>
00356 void memfun_broadcast(Object* o, U (T::*func)(V),
00357                       typename boost::call_traits<V>::param_type arg1,
00358                       ObjectGraphIterator::TraversalType tt = ObjectGraphIterator::DepthPreOrder)
00359 {
00360     ObjectGraphIterator grit(o, tt, false, T::_classname_()), grend;
00361     for ( ; grit != grend ; ++grit)
00362         if (T* t = const_cast<T*>(dynamic_cast<const T*>(*grit)))
00363             (t->*func)(arg1);
00364 }
00365 
00366 
00367 // Two arguments, const
00368 template <class T, class U, class V, class W>
00369 void memfun_broadcast(const Object* o, U (T::*func)(V,W) const,
00370                       typename boost::call_traits<V>::param_type arg1,
00371                       typename boost::call_traits<W>::param_type arg2,
00372                       ObjectGraphIterator::TraversalType tt = ObjectGraphIterator::DepthPreOrder)
00373 {
00374     ObjectGraphIterator grit(o, tt, false, T::_classname_()), grend;
00375     for ( ; grit != grend ; ++grit)
00376         if (const T* t = dynamic_cast<const T*>(*grit))
00377             (t->*func)(arg1,arg2);
00378 }
00379 
00380 
00381 // Two arguments, non-const
00382 template <class T, class U, class V, class W>
00383 void memfun_broadcast(Object* o, U (T::*func)(V,W),
00384                       typename boost::call_traits<V>::param_type arg1,
00385                       typename boost::call_traits<W>::param_type arg2,
00386                       ObjectGraphIterator::TraversalType tt = ObjectGraphIterator::DepthPreOrder)
00387 {
00388     ObjectGraphIterator grit(o, tt, false, T::_classname_()), grend;
00389     for ( ; grit != grend ; ++grit)
00390         if (T* t = const_cast<T*>(dynamic_cast<const T*>(*grit)))
00391             (t->*func)(arg1,arg2);
00392 }
00393 
00394 
00395 // Three arguments, const
00396 template <class T, class U, class V, class W, class X>
00397 void memfun_broadcast(const Object* o, U (T::*func)(V,W,X) const,
00398                       typename boost::call_traits<V>::param_type arg1,
00399                       typename boost::call_traits<W>::param_type arg2,
00400                       typename boost::call_traits<X>::param_type arg3,
00401                       ObjectGraphIterator::TraversalType tt = ObjectGraphIterator::DepthPreOrder)
00402 {
00403     ObjectGraphIterator grit(o, tt, false, T::_classname_()), grend;
00404     for ( ; grit != grend ; ++grit)
00405         if (const T* t = dynamic_cast<const T*>(*grit))
00406             (t->*func)(arg1,arg2,arg3);
00407 }
00408 
00409 
00410 // Three arguments, non-const
00411 template <class T, class U, class V, class W, class X>
00412 void memfun_broadcast(Object* o, U (T::*func)(V,W,X),
00413                       typename boost::call_traits<V>::param_type arg1,
00414                       typename boost::call_traits<W>::param_type arg2,
00415                       typename boost::call_traits<X>::param_type arg3,
00416                       ObjectGraphIterator::TraversalType tt = ObjectGraphIterator::DepthPreOrder)
00417 {
00418     ObjectGraphIterator grit(o, tt, false, T::_classname_()), grend;
00419     for ( ; grit != grend ; ++grit)
00420         if (T* t = const_cast<T*>(dynamic_cast<const T*>(*grit)))
00421             (t->*func)(arg1,arg2,arg3);
00422 }
00423 
00424 
00447 // Zero argument, const
00448 template <class T, class U, class V>
00449 void memfun_broadcast_optname(const Object* o, U (T::*func)(V) const,
00450                               ObjectGraphIterator::TraversalType tt =
00451                               ObjectGraphIterator::DepthPreOrder)
00452 {
00453     ObjectGraphIterator grit(o, tt, true, T::_classname_()), grend;
00454     for ( ; grit != grend ; ++grit)
00455         if (const T* t = dynamic_cast<const T*>(*grit))
00456             (t->*func)(grit.getCurrentOptionName());
00457 }
00458 
00459 
00460 // Zero argument, non-const
00461 template <class T, class U, class V>
00462 void memfun_broadcast_optname(Object* o, U (T::*func)(V),
00463                               ObjectGraphIterator::TraversalType tt =
00464                               ObjectGraphIterator::DepthPreOrder)
00465 {
00466     ObjectGraphIterator grit(o, tt, true, T::_classname_()), grend;
00467     for ( ; grit != grend ; ++grit)
00468         if (T* t = const_cast<T*>(dynamic_cast<const T*>(*grit)))
00469             (t->*func)(grit.getCurrentOptionName());
00470 }
00471 
00472 
00473 // One argument, const
00474 template <class T, class U, class V, class W>
00475 void memfun_broadcast_optname(const Object* o, U (T::*func)(V,W) const,
00476                               typename boost::call_traits<V>::param_type arg1,
00477                               ObjectGraphIterator::TraversalType tt =
00478                               ObjectGraphIterator::DepthPreOrder)
00479 {
00480     ObjectGraphIterator grit(o, tt, true, T::_classname_()), grend;
00481     for ( ; grit != grend ; ++grit)
00482         if (const T* t = dynamic_cast<const T*>(*grit))
00483             (t->*func)(grit.getCurrentOptionName(), arg1);
00484 }
00485 
00486 
00487 // One argument, non-const
00488 template <class T, class U, class V, class W>
00489 void memfun_broadcast_optname(Object* o, U (T::*func)(V,W),
00490                               typename boost::call_traits<V>::param_type arg1,
00491                               ObjectGraphIterator::TraversalType tt =
00492                               ObjectGraphIterator::DepthPreOrder)
00493 {
00494     ObjectGraphIterator grit(o, tt, true, T::_classname_()), grend;
00495     for ( ; grit != grend ; ++grit)
00496         if (T* t = const_cast<T*>(dynamic_cast<const T*>(*grit)))
00497             (t->*func)(grit.getCurrentOptionName(), arg1);
00498 }
00499 
00500 
00501 // Two arguments, const
00502 template <class T, class U, class V, class W, class X>
00503 void memfun_broadcast_optname(const Object* o, U (T::*func)(V,W,X) const,
00504                               typename boost::call_traits<V>::param_type arg1,
00505                               typename boost::call_traits<W>::param_type arg2,
00506                               ObjectGraphIterator::TraversalType tt =
00507                               ObjectGraphIterator::DepthPreOrder)
00508 {
00509     ObjectGraphIterator grit(o, tt, true, T::_classname_()), grend;
00510     for ( ; grit != grend ; ++grit)
00511         if (const T* t = dynamic_cast<const T*>(*grit))
00512             (t->*func)(grit.getCurrentOptionName(), arg1, arg2);
00513 }
00514 
00515 
00516 // Two arguments, non-const
00517 template <class T, class U, class V, class W, class X>
00518 void memfun_broadcast_optname(Object* o, U (T::*func)(V,W,X),
00519                               typename boost::call_traits<V>::param_type arg1,
00520                               typename boost::call_traits<W>::param_type arg2,
00521                               ObjectGraphIterator::TraversalType tt =
00522                               ObjectGraphIterator::DepthPreOrder)
00523 {
00524     ObjectGraphIterator grit(o, tt, true, T::_classname_()), grend;
00525     for ( ; grit != grend ; ++grit)
00526         if (T* t = const_cast<T*>(dynamic_cast<const T*>(*grit)))
00527             (t->*func)(grit.getCurrentOptionName(), arg1, arg2);
00528 }
00529 
00530 
00543 void setoption_broadcast(const Object* o, const string& class_name,
00544                          const string& option_name, const string& option_value,
00545                          ObjectGraphIterator::TraversalType tt =
00546                          ObjectGraphIterator::DepthPreOrder);
00547 
00548 } // end of namespace PLearn
00549 
00550 #endif
00551 
00552 
00553 /*
00554   Local Variables:
00555   mode:c++
00556   c-basic-offset:4
00557   c-file-style:"stroustrup"
00558   c-file-offsets:((innamespace . 0)(inline-open . 0))
00559   indent-tabs-mode:nil
00560   fill-column:79
00561   End:
00562 */
00563 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines