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;
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
Queries::Query::setMatchFunc
void setMatchFunc(bool(*what)(MatchFuncArgType))
sets our match function
Definition: Query.h:86
Queries::Query::CHILD_VECT_CI
CHILD_VECT::const_iterator CHILD_VECT_CI
Definition: Query.h:53
Queries::Query::df_negate
bool df_negate
Definition: Query.h:149
Queries::Query::copy
virtual Query< MatchFuncArgType, DataFuncArgType, needsConversion > * copy() const
returns a copy of this Query
Definition: Query.h:127
Queries::Query::Match
virtual bool Match(const DataFuncArgType arg) const
returns whether or not we match the argument
Definition: Query.h:108
Queries::Query::setNegation
void setNegation(bool what)
sets whether or not we are negated
Definition: Query.h:63
Queries::queryCmp
int queryCmp(const T1 v1, const T2 v2, const T1 tol)
Definition: Query.h:191
Queries::Query::d_children
CHILD_VECT d_children
Definition: Query.h:148
Queries::Query::d_val
MatchFuncArgType d_val
Definition: Query.h:145
Queries::Query::d_dataFunc
MatchFuncArgType(* d_dataFunc)(DataFuncArgType)
Definition: Query.h:158
Queries::Query::CHILD_TYPE
boost::shared_ptr< Query< MatchFuncArgType, DataFuncArgType, needsConversion > > CHILD_TYPE
Definition: Query.h:50
Queries::Query::TypeConvert
MatchFuncArgType TypeConvert(DataFuncArgType what, Int2Type< true >) const
calls our dataFunc (which must be set) on what and returns the
Definition: Query.h:176
Queries::Query::getDataFunc
MatchFuncArgType(*)(DataFuncArgType) getDataFunc() const
returns our data function:
Definition: Query.h:96
Queries
Definition: AndQuery.h:16
Queries::Query::d_matchFunc
bool(* d_matchFunc)(MatchFuncArgType)
Definition: Query.h:150
Queries::Query::getMatchFunc
bool(*)(MatchFuncArgType) getMatchFunc() const
returns our match function:
Definition: Query.h:90
Queries::Query::setDescription
void setDescription(const char *descr)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: Query.h:72
Invariant.h
Queries::Query::d_description
std::string d_description
Definition: Query.h:147
Queries::Query::~Query
virtual ~Query()
Definition: Query.h:60
Queries::Query::setDataFunc
void setDataFunc(MatchFuncArgType(*what)(DataFuncArgType))
sets our data function
Definition: Query.h:92
Queries::Query::addChild
void addChild(CHILD_TYPE child)
adds a child to our list of children
Definition: Query.h:101
Queries::Query::getNegation
bool getNegation() const
returns whether or not we are negated
Definition: Query.h:65
Queries::Int2Type
class to allow integer values to pick templates
Definition: Query.h:27
Queries::Query::endChildren
CHILD_VECT_CI endChildren() const
returns an iterator for the end of our child vector
Definition: Query.h:105
Queries::Query::getFullDescription
virtual std::string getFullDescription() const
returns a fuller text description
Definition: Query.h:78
Queries::Query::beginChildren
CHILD_VECT_CI beginChildren() const
returns an iterator for the beginning of our child vector
Definition: Query.h:103
Queries::Query::Query
Query()
Definition: Query.h:55
Queries::Query::TypeConvert
MatchFuncArgType TypeConvert(MatchFuncArgType what, Int2Type< false >) const
calls our dataFunc (if it's set) on what and returns the result, otherwise returns what
Definition: Query.h:163
Queries::Query::CHILD_VECT
std::vector< CHILD_TYPE > CHILD_VECT
Definition: Query.h:51
Queries::Query::d_tol
MatchFuncArgType d_tol
Definition: Query.h:146
PRECONDITION
#define PRECONDITION(expr, mess)
Definition: Invariant.h:109
Queries::Query
Base class for all queries.
Definition: Query.h:46
Queries::Query::getDescription
const std::string & getDescription() const
returns our text description
Definition: Query.h:76
Queries::Query::CHILD_VECT_I
CHILD_VECT::iterator CHILD_VECT_I
Definition: Query.h:52
Queries::Query::setDescription
void setDescription(const std::string &descr)
sets our text description
Definition: Query.h:68
Queries::Query::d_dataFuncSameType
MatchFuncArgType(* d_dataFuncSameType)(MatchFuncArgType)
Definition: Query.h:159
export.h