00001 #ifndef wali_nwa_query_details_SELECTORS_HPP 00002 #define wali_nwa_query_details_SELECTORS_HPP 00003 00004 #include "opennwa/Nwa.hpp" 00005 00006 #include <utility> 00007 00008 namespace opennwa 00009 { 00010 namespace query 00011 { 00012 namespace details 00013 { 00014 /// This namepsace defines a library of selector classes. 00015 /// 00016 /// A selector class's purpose is to transform an NWA transition into 00017 /// whatever the user wants. For instance, if the user writes 00018 /// query().select_symbol(). ... 00019 /// then the 'selector' is what's responsible for pulling out the 00020 /// symbol field of each transition in order to fulfill that query. 00021 /// 00022 /// A selector is a functor that is callable on one or more 00023 /// transition types -- calls, internals, and returns -- and returns 00024 /// pretty much anything you want. For most things, you'll want it to 00025 /// be callable on all three types, which means you'll have to 00026 /// overload operator(). (This is why most of these must be classes 00027 /// instead of using function pointers.) Note however that because 00028 /// C/C++ doesn't have strong typedefs, Call and Internal transitions 00029 /// are the same type! This means that you must do the same thing in 00030 /// both cases. 00031 /// 00032 /// Right now there is also a 'type' field in each class that holds 00033 /// the type of whatever the user wants out, but really this should 00034 /// be reworked slightly to use traits. (That way the user can pass a 00035 /// function if they really want, with the caveat that you can't do 00036 /// the overload thing.) 00037 namespace selectors 00038 { 00039 /// This class selects the whole transition 00040 struct CallTransitionSelector 00041 { 00042 typedef Nwa::Call type; 00043 00044 Nwa::Call operator()(Nwa::Call const & c) const { 00045 return c; 00046 } 00047 }; 00048 00049 /// This class selects the whole transition 00050 struct InternalTransitionSelector 00051 { 00052 typedef Nwa::Internal type; 00053 00054 Nwa::Internal operator()(Nwa::Internal const & c) const { 00055 return c; 00056 } 00057 }; 00058 00059 00060 /// This class selects the whole transition 00061 struct ReturnTransitionSelector 00062 { 00063 typedef Nwa::Return type; 00064 00065 Nwa::Return operator()(Nwa::Return const & c) const { 00066 return c; 00067 } 00068 }; 00069 00070 00071 /// This class selects the source from transitions 00072 struct SourceSelector 00073 { 00074 /// The type of what it returns -- SourceSelectors select the 00075 /// source, so that's a state. 00076 typedef State type; 00077 00078 State operator()(Nwa::Call const & c) const { 00079 return c.first; 00080 } 00081 00082 //State operator()(Nwa::Internal const & i) const { 00083 // return i.first; 00084 //} 00085 00086 State operator()(Nwa::Return const & r) const { 00087 return r.first; 00088 } 00089 }; 00090 00091 00092 /// This class selects the symobl from transitions 00093 struct SymbolSelector 00094 { 00095 /// SymbolSelectors select the symbol, which is a Symbol 00096 typedef Symbol type; 00097 00098 State operator()(Nwa::Call const & c) const { 00099 return c.second; 00100 } 00101 00102 //State operator()(Nwa::Internal const & i) const { 00103 // return i.second; 00104 //} 00105 00106 State operator()(Nwa::Return const & r) const { 00107 return r.third; 00108 } 00109 }; 00110 00111 00112 /// This class selects the target from transitions 00113 struct TargetSelector 00114 { 00115 typedef State type; 00116 00117 State operator()(Nwa::Call const & c) const { 00118 return c.third; 00119 } 00120 00121 //State operator()(Nwa::Internal const & i) const { 00122 // return i.third; 00123 //} 00124 00125 State operator()(Nwa::Return const & r) const { 00126 return r.fourth; 00127 } 00128 }; 00129 00130 00131 /// This class selects the call predecessor from return transitions 00132 struct CallPredecessorSelector 00133 { 00134 typedef State type; 00135 00136 State operator()(Nwa::Return const & r) const { 00137 return r.second; 00138 } 00139 }; 00140 00141 00142 /// This selects a pair of things 00143 template<typename Selector1, typename Selector2> 00144 struct PairSelector 00145 { 00146 // The types that the two selectors select 00147 typedef typename Selector1::type T1; 00148 typedef typename Selector2::type T2; 00149 00150 // The type *this* selector selects 00151 typedef std::pair<T1, T2> type; 00152 00153 type operator()(Nwa::Call const & c) const { 00154 return type(Selector1()(c), 00155 Selector2()(c)); 00156 } 00157 00158 //type operator()(Nwa::Internal const & c) const { 00159 // return type(Selector1()(c), 00160 // Selector2()(c)); 00161 //} 00162 00163 type operator()(Nwa::Return const & c) const { 00164 return type(Selector1()(c), 00165 Selector2()(c)); 00166 } 00167 }; 00168 00169 00170 00171 } 00172 } 00173 } 00174 } 00175 00176 // Yo, Emacs! 00177 // Local Variables: 00178 // c-file-style: "ellemtel" 00179 // c-basic-offset: 2 00180 // End: 00181 00182 #endif