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