RDKit
Open-source cheminformatics and machine learning.
Query.h
Go to the documentation of this file.
1 //
2 // Copyright (c) 2003-2006 Greg Landrum and Rational Discovery LLC
3 //
4 // @@ All Rights Reserved @@
5 // This file is part of the RDKit.
6 // The contents are covered by the terms of the BSD license
7 // which is included in the file license.txt, found at the root
8 // of the RDKit source tree.
9 //
10 #ifndef __RD_QUERY_H__
11 #define __RD_QUERY_H__
12 
13 #ifdef _MSC_VER
14 #pragma warning(disable : 4800) // warning: converting things to bool
15 #endif
16 
17 #include <vector>
18 #include <string>
19 #include <boost/smart_ptr.hpp>
20 #include <RDGeneral/Invariant.h>
21 
22 namespace Queries {
23 
24 //! class to allow integer values to pick templates
25 template <int v>
26 class Int2Type {
27  enum { value = v };
28 };
29 
30 //! Base class for all queries
31 /*!
32  Query objects have one or two functions associated with them:
33  - <tt>bool matchFunc(MatchFuncArgType other)</tt> returns true or false
34  to indicate whether this query matches \c other.
35  This is mandatory.
36 
37  - <tt>MatchFuncArgType dataFunc(DataFuncArgType other)</tt> converts
38  the argument \c other from \c DataFuncArgType to \c MatchFuncArgType.
39  This is optional if \c DataFuncArgType is the same as (or implicitly
40  convertible to) \c MatchFuncArgType.
41 
42 */
43 template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
44  bool needsConversion = false>
45 class Query {
46  public:
47  typedef boost::shared_ptr<
49  typedef std::vector<CHILD_TYPE> CHILD_VECT;
50  typedef typename CHILD_VECT::iterator CHILD_VECT_I;
51  typedef typename CHILD_VECT::const_iterator CHILD_VECT_CI;
52 
54  : d_description(""),
55  df_negate(false),
56  d_matchFunc(NULL),
57  d_dataFunc(NULL){};
58  virtual ~Query() { this->d_children.clear(); };
59 
60  //! sets whether or not we are negated
61  void setNegation(bool what) { this->df_negate = what; };
62  //! returns whether or not we are negated
63  bool getNegation() const { return this->df_negate; };
64 
65  //! sets our text description
66  void setDescription(const std::string &descr) {
67  this->d_description = descr;
68  };
69  //! \overload
70  void setDescription(const char *descr) {
71  this->d_description = std::string(descr);
72  };
73  //! returns our text description
74  const std::string &getDescription() const { return this->d_description; };
75  //! returns a fuller text description
76  virtual std::string getFullDescription() const {
77  if (!getNegation())
78  return getDescription();
79  else
80  return "not " + getDescription();
81  }
82 
83  //! sets our match function
84  void setMatchFunc(bool (*what)(MatchFuncArgType)) {
85  this->d_matchFunc = what;
86  };
87  //! returns our match function:
88  bool (*getMatchFunc() const)(MatchFuncArgType) { return this->d_matchFunc; };
89  //! sets our data function
90  void setDataFunc(MatchFuncArgType (*what)(DataFuncArgType)) {
91  this->d_dataFunc = what;
92  };
93  //! returns our data function:
94  MatchFuncArgType (*getDataFunc() const)(DataFuncArgType) {
95  return this->d_dataFunc;
96  };
97 
98  //! adds a child to our list of children
99  void addChild(CHILD_TYPE child) { this->d_children.push_back(child); };
100  //! returns an iterator for the beginning of our child vector
101  CHILD_VECT_CI beginChildren() const { return this->d_children.begin(); }
102  //! returns an iterator for the end of our child vector
103  CHILD_VECT_CI endChildren() const { return this->d_children.end(); }
104 
105  //! returns whether or not we match the argument
106  virtual bool Match(const DataFuncArgType arg) const {
107  MatchFuncArgType mfArg = TypeConvert(arg, Int2Type<needsConversion>());
108  bool tRes;
109  if (this->d_matchFunc)
110  tRes = this->d_matchFunc(mfArg);
111  else
112  tRes = static_cast<bool>(mfArg);
113 
114  if (this->getNegation())
115  return !tRes;
116  else
117  return tRes;
118  };
119 
120  //! returns a copy of this Query
121  /*!
122  <b>Notes:</b>
123  - the caller is responsible for <tt>delete</tt>ing the result
124  */
126  const {
129  typename Query<MatchFuncArgType, DataFuncArgType,
130  needsConversion>::CHILD_VECT_CI iter;
131  for (iter = this->beginChildren(); iter != this->endChildren(); ++iter) {
132  res->addChild(CHILD_TYPE(iter->get()->copy()));
133  }
134  res->df_negate = this->df_negate;
135  res->d_matchFunc = this->d_matchFunc;
136  res->d_dataFunc = this->d_dataFunc;
137  res->d_description = this->d_description;
138  return res;
139  };
140 
141  protected:
142  std::string d_description;
143  CHILD_VECT d_children;
144  bool df_negate;
145  bool (*d_matchFunc)(MatchFuncArgType);
146  MatchFuncArgType (*d_dataFunc)(DataFuncArgType);
147 
148  //! \brief calls our \c dataFunc (if it's set) on \c what and returns
149  //! the result, otherwise returns \c what
150  MatchFuncArgType TypeConvert(MatchFuncArgType what,
151  Int2Type<false> /*d*/) const {
152  MatchFuncArgType mfArg;
153  if (this->d_dataFunc != NULL) {
154  mfArg = this->d_dataFunc(what);
155  } else {
156  mfArg = what;
157  }
158  return mfArg;
159  }
160  //! calls our \c dataFunc (which must be set) on \c what and returns the
161  //result
162  MatchFuncArgType TypeConvert(DataFuncArgType what,
163  Int2Type<true> /*d*/) const {
164  PRECONDITION(this->d_dataFunc, "no data function");
165  MatchFuncArgType mfArg;
166  mfArg = this->d_dataFunc(what);
167  return mfArg;
168  }
169 };
170 
171 //----------------------------
172 //
173 // Used within query functions to compare values
174 //
175 //----------------------------
176 template <class T1, class T2>
177 int queryCmp(const T1 v1, const T2 v2, const T1 tol) {
178  T1 diff = v1 - v2;
179  if (diff <= tol) {
180  if (diff >= -tol) {
181  return 0;
182  } else {
183  return -1;
184  }
185  } else {
186  return 1;
187  }
188 };
189 }
190 #endif
bool getNegation() const
returns whether or not we are negated
Definition: Query.h:63
int queryCmp(const T1 v1, const T2 v2, const T1 tol)
Definition: Query.h:177
CHILD_VECT_CI beginChildren() const
returns an iterator for the beginning of our child vector
Definition: Query.h:101
const std::string & getDescription() const
returns our text description
Definition: Query.h:74
void setNegation(bool what)
sets whether or not we are negated
Definition: Query.h:61
CHILD_VECT_CI endChildren() const
returns an iterator for the end of our child vector
Definition: Query.h:103
boost::shared_ptr< Query< MatchFuncArgType, DataFuncArgType, needsConversion > > CHILD_TYPE
Definition: Query.h:48
MatchFuncArgType TypeConvert(MatchFuncArgType what, Int2Type< false >) const
calls our dataFunc (if it&#39;s set) on what and returns the result, otherwise returns what ...
Definition: Query.h:150
CHILD_VECT::iterator CHILD_VECT_I
Definition: Query.h:50
MatchFuncArgType(*)(DataFuncArgType) getDataFunc() const
returns our data function:
Definition: Query.h:94
void setMatchFunc(bool(*what)(MatchFuncArgType))
sets our match function
Definition: Query.h:84
virtual bool Match(const DataFuncArgType arg) const
returns whether or not we match the argument
Definition: Query.h:106
bool(* d_matchFunc)(MatchFuncArgType)
Definition: Query.h:145
std::vector< CHILD_TYPE > CHILD_VECT
Definition: Query.h:49
class to allow integer values to pick templates
Definition: Query.h:26
CHILD_VECT d_children
Definition: Query.h:143
void setDescription(const char *descr)
Definition: Query.h:70
void addChild(CHILD_TYPE child)
adds a child to our list of children
Definition: Query.h:99
MatchFuncArgType(* d_dataFunc)(DataFuncArgType)
Definition: Query.h:146
bool df_negate
Definition: Query.h:144
virtual ~Query()
Definition: Query.h:58
bool(*)(MatchFuncArgType) getMatchFunc() const
returns our match function:
Definition: Query.h:88
void setDataFunc(MatchFuncArgType(*what)(DataFuncArgType))
sets our data function
Definition: Query.h:90
CHILD_VECT::const_iterator CHILD_VECT_CI
Definition: Query.h:51
#define PRECONDITION(expr, mess)
Definition: Invariant.h:107
virtual std::string getFullDescription() const
returns a fuller text description
Definition: Query.h:76
std::string d_description
Definition: Query.h:139
MatchFuncArgType TypeConvert(DataFuncArgType what, Int2Type< true >) const
calls our dataFunc (which must be set) on what and returns the
Definition: Query.h:162
Base class for all queries.
Definition: Query.h:45
void setDescription(const std::string &descr)
sets our text description
Definition: Query.h:66
virtual Query< MatchFuncArgType, DataFuncArgType, needsConversion > * copy() const
returns a copy of this Query
Definition: Query.h:125