RDKit: Query.h Source File

| RDKit Open-source cheminformatics and machine learning.

Loading...
Searching...
No Matches
Query.h
Go to the documentation of this file.
1//
2// Copyright (c) 2003-2020 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 <RDGeneral/Invariant.h>
21
22namespace Queries {
23
24//! class to allow integer values to pick templates
25template <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*/
43template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
44 bool needsConversion = false>
45 class RDKIT_QUERY_EXPORT Query {
46 public:
47 using CHILD_TYPE = std::shared_ptr<
48 Query<MatchFuncArgType, DataFuncArgType, needsConversion>>;
49 using CHILD_VECT = std::vector<CHILD_TYPE>;
50 using CHILD_VECT_I = typename CHILD_VECT::iterator;
51 using CHILD_VECT_CI = typename CHILD_VECT::const_iterator;
52 using MATCH_FUNC_ARG_TYPE = MatchFuncArgType;
53 using DATA_FUNC_ARG_TYPE = DataFuncArgType;
54
55 Query() : d_matchFunc(nullptr), d_dataFunc(nullptr) {}
56 virtual ~Query() { this->d_children.clear(); }
57
58 //! sets whether or not we are negated
59 void setNegation(bool what) { this->df_negate = what; }
60 //! returns whether or not we are negated
61 bool getNegation() const { return this->df_negate; }
62
63 //! sets our text description
64 void setDescription(const std::string &descr) { this->d_description = descr; }
65 //! \overload
66 void setDescription(const char *descr) {
67 this->d_description = std::string(descr);
68 }
69 //! returns our text description
70 const std::string &getDescription() const { return this->d_description; }
71 //! returns a fuller text description
72 virtual std::string getFullDescription() const {
73 if (!getNegation()) {
74 return getDescription();
75 } else {
76 return "not " + getDescription();
77 }
78 }
79
80 //! sets our type label
81 void setTypeLabel(const std::string &typ) { this->d_queryType = typ; }
82 //! \overload
83 void setTypeLabel(const char *typ) { this->d_queryType = std::string(typ); }
84 //! returns our text label.
85 const std::string &getTypeLabel() const { return this->d_queryType; }
86
87 //! sets our match function
88 void setMatchFunc(bool (*what)(MatchFuncArgType)) {
89 this->d_matchFunc = what;
90 }
91 //! returns our match function:
92 bool (*getMatchFunc() const)(MatchFuncArgType) { return this->d_matchFunc; }
93 //! sets our data function
94 void setDataFunc(MatchFuncArgType (*what)(DataFuncArgType)) {
95 this->d_dataFunc = what;
96 }
97 //! returns our data function:
98 MatchFuncArgType (*getDataFunc() const)(DataFuncArgType) {
99 return this->d_dataFunc;
100 }
101
102 //! adds a child to our list of children
103 void addChild(CHILD_TYPE child) { this->d_children.push_back(child); }
104 //! returns an iterator for the beginning of our child vector
105 CHILD_VECT_CI beginChildren() const { return this->d_children.begin(); }
106 //! returns an iterator for the end of our child vector
107 CHILD_VECT_CI endChildren() const { return this->d_children.end(); }
108
109 //! returns whether or not we match the argument
110 virtual bool Match(const DataFuncArgType arg) const {
111 MatchFuncArgType mfArg = TypeConvert(arg, Int2Type<needsConversion>());
112 bool tRes;
113 if (this->d_matchFunc) {
114 tRes = this->d_matchFunc(mfArg);
115 } else {
116 tRes = static_cast<bool>(mfArg);
117 }
118
119 if (this->getNegation()) {
120 return !tRes;
121 } else {
122 return tRes;
123 }
124 }
125
126 //! returns a copy of this Query
127 /*!
128 <b>Notes:</b>
129 - the caller is responsible for <tt>delete</tt>ing the result
130 */
131 virtual Query<MatchFuncArgType, DataFuncArgType, needsConversion> *copy()
132 const {
133 Query<MatchFuncArgType, DataFuncArgType, needsConversion> *res =
134 new Query<MatchFuncArgType, DataFuncArgType, needsConversion>();
135 for (auto iter = this->beginChildren(); iter != this->endChildren();
136 ++iter) {
137 res->addChild(CHILD_TYPE(iter->get()->copy()));
138 }
139 res->d_val = this->d_val;
140 res->d_tol = this->d_tol;
141 res->df_negate = this->df_negate;
142 res->d_matchFunc = this->d_matchFunc;
143 res->d_dataFunc = this->d_dataFunc;
144 res->d_description = this->d_description;
145 res->d_queryType = this->d_queryType;
146 return res;
147 }
148
149 protected:
150 MatchFuncArgType d_val = 0;
151 MatchFuncArgType d_tol = 0;
152 std::string d_description = "";
153 std::string d_queryType = "";
154 CHILD_VECT d_children;
155 bool df_negate{false};
156 bool (*d_matchFunc)(MatchFuncArgType);
157
158 // MSVC complains at compile time when TypeConvert(MatchFuncArgType what,
159 // Int2Type<false>) attempts to pass what (which is of type MatchFuncArgType)
160 // as parameter of d_dataFunc() (which should be of type DataFuncArgType). The
161 // union is but a trick to avoid silly casts and keep MSVC happy when building
162 // DLLs
163 union {
164 MatchFuncArgType (*d_dataFunc)(DataFuncArgType);
165 MatchFuncArgType (*d_dataFuncSameType)(MatchFuncArgType);
166 };
167 //! \brief calls our \c dataFunc (if it's set) on \c what and returns
168 //! the result, otherwise returns \c what
169 MatchFuncArgType TypeConvert(MatchFuncArgType what,
170 Int2Type<false> /*d*/) const {
171 MatchFuncArgType mfArg;
172 if (this->d_dataFuncSameType != nullptr &&
173 std::is_same<MatchFuncArgType, DataFuncArgType>::value) {
174 mfArg = this->d_dataFuncSameType(what);
175 } else {
176 mfArg = what;
177 }
178 return mfArg;
179 }
180 //! calls our \c dataFunc (which must be set) on \c what and returns the
181 /// result
182 MatchFuncArgType TypeConvert(DataFuncArgType what,
183 Int2Type<true> /*d*/) const {
184 PRECONDITION(this->d_dataFunc, "no data function");
185 MatchFuncArgType mfArg;
186 mfArg = this->d_dataFunc(what);
187 return mfArg;
188 }
189};
190
191//----------------------------
192//
193// Used within query functions to compare values
194//
195//----------------------------
196template <class T1, class T2>
197 int queryCmp(const T1 v1, const T2 v2, const T1 tol) {
198 T1 diff = v1 - v2;
199 if (diff <= tol) {
200 if (diff >= -tol) {
201 return 0;
202 } else {
203 return -1;
204 }
205 } else {
206 return 1;
207 }
208};
209} // namespace Queries
210#endif
Invariant.h
PRECONDITION
#define PRECONDITION(expr, mess)
Definition Invariant.h:108
Queries::Int2Type
class to allow integer values to pick templates
Definition Query.h:26
Queries::Query< int, Atom const *, true >::d_dataFunc
int(* d_dataFunc)(Atom const *)
Definition Query.h:164
Queries::Query::TypeConvert
MatchFuncArgType TypeConvert(DataFuncArgType what, Int2Type< true >) const
Definition Query.h:182
Queries::Query::getTypeLabel
const std::string & getTypeLabel() const
returns our text label.
Definition Query.h:85
Queries::Query::getMatchFunc
bool(*)(MatchFuncArgType) getMatchFunc() const
returns our match function:
Definition Query.h:92
Queries::Query< int, Atom const *, true >::d_dataFuncSameType
int(* d_dataFuncSameType)(int)
Definition Query.h:165
Queries::Query::getFullDescription
virtual std::string getFullDescription() const
returns a fuller text description
Definition Query.h:72
Queries::Query::Match
virtual bool Match(const DataFuncArgType arg) const
returns whether or not we match the argument
Definition Query.h:110
Queries::Query< int, Atom const *, true >::TypeConvert
int TypeConvert(int what, Int2Type< false >) const
Definition Query.h:169
Queries::Query::addChild
void addChild(CHILD_TYPE child)
adds a child to our list of children
Definition Query.h:103
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:66
Queries::Query< int, Atom const *, true >::d_queryType
std::string d_queryType
Definition Query.h:153
Queries::Query::endChildren
CHILD_VECT_CI endChildren() const
returns an iterator for the end of our child vector
Definition Query.h:107
Queries::Query< int, Atom const *, true >::MATCH_FUNC_ARG_TYPE
int MATCH_FUNC_ARG_TYPE
Definition Query.h:52
Queries::Query::beginChildren
CHILD_VECT_CI beginChildren() const
returns an iterator for the beginning of our child vector
Definition Query.h:105
Queries::Query::setDataFunc
void setDataFunc(MatchFuncArgType(*what)(DataFuncArgType))
sets our data function
Definition Query.h:94
Queries::Query::setTypeLabel
void setTypeLabel(const std::string &typ)
sets our type label
Definition Query.h:81
Queries::Query< int, Atom const *, true >::CHILD_VECT
std::vector< CHILD_TYPE > CHILD_VECT
Definition Query.h:49
Queries::Query< int, Atom const *, true >::DATA_FUNC_ARG_TYPE
Atom const * DATA_FUNC_ARG_TYPE
Definition Query.h:53
Queries::Query::getNegation
bool getNegation() const
returns whether or not we are negated
Definition Query.h:61
Queries::Query::setNegation
void setNegation(bool what)
sets whether or not we are negated
Definition Query.h:59
Queries::Query::copy
virtual Query< MatchFuncArgType, DataFuncArgType, needsConversion > * copy() const
returns a copy of this Query
Definition Query.h:131
Queries::Query< int, Atom const *, true >::d_children
CHILD_VECT d_children
Definition Query.h:154
Queries::Query::getDescription
const std::string & getDescription() const
returns our text description
Definition Query.h:70
Queries::Query< int, Atom const *, true >::CHILD_VECT_CI
typename CHILD_VECT::const_iterator CHILD_VECT_CI
Definition Query.h:51
Queries::Query::setMatchFunc
void setMatchFunc(bool(*what)(MatchFuncArgType))
sets our match function
Definition Query.h:88
Queries::Query::Query
Query()
Definition Query.h:55
Queries::Query< int, Atom const *, true >::df_negate
bool df_negate
Definition Query.h:155
Queries::Query::setTypeLabel
void setTypeLabel(const char *typ)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition Query.h:83
Queries::Query::~Query
virtual ~Query()
Definition Query.h:56
Queries::Query< int, Atom const *, true >::CHILD_VECT_I
typename CHILD_VECT::iterator CHILD_VECT_I
Definition Query.h:50
Queries::Query::d_tol
MatchFuncArgType d_tol
Definition Query.h:151
Queries::Query::d_val
MatchFuncArgType d_val
Definition Query.h:150
Queries::Query< int, Atom const *, true >::CHILD_TYPE
std::shared_ptr< Query< int, Atom const *, needsConversion > > CHILD_TYPE
Definition Query.h:47
Queries::Query::getDataFunc
MatchFuncArgType(*)(DataFuncArgType) getDataFunc() const
returns our data function:
Definition Query.h:98
Queries::Query::setDescription
void setDescription(const std::string &descr)
sets our text description
Definition Query.h:64
Queries::Query< int, Atom const *, true >::d_description
std::string d_description
Definition Query.h:152
Queries::Query< int, Atom const *, true >::d_matchFunc
bool(* d_matchFunc)(int)
Definition Query.h:156
export.h
RDKIT_QUERY_EXPORT
#define RDKIT_QUERY_EXPORT
Definition export.h:661
Queries
Definition AndQuery.h:16
Queries::queryCmp
int queryCmp(const T1 v1, const T2 v2, const T1 tol)
Definition Query.h:197