RDKit
Open-source cheminformatics and machine learning.
QueryAtom.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2022 Greg Landrum and other RDKit contributors
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_QUERYATOM_H
12 #define RD_QUERYATOM_H
13 
14 #include <utility>
15 #include "Atom.h"
16 #include <Query/QueryObjects.h>
17 #include <GraphMol/QueryOps.h>
18 
19 namespace RDKit {
20 
21 //! Class for storing atomic queries
22 /*!
23  QueryAtom objects are derived from Atom objects, so they can be
24  added to molecules and the like, but they have much fancier
25  querying capabilities.
26 
27  */
29  public:
31 
32  QueryAtom() : Atom() {}
33  explicit QueryAtom(int num) : Atom(num), dp_query(makeAtomNumQuery(num)) {}
34  explicit QueryAtom(const Atom &other)
35  : Atom(other), dp_query(makeAtomNumQuery(other.getAtomicNum())) {
36  if (other.getIsotope()) {
37  this->expandQuery(makeAtomIsotopeQuery(other.getIsotope()),
39  }
40  if (other.getFormalCharge()) {
41  this->expandQuery(makeAtomFormalChargeQuery(other.getFormalCharge()),
43  }
44  if (other.getNumRadicalElectrons()) {
45  this->expandQuery(
48  }
49  }
50  QueryAtom(const QueryAtom &other) : Atom(other) {
51  if (other.dp_query) {
52  dp_query = other.dp_query->copy();
53  } else {
54  dp_query = nullptr;
55  }
56  }
57  QueryAtom &operator=(const QueryAtom &other) {
58  if (this == &other) {
59  return *this;
60  }
61  Atom::operator=(other);
62  delete dp_query;
63  if (other.dp_query) {
64  dp_query = other.dp_query->copy();
65  } else {
66  dp_query = nullptr;
67  }
68  return *this;
69  }
70 
71  QueryAtom(QueryAtom &&other) noexcept : Atom(std::move(other)) {
72  dp_query = std::exchange(other.dp_query, nullptr);
73  }
74  QueryAtom &operator=(QueryAtom &&other) noexcept {
75  if (this == &other) {
76  return *this;
77  }
78  QueryAtom::operator=(std::move(other));
79  dp_query = std::exchange(other.dp_query, nullptr);
80  return *this;
81  }
82 
83  ~QueryAtom() override;
84 
85  //! returns a copy of this query, owned by the caller
86  Atom *copy() const override;
87 
88  // This method can be used to distinguish query atoms from standard atoms:
89  bool hasQuery() const override { return dp_query != nullptr; }
90 
91  //! returns the label associated to this query
92  std::string getQueryType() const override { return dp_query->getTypeLabel(); }
93 
94  //! replaces our current query with the value passed in
95  void setQuery(QUERYATOM_QUERY *what) override {
96  delete dp_query;
97  dp_query = what;
98  }
99  //! returns our current query
100  QUERYATOM_QUERY *getQuery() const override { return dp_query; }
101 
102  //! expands our current query
103  /*!
104  \param what the Queries::Query to be added. The ownership of
105  the query is passed to the current object, where it
106  might be deleted, so that the pointer should not be
107  used again in the calling code.
108  \param how the operator to be used in the expansion
109  \param maintainOrder (optional) flags whether the relative order of
110  the queries needs to be maintained, if this is
111  false, the order is reversed
112  <b>Notes:</b>
113  - \c what should probably be constructed using one of the functions
114  defined in QueryOps.h
115  - the \c maintainOrder option can be useful because the combination
116  operators short circuit when possible.
117 
118  */
121  bool maintainOrder = true) override;
122 
123  //! returns true if we match Atom \c what
124  bool Match(Atom const *what) const override;
125 
126  //! returns true if our query details match those of QueryAtom \c what
127  bool QueryMatch(QueryAtom const *what) const;
128 
129  private:
130  QUERYATOM_QUERY *dp_query{nullptr};
131 
132 }; // end o' class
133 
134 namespace detail {
135 inline std::string qhelper(Atom::QUERYATOM_QUERY *q, unsigned int depth) {
136  std::string res = "";
137  if (q) {
138  for (unsigned int i = 0; i < depth; ++i) {
139  res += " ";
140  }
141  res += q->getFullDescription() + "\n";
143  ci != q->endChildren(); ++ci) {
144  res += qhelper((*ci).get(), depth + 1);
145  }
146  }
147  return res;
148 }
149 } // namespace detail
150 inline std::string describeQuery(const Atom *atom) {
151  PRECONDITION(atom, "bad atom");
152  std::string res = "";
153  if (atom->hasQuery()) {
154  res = detail::qhelper(atom->getQuery(), 0);
155  }
156  return res;
157 }
158 
159 }; // namespace RDKit
160 
161 #endif
Defines the Atom class and associated typedefs.
#define PRECONDITION(expr, mess)
Definition: Invariant.h:109
Pulls in all the query types.
Base class for all queries.
Definition: Query.h:45
virtual std::string getFullDescription() const
returns a fuller text description
Definition: Query.h:72
CHILD_VECT_CI endChildren() const
returns an iterator for the end of our child vector
Definition: Query.h:107
CHILD_VECT_CI beginChildren() const
returns an iterator for the beginning of our child vector
Definition: Query.h:105
virtual Query< MatchFuncArgType, DataFuncArgType, needsConversion > * copy() const
returns a copy of this Query
Definition: Query.h:131
typename CHILD_VECT::const_iterator CHILD_VECT_CI
Definition: Query.h:51
The class for representing atoms.
Definition: Atom.h:68
Atom & operator=(const Atom &other)
unsigned int getNumRadicalElectrons() const
returns the number of radical electrons for this Atom
Definition: Atom.h:210
virtual QUERYATOM_QUERY * getQuery() const
NOT CALLABLE.
virtual bool hasQuery() const
Definition: Atom.h:271
int getFormalCharge() const
returns the formal charge of this atom
Definition: Atom.h:214
unsigned int getIsotope() const
returns our isotope number
Definition: Atom.h:240
Class for storing atomic queries.
Definition: QueryAtom.h:28
bool hasQuery() const override
Definition: QueryAtom.h:89
bool QueryMatch(QueryAtom const *what) const
returns true if our query details match those of QueryAtom what
QUERYATOM_QUERY * getQuery() const override
returns our current query
Definition: QueryAtom.h:100
void setQuery(QUERYATOM_QUERY *what) override
replaces our current query with the value passed in
Definition: QueryAtom.h:95
QueryAtom(int num)
Definition: QueryAtom.h:33
QueryAtom(QueryAtom &&other) noexcept
Definition: QueryAtom.h:71
Atom * copy() const override
returns a copy of this query, owned by the caller
bool Match(Atom const *what) const override
returns true if we match Atom what
Queries::Query< int, Atom const *, true > QUERYATOM_QUERY
Definition: QueryAtom.h:30
QueryAtom & operator=(const QueryAtom &other)
Definition: QueryAtom.h:57
QueryAtom(const QueryAtom &other)
Definition: QueryAtom.h:50
QueryAtom(const Atom &other)
Definition: QueryAtom.h:34
~QueryAtom() override
void expandQuery(QUERYATOM_QUERY *what, Queries::CompositeQueryType how=Queries::COMPOSITE_AND, bool maintainOrder=true) override
expands our current query
std::string getQueryType() const override
returns the label associated to this query
Definition: QueryAtom.h:92
QueryAtom & operator=(QueryAtom &&other) noexcept
Definition: QueryAtom.h:74
#define RDKIT_GRAPHMOL_EXPORT
Definition: export.h:225
CompositeQueryType
Definition: QueryObjects.h:36
@ COMPOSITE_AND
Definition: QueryObjects.h:36
std::string qhelper(Atom::QUERYATOM_QUERY *q, unsigned int depth)
Definition: QueryAtom.h:135
Std stuff.
Definition: Abbreviations.h:19
T * makeAtomFormalChargeQuery(int what, const std::string &descr)
returns a Query for matching formal charge
Definition: QueryOps.h:486
std::string describeQuery(const Atom *atom)
Definition: QueryAtom.h:150
T * makeAtomIsotopeQuery(int what, const std::string &descr)
returns a Query for matching atoms with a particular isotope
Definition: QueryOps.h:478
T * makeAtomNumQuery(int what, const std::string &descr)
returns a Query for matching atomic number
Definition: QueryOps.h:363
T * makeAtomNumRadicalElectronsQuery(int what, const std::string &descr)
returns a Query for matching the number of radical electrons
Definition: QueryOps.h:512