00001
00002
00003
00004
00005
00006 #ifndef __RD_QUERY_H__
00007 #define __RD_QUERY_H__
00008
00009 #ifdef _MSC_VER
00010 #pragma warning (disable: 4800) // warning: converting things to bool
00011 #endif
00012
00013 #include <vector>
00014 #include <string>
00015 #include <boost/smart_ptr.hpp>
00016 #include <RDGeneral/Invariant.h>
00017
00018 namespace Queries {
00019
00020
00021 template <int v>
00022 class Int2Type
00023 {
00024 enum { value = v };
00025 };
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 template <class MatchFuncArgType, class DataFuncArgType=MatchFuncArgType,
00041 bool needsConversion=false>
00042 class Query {
00043 public:
00044 typedef boost::shared_ptr< Query<MatchFuncArgType, DataFuncArgType, needsConversion> > CHILD_TYPE;
00045 typedef std::vector< CHILD_TYPE > CHILD_VECT;
00046 typedef typename CHILD_VECT::iterator CHILD_VECT_I;
00047 typedef typename CHILD_VECT::const_iterator CHILD_VECT_CI;
00048
00049 Query() : d_description(""),df_negate(false),d_matchFunc(NULL),d_dataFunc(NULL){};
00050 virtual ~Query() { this->d_children.clear(); };
00051
00052
00053
00054 void setNegation(bool what) { this->df_negate = what; };
00055
00056 bool getNegation() const { return this->df_negate; };
00057
00058
00059 void setDescription(std::string &descr) { this->d_description = descr; };
00060
00061 void setDescription(const char *descr) { this->d_description = std::string(descr); };
00062
00063 std::string getDescription() const { return this->d_description; };
00064
00065
00066 void setMatchFunc(bool (*what)(MatchFuncArgType)) { this->d_matchFunc = what; };
00067
00068 bool (*getMatchFunc() const)(MatchFuncArgType) { return this->d_matchFunc; };
00069
00070 void setDataFunc(MatchFuncArgType (*what)(DataFuncArgType)) { this->d_dataFunc = what; };
00071
00072 MatchFuncArgType (*getDataFunc() const)(DataFuncArgType) { return this->d_dataFunc; };
00073
00074
00075 void addChild(CHILD_TYPE child) { this->d_children.push_back(child); };
00076
00077 CHILD_VECT_CI beginChildren() const { return this->d_children.begin(); }
00078
00079 CHILD_VECT_CI endChildren() const { return this->d_children.end(); }
00080
00081
00082 virtual bool Match(const DataFuncArgType arg) const{
00083 MatchFuncArgType mfArg = TypeConvert(arg,Int2Type<needsConversion>());
00084 bool tRes;
00085 if(this->d_matchFunc) tRes = this->d_matchFunc(mfArg);
00086 else tRes = static_cast<bool>(mfArg);
00087
00088 if( this->getNegation() ) return !tRes;
00089 else return tRes;
00090 };
00091
00092
00093
00094
00095
00096
00097 virtual Query<MatchFuncArgType,DataFuncArgType,needsConversion> *
00098 copy( ) const {
00099 Query<MatchFuncArgType,DataFuncArgType,needsConversion> *res =
00100 new Query<MatchFuncArgType,DataFuncArgType,needsConversion>();
00101 typename Query<MatchFuncArgType,DataFuncArgType,needsConversion>::CHILD_VECT_CI iter;
00102 for(iter=this->beginChildren();
00103 iter!=this->endChildren();
00104 ++iter){
00105 res->addChild(*iter);
00106 }
00107 res->df_negate = this->df_negate;
00108 res->d_matchFunc = this->d_matchFunc;
00109 res->d_dataFunc = this->d_dataFunc;
00110 res->d_description = this->d_description;
00111 return res;
00112 };
00113
00114 protected :
00115 std::string d_description;
00116 CHILD_VECT d_children;
00117 bool df_negate;
00118 bool (*d_matchFunc) (MatchFuncArgType);
00119 MatchFuncArgType (*d_dataFunc)(DataFuncArgType);
00120
00121
00122
00123 MatchFuncArgType TypeConvert(MatchFuncArgType what,Int2Type<false> d) const{
00124 MatchFuncArgType mfArg;
00125 if( this->d_dataFunc != NULL ){
00126 mfArg = this->d_dataFunc(what);
00127 } else {
00128 mfArg = what;
00129 }
00130 return mfArg;
00131 }
00132
00133 MatchFuncArgType TypeConvert(DataFuncArgType what,Int2Type<true> d) const{
00134 PRECONDITION(this->d_dataFunc,"no data function");
00135 MatchFuncArgType mfArg;
00136 mfArg = this->d_dataFunc(what);
00137 return mfArg;
00138 }
00139
00140
00141 };
00142
00143
00144
00145
00146
00147
00148
00149 template <class T1, class T2>
00150 int queryCmp(const T1 v1, const T2 v2, const T1 tol) {
00151 T1 diff = v1 - v2;
00152 if( diff <= tol ){
00153 if( diff >= -tol ){
00154 return 0;
00155 } else {
00156 return -1;
00157 }
00158 } else {
00159 return 1;
00160 }
00161 };
00162
00163
00164 }
00165 #endif