00001 #ifndef IOKERNEL__VISITORMAP_H 00002 #define IOKERNEL__VISITORMAP_H 00003 00004 #include "iokernel/object.h" 00005 #include "iokernel/iokernel_forwarders.h" 00006 00052 typedef void ( * VisitMethod )( Address state, Object * object ); 00053 00054 00061 class VisitorEntry { 00062 public: 00063 Address stateAddress; 00064 VisitMethod visitMethod; 00065 public: 00066 VisitorEntry(Address address, VisitMethod method) : 00067 stateAddress(address), visitMethod(method) {} 00068 VisitorEntry() : 00069 stateAddress(0), visitMethod(0) {} 00070 VisitorEntry(const VisitorEntry &other) : 00071 stateAddress(other.stateAddress), visitMethod(other.visitMethod) {} 00072 VisitorEntry& operator=(const VisitorEntry &other) { 00073 stateAddress = other.stateAddress; 00074 visitMethod = other.visitMethod; 00075 return(*this); 00076 } 00077 bool operator==(const VisitorEntry &other) { 00078 return ((visitMethod == other.visitMethod) && 00079 (stateAddress == other.stateAddress)); 00080 } 00081 bool operator!=(const VisitorEntry &other) { 00082 return ((visitMethod != other.visitMethod) || 00083 (stateAddress != other.stateAddress)); 00084 } 00085 }; 00086 00087 /* 00088 * \par VisitorMap example 00089 * To use this visitor map: 00090 * 00091 * \code 00092 * // Write your visitor state class 00093 * 00094 * class MyVisitorInfo { 00095 * static void do_static_procedure_definition( MyVisitorInfo *info, 00096 * ProcedureDefinition *obj ) { 00097 * info->do_procedure_definition(obj); 00098 * } 00099 * void do_procedure_definition(ProcedureDefinition *proc_def) { 00100 * ...do_something... 00101 * } 00102 * } 00103 * \endcode 00104 * \code 00105 * // register the visitor functions 00106 * VisitorMap *map = new VisitorMap(suif_env); 00107 * MyVisitorClass my_info; 00108 * map->registerVisitMethod( &myinfo, 00109 * &MyVisitorClass::do_procedure_definition, 00110 * ProcedureDefinition::get_class_name() ); 00111 * \endcode 00112 * \code 00113 * // Pick an object: 00114 * // SuifObject *so; 00115 * map->apply(so); 00116 * \endcode 00117 * 00118 */ 00119 00120 template <class T> class CascadingMap; 00121 00122 class VisitorMap { 00123 public: 00124 VisitorMap( SuifEnv* suif ); 00125 ~VisitorMap(); 00126 00127 void register_visit_method( Address state, 00128 VisitMethod visitMethod, 00129 const LString &className ); 00130 00131 void register_unknown_method( Address state, 00132 VisitMethod visitMethod ); 00133 00134 void apply( Object* object ); 00135 00136 // more low level 00137 void apply( Object* object, const MetaClass* metaClass ); 00138 void register_visit_method( Address state, 00139 VisitMethod visitMethod, 00140 MetaClass* mc ); 00141 00142 private: 00143 CascadingMap<VisitorEntry> *map; 00144 Address unknownState; 00145 VisitMethod unknownMethod; 00146 private: 00147 VisitorMap(const VisitorMap &other); 00148 VisitorMap& operator=(const VisitorMap &other); 00149 }; 00150 00151 #endif