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