00001 // Torc - Copyright 2011 University of Southern California. All Rights Reserved. 00002 // $HeadURL: https://torc-isi.svn.sourceforge.net/svnroot/torc-isi/branches/staging/0.9/src/torc/generic/om/VisitorType.hpp $ 00003 // $Id: VisitorType.hpp 10 2011-10-12 18:40:16Z nsteiner $ 00004 00005 // This program is free software: you can redistribute it and/or modify it under the terms of the 00006 // GNU General Public License as published by the Free Software Foundation, either version 3 of the 00007 // License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 00010 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 00011 // the GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License along with this program. If 00014 // not, see <http://www.gnu.org/licenses/>. 00015 00016 #ifndef TORC_GENERIC_OM_VISITORTYPE_HPP 00017 #define TORC_GENERIC_OM_VISITORTYPE_HPP 00018 00019 #include "torc/generic/util/Error.hpp" 00020 00021 namespace torc { 00022 00023 namespace generic { 00024 00025 /** 00026 * @brief A base class for Visitor 00027 * 00028 * This is the base class for Visitor template. This class is used to provide a concrete handle of a inoutVisitor to a visitable class. This class therefore does not contain any methods other than a (protected) constructor and a destructor. 00029 */ 00030 class BaseVisitor 00031 { 00032 protected: 00033 BaseVisitor(); 00034 00035 public: 00036 virtual 00037 ~BaseVisitor() throw(); 00038 00039 private: 00040 BaseVisitor( const BaseVisitor &); 00041 BaseVisitor & 00042 operator =( const BaseVisitor &); 00043 }; 00044 00045 /** 00046 * @brief An acyclic inoutVisitor implementation 00047 * 00048 * The VisitorType template acts as a template that can be derived by clients to add extrinsic virtual functions on class hierarchies. This is useful in situations where the user does not have direct handle to a derived class, but has a pointer/reference to a base class. This class defines a polymorphic method visit() that can be used to get a handle to the actual derived object and can therefore be programmed to perform arbitrary operations on it using public methods specific to the derived class object. For more information on the Visitor deisgn pattern see: http://en.wikipedia.org/wiki/Visitor_pattern 00049 * The inoutVisitor implementation in EOM follows the acyclic inoutVisitor implementation detiled in Andrei Alexandrescu's <i>Modern C++ Design</i>. 00050 */ 00051 template<typename _Tp> 00052 class VisitorType : virtual public BaseVisitor 00053 { 00054 protected: 00055 explicit VisitorType() throw(); 00056 00057 00058 public: 00059 virtual ~VisitorType() throw(); 00060 00061 /** 00062 * Visit the target object. This will typically be a derived leaf type. 00063 * 00064 * @param[in,out] client A reference to the target object 00065 * @exception Error Exception generated by any of the functions called from inside visit() 00066 */ 00067 virtual void visit(_Tp & client) throw(Error) = 0; 00068 00069 00070 }; 00071 template<typename _Tp> 00072 VisitorType<_Tp>::VisitorType() throw() { 00073 } 00074 00075 template<typename _Tp> 00076 VisitorType<_Tp>::~VisitorType() throw() { 00077 } 00078 00079 template<typename _Tp> 00080 void runVisitor(_Tp &inoutVisited, 00081 BaseVisitor &inoutVisitor) throw(Error) 00082 { 00083 typedef VisitorType<_Tp> ConcreteVisitor; 00084 00085 if( ConcreteVisitor *p 00086 = dynamic_cast<ConcreteVisitor *>(&inoutVisitor) ) 00087 { 00088 try 00089 { 00090 p->visit( inoutVisited ); 00091 } 00092 catch( Error &e ) 00093 { 00094 e.setCurrentLocation( 00095 __FUNCTION__, __FILE__, __LINE__ ); 00096 throw; 00097 } 00098 return; 00099 } 00100 //TBD::Error?Fallback? 00101 return; 00102 } 00103 00104 } // namespace torc::generic 00105 00106 } // namespace torc 00107 #endif // TORC_GENERIC_OM_VISITORTYPE_HPP