RDCode: Query.h Source File

# Query.h

Go to the documentation of this file.

    00001 //
    00002 // Copyright (c) 2003-2006 Greg Landrum and Rational Discovery LLC
    00003 //
    00004 //   @@ All Rights Reserved  @@
    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   //! class to allow integer values to pick templates
    00021   template <int v>
    00022   class Int2Type
    00023   {
    00024     enum { value = v };
    00025   };
    00026
    00027   //! Base class for all queries
    00028   /*!
    00029     Query objects have one or two functions associated with them:
    00030       - <tt>bool matchFunc(MatchFuncArgType other)</tt> returns true or false
    00031         to indicate whether this query matches \c other.
    00032         This is mandatory.
    00033
    00034       - <tt>MatchFuncArgType dataFunc(DataFuncArgType other)</tt> converts
    00035         the argument \c other from \c DataFuncArgType to \c MatchFuncArgType.
    00036         This is optional if \c DataFuncArgType is the same as (or implicitly
    00037         convertible to) \c MatchFuncArgType.
    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     //! sets whether or not we are negated
    00054     void setNegation(bool what) { this->df_negate = what; };
    00055     //! returns whether or not we are negated
    00056     bool getNegation() const { return this->df_negate; };
    00057
    00058     //! sets our text description
    00059     void setDescription(std::string &descr) { this->d_description = descr; };
    00060     //! \overload
    00061     void setDescription(const char *descr) { this->d_description = std::string(descr); };
    00062     //! returns our text description
    00063     std::string getDescription() const { return this->d_description; };
    00064
    00065     //! sets our match function
    00066     void setMatchFunc(bool (*what)(MatchFuncArgType)) { this->d_matchFunc = what; };
    00067     //! returns our match function:
    00068     bool (*getMatchFunc() const)(MatchFuncArgType) { return this->d_matchFunc; };
    00069     //! sets our data function
    00070     void setDataFunc(MatchFuncArgType (*what)(DataFuncArgType)) { this->d_dataFunc = what; };
    00071     //! returns our data function:
    00072     MatchFuncArgType (*getDataFunc() const)(DataFuncArgType) { return this->d_dataFunc; };
    00073
    00074     //! adds a child to our list of children
    00075     void addChild(CHILD_TYPE child) { this->d_children.push_back(child); };
    00076     //! returns an iterator for the beginning of our child vector
    00077     CHILD_VECT_CI beginChildren() const { return this->d_children.begin(); }
    00078     //! returns an iterator for the end of our child vector
    00079     CHILD_VECT_CI endChildren() const { return this->d_children.end(); }
    00080
    00081     //! returns whether or not we match the argument
    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     //! returns a copy of this Query
    00093     /*!
    00094        <b>Notes:</b>
    00095          - the caller is responsible for <tt>delete</tt>ing the result
    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     //! \brief calls our \c dataFunc (if it's set) on \c what and returns
    00122     //! the result, otherwise returns \c what
    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     //! calls our \c dataFunc (which must be set) on \c what and returns the result
    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   // Used within query functions to compare values
    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