Loading...
Searching...
No Matches
Query.h
Go to the documentation of this file.
//
// Copyright (c) 2003-2026 Greg Landrum and other RDKit contributors
//
// @@ All Rights Reserved @@
// This file is part of the RDKit.
// The contents are covered by the terms of the BSD license
// which is included in the file license.txt, found at the root
// of the RDKit source tree.
//
#include <RDGeneral/export.h>
#ifndef RD_QUERY_H
#define RD_QUERY_H
#ifdef _MSC_VER
#pragma warning(disable : 4800) // warning: converting things to bool
#endif
#include <vector>
#include <string>
#include <functional>
#include <RDGeneral/Invariant.h>
namespace Queries {
//! class to allow integer values to pick templates
template <int v>
class Int2Type {
enum {
value = v
};
};
//! Base class for all queries
/*!
Query objects have one or two functions associated with them:
- <tt>bool matchFunc(MatchFuncArgType other)</tt> returns true or false
to indicate whether this query matches \c other.
This is mandatory.
- <tt>MatchFuncArgType dataFunc(DataFuncArgType other)</tt> converts
the argument \c other from \c DataFuncArgType to \c MatchFuncArgType.
This is optional if \c DataFuncArgType is the same as (or implicitly
convertible to) \c MatchFuncArgType.
*/
template <class MatchFuncArgType, class DataFuncArgType = MatchFuncArgType,
bool needsConversion = false>
class RDKIT_QUERY_EXPORT Query {
public:
using CHILD_TYPE = std::shared_ptr<
Query<MatchFuncArgType, DataFuncArgType, needsConversion>>;
using CHILD_VECT = std::vector<CHILD_TYPE>;
using CHILD_VECT_I = typename CHILD_VECT::iterator;
using CHILD_VECT_CI = typename CHILD_VECT::const_iterator;
using MATCH_FUNC_ARG_TYPE = MatchFuncArgType;
using DATA_FUNC_ARG_TYPE = DataFuncArgType;
Query() : d_matchFunc(nullptr), d_dataFunc(nullptr) {}
virtual ~Query() { this->d_children.clear(); }
//! sets whether or not we are negated
void setNegation(bool what) { this->df_negate = what; }
//! returns whether or not we are negated
bool getNegation() const { return this->df_negate; }
//! sets our text description
void setDescription(const std::string &descr) { this->d_description = descr; }
//! \overload
void setDescription(const char *descr) {
this->d_description = std::string(descr);
}
//! returns our text description
const std::string &getDescription() const { return this->d_description; }
//! returns a fuller text description
virtual std::string getFullDescription() const {
if (!getNegation()) {
return getDescription();
} else {
return "not " + getDescription();
}
}
//! sets our type label
void setTypeLabel(const std::string &typ) { this->d_queryType = typ; }
//! \overload
void setTypeLabel(const char *typ) { this->d_queryType = std::string(typ); }
//! returns our text label.
const std::string &getTypeLabel() const { return this->d_queryType; }
//! sets our match function
void setMatchFunc(std::function<bool(MatchFuncArgType)> what) {
this->d_matchFunc = what;
}
//! returns our match function:
std::function<bool(MatchFuncArgType)> getMatchFunc() const {
return this->d_matchFunc;
}
//! sets our data function
void setDataFunc(std::function<MatchFuncArgType(DataFuncArgType)> what) {
this->d_dataFunc = what;
}
//! returns our data function:
std::function<MatchFuncArgType(DataFuncArgType)> getDataFunc() const {
return this->d_dataFunc;
}
//! adds a child to our list of children
void addChild(CHILD_TYPE child) { this->d_children.push_back(child); }
//! returns an iterator for the beginning of our child vector
CHILD_VECT_CI beginChildren() const { return this->d_children.begin(); }
//! returns an iterator for the end of our child vector
CHILD_VECT_CI endChildren() const { return this->d_children.end(); }
//! returns whether or not we match the argument
virtual bool Match(const DataFuncArgType arg) const {
MatchFuncArgType mfArg = TypeConvert(arg, Int2Type<needsConversion>());
bool tRes;
if (this->d_matchFunc) {
tRes = this->d_matchFunc(mfArg);
} else {
tRes = static_cast<bool>(mfArg);
}
if (this->getNegation()) {
return !tRes;
} else {
return tRes;
}
}
//! returns a copy of this Query
/*!
<b>Notes:</b>
- the caller is responsible for <tt>delete</tt>ing the result
*/
virtual Query<MatchFuncArgType, DataFuncArgType, needsConversion> *copy()
const {
Query<MatchFuncArgType, DataFuncArgType, needsConversion> *res =
new Query<MatchFuncArgType, DataFuncArgType, needsConversion>();
for (auto iter = this->beginChildren(); iter != this->endChildren();
++iter) {
res->addChild(CHILD_TYPE(iter->get()->copy()));
}
res->d_val = this->d_val;
res->d_tol = this->d_tol;
res->df_negate = this->df_negate;
res->d_matchFunc = this->d_matchFunc;
res->d_dataFunc = this->d_dataFunc;
res->d_description = this->d_description;
res->d_queryType = this->d_queryType;
return res;
}
protected:
MatchFuncArgType d_val = 0;
MatchFuncArgType d_tol = 0;
std::string d_description = "";
std::string d_queryType = "";
CHILD_VECT d_children;
bool df_negate{false};
std::function<bool(MatchFuncArgType)> d_matchFunc;
// MSVC complains at compile time when TypeConvert(MatchFuncArgType what,
// Int2Type<false>) attempts to pass what (which is of type MatchFuncArgType)
// as parameter of d_dataFunc() (which should be of type DataFuncArgType). The
// union is but a trick to avoid silly casts and keep MSVC happy when building
// DLLs
union {
std::function<MatchFuncArgType(DataFuncArgType)> d_dataFunc;
std::function<MatchFuncArgType(MatchFuncArgType)> d_dataFuncSameType;
};
//! \brief calls our \c dataFunc (if it's set) on \c what and returns
//! the result, otherwise returns \c what
MatchFuncArgType TypeConvert(MatchFuncArgType what,
Int2Type<false> /*d*/) const {
MatchFuncArgType mfArg;
if (this->d_dataFuncSameType != nullptr &&
std::is_same<MatchFuncArgType, DataFuncArgType>::value) {
mfArg = this->d_dataFuncSameType(what);
} else {
mfArg = what;
}
return mfArg;
}
//! calls our \c dataFunc (which must be set) on \c what and returns the
/// result
MatchFuncArgType TypeConvert(DataFuncArgType what,
Int2Type<true> /*d*/) const {
PRECONDITION(this->d_dataFunc, "no data function");
MatchFuncArgType mfArg;
mfArg = this->d_dataFunc(what);
return mfArg;
}
};
//----------------------------
//
// Used within query functions to compare values
//
//----------------------------
template <class T1, class T2>
int queryCmp(const T1 v1, const T2 v2, const T1 tol) {
T1 diff = v1 - v2;
if (diff <= tol) {
if (diff >= -tol) {
return 0;
} else {
return -1;
}
} else {
return 1;
}
};
} // namespace Queries
#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:27
Queries::Query::TypeConvert
MatchFuncArgType TypeConvert(DataFuncArgType what, Int2Type< true >) const
Definition Query.h:187
Queries::Query::getTypeLabel
const std::string & getTypeLabel() const
returns our text label.
Definition Query.h:88
Queries::Query::getFullDescription
virtual std::string getFullDescription() const
returns a fuller text description
Definition Query.h:75
Queries::Query::Match
virtual bool Match(const DataFuncArgType arg) const
returns whether or not we match the argument
Definition Query.h:115
Queries::Query< int, Atom const *, true >::TypeConvert
int TypeConvert(int what, Int2Type< false >) const
Definition Query.h:174
Queries::Query::addChild
void addChild(CHILD_TYPE child)
adds a child to our list of children
Definition Query.h:108
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:69
Queries::Query< int, Atom const *, true >::d_dataFunc
std::function< int(Atom const *)> d_dataFunc
Definition Query.h:169
Queries::Query< int, Atom const *, true >::d_queryType
std::string d_queryType
Definition Query.h:158
Queries::Query::endChildren
CHILD_VECT_CI endChildren() const
returns an iterator for the end of our child vector
Definition Query.h:112
Queries::Query< int, Atom const *, true >::MATCH_FUNC_ARG_TYPE
int MATCH_FUNC_ARG_TYPE
Definition Query.h:55
Queries::Query::beginChildren
CHILD_VECT_CI beginChildren() const
returns an iterator for the beginning of our child vector
Definition Query.h:110
Queries::Query::setTypeLabel
void setTypeLabel(const std::string &typ)
sets our type label
Definition Query.h:84
Queries::Query< int, Atom const *, true >::CHILD_VECT
std::vector< CHILD_TYPE > CHILD_VECT
Definition Query.h:52
Queries::Query< int, Atom const *, true >::DATA_FUNC_ARG_TYPE
Atom const * DATA_FUNC_ARG_TYPE
Definition Query.h:56
Queries::Query::setDataFunc
void setDataFunc(std::function< MatchFuncArgType(DataFuncArgType)> what)
sets our data function
Definition Query.h:99
Queries::Query::getNegation
bool getNegation() const
returns whether or not we are negated
Definition Query.h:64
Queries::Query::setNegation
void setNegation(bool what)
sets whether or not we are negated
Definition Query.h:62
Queries::Query::copy
virtual Query< MatchFuncArgType, DataFuncArgType, needsConversion > * copy() const
returns a copy of this Query
Definition Query.h:136
Queries::Query< int, Atom const *, true >::d_children
CHILD_VECT d_children
Definition Query.h:159
Queries::Query::setMatchFunc
void setMatchFunc(std::function< bool(MatchFuncArgType)> what)
sets our match function
Definition Query.h:91
Queries::Query::getDescription
const std::string & getDescription() const
returns our text description
Definition Query.h:73
Queries::Query< int, Atom const *, true >::CHILD_VECT_CI
typename CHILD_VECT::const_iterator CHILD_VECT_CI
Definition Query.h:54
Queries::Query::Query
Query()
Definition Query.h:58
Queries::Query::getMatchFunc
std::function< bool(MatchFuncArgType)> getMatchFunc() const
returns our match function:
Definition Query.h:95
Queries::Query< int, Atom const *, true >::d_matchFunc
std::function< bool(int)> d_matchFunc
Definition Query.h:161
Queries::Query< int, Atom const *, true >::df_negate
bool df_negate
Definition Query.h:160
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:86
Queries::Query::~Query
virtual ~Query()
Definition Query.h:59
Queries::Query< int, Atom const *, true >::CHILD_VECT_I
typename CHILD_VECT::iterator CHILD_VECT_I
Definition Query.h:53
Queries::Query::d_tol
MatchFuncArgType d_tol
Definition Query.h:156
Queries::Query::getDataFunc
std::function< MatchFuncArgType(DataFuncArgType)> getDataFunc() const
returns our data function:
Definition Query.h:103
Queries::Query< int, Atom const *, true >::d_dataFuncSameType
std::function< int(int)> d_dataFuncSameType
Definition Query.h:170
Queries::Query::d_val
MatchFuncArgType d_val
Definition Query.h:155
Queries::Query< int, Atom const *, true >::CHILD_TYPE
std::shared_ptr< Query< int, Atom const *, needsConversion > > CHILD_TYPE
Definition Query.h:50
Queries::Query::setDescription
void setDescription(const std::string &descr)
sets our text description
Definition Query.h:67
Queries::Query< int, Atom const *, true >::d_description
std::string d_description
Definition Query.h:157
export.h
RDKIT_QUERY_EXPORT
#define RDKIT_QUERY_EXPORT
Definition export.h:669
Queries
Definition AndQuery.h:16
Queries::queryCmp
int queryCmp(const T1 v1, const T2 v2, const T1 tol)
Definition Query.h:202