Coverage Report

Created: 2026-03-31 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rdkit/Code/GraphMol/RWMol.h
Line
Count
Source
1
//
2
//  Copyright (C) 2003-2021 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
/*! \file RWMol.h
11
12
  \brief Defines the editable molecule class \c RWMol
13
14
*/
15
16
#include <RDGeneral/export.h>
17
18
#ifndef RD_RWMOL_H
19
#define RD_RWMOL_H
20
21
// our stuff
22
#include "ROMol.h"
23
#include "RingInfo.h"
24
25
namespace RDKit {
26
27
//! RWMol is a molecule class that is intended to be edited
28
/*!
29
    See documentation for ROMol for general remarks
30
31
 */
32
class RDKIT_GRAPHMOL_EXPORT RWMol : public ROMol {
33
 public:
34
64.3k
  RWMol() : ROMol() {}
35
  //! copy constructor with a twist
36
  /*!
37
    \param other     the molecule to be copied
38
    \param quickCopy (optional) if this is true, the resulting ROMol will not
39
         copy any of the properties or bookmarks and conformers from \c other.
40
    This can
41
         make the copy substantially faster (thus the name).
42
    \param confId if this is >=0, the resulting ROMol will contain only
43
         the specified conformer from \c other.
44
  */
45
  RWMol(const ROMol &other, bool quickCopy = false, int confId = -1)
46
1.99k
      : ROMol(other, quickCopy, confId) {}
47
0
  RWMol(const RWMol &other) : ROMol(other) {}
48
  RWMol &operator=(const RWMol &);
49
0
  RWMol(RWMol &&other) noexcept : ROMol(std::move(other)) {}
50
0
  RWMol &operator=(RWMol &&other) noexcept {
51
0
    ROMol::operator=(std::move(other));
52
0
    return *this;
53
0
  }
54
55
  //! insert the atoms and bonds from \c other into this molecule
56
  void insertMol(const ROMol &other);
57
58
  //! \name Atoms
59
  //! @{
60
61
  //! adds an empty Atom to our collection
62
  /*!
63
    \param updateLabel   (optional) if this is true, the new Atom will be
64
                         our \c activeAtom
65
66
    \return the index of the added atom
67
68
  */
69
  unsigned int addAtom(bool updateLabel = true);
70
71
  //! adds an Atom to our collection
72
  /*!
73
    \param atom          pointer to the Atom to add
74
    \param updateLabel   (optional) if this is true, the new Atom will be
75
                         our \c activeAtom
76
    \param takeOwnership (optional) if this is true, we take ownership of \c
77
    atom
78
                         instead of copying it.
79
80
    \return the index of the added atom
81
  */
82
  unsigned int addAtom(Atom *atom, bool updateLabel = true,
83
9.96M
                       bool takeOwnership = false) {
84
9.96M
    return ROMol::addAtom(atom, updateLabel, takeOwnership);
85
9.96M
  }
86
87
  //! adds an Atom to our collection
88
89
  //! replaces a particular Atom
90
  /*!
91
    \param idx          the index of the Atom to replace
92
    \param atom         the new atom, which will be copied.
93
    \param updateLabel   (optional) if this is true, the new Atom will be
94
                         our \c activeAtom
95
    \param preserveProps if true preserve the original atom property data
96
97
  */
98
  void replaceAtom(unsigned int idx, Atom *atom, bool updateLabel = false,
99
                   bool preserveProps = false);
100
  //! returns a pointer to the highest-numbered Atom
101
0
  Atom *getLastAtom() { return getAtomWithIdx(getNumAtoms() - 1); }
102
  //! returns a pointer to the "active" Atom
103
  /*!
104
     If we have an \c activeAtom, it will be returned,
105
     otherwise the results of getLastAtom() will be returned.
106
   */
107
  Atom *getActiveAtom();
108
  //! sets our \c activeAtom
109
  void setActiveAtom(Atom *atom);
110
  //! \overload
111
  void setActiveAtom(unsigned int idx);
112
  //! removes an Atom from the molecule
113
  void removeAtom(unsigned int idx);
114
  //! \overload
115
  void removeAtom(Atom *atom);
116
  //! \overload
117
  void removeAtom(Atom *atom, bool clearProps);
118
119
  //! @}
120
121
  //! \name Bonds
122
  //! @{
123
124
  //! adds a Bond between the indicated Atoms
125
  /*!
126
     \return the number of Bonds
127
  */
128
  unsigned int addBond(unsigned int beginAtomIdx, unsigned int endAtomIdx,
129
                       Bond::BondType order = Bond::UNSPECIFIED);
130
  //! \overload
131
  unsigned int addBond(Atom *beginAtom, Atom *endAtom,
132
                       Bond::BondType order = Bond::UNSPECIFIED);
133
134
  //! adds a Bond to our collection
135
  /*!
136
    \param bond          pointer to the Bond to add
137
    \param takeOwnership (optional) if this is true, we take ownership of \c
138
    bond
139
                         instead of copying it.
140
141
    \return the new number of bonds
142
  */
143
2.36M
  unsigned int addBond(Bond *bond, bool takeOwnership = false) {
144
2.36M
    return ROMol::addBond(bond, takeOwnership);
145
2.36M
  }
146
147
  //! starts a Bond and sets its beginAtomIdx
148
  /*!
149
    \return a pointer to the new bond
150
151
    The caller should set a bookmark to the returned Bond in order
152
    to be able to later complete it:
153
154
    \verbatim
155
      Bond *pBond = mol->createPartialBond(1);
156
      mol->setBondBookmark(pBond,666);
157
      ... do some other stuff ...
158
      mol->finishPartialBond(2,666,Bond::SINGLE);
159
      mol->clearBondBookmark(666,pBond);
160
    \endverbatim
161
162
    or, if we want to set the \c BondType initially:
163
    \verbatim
164
      Bond *pBond = mol->createPartialBond(1,Bond::DOUBLE);
165
      mol->setBondBookmark(pBond,666);
166
      ... do some other stuff ...
167
      mol->finishPartialBond(2,666);
168
      mol->clearBondBookmark(666,pBond);
169
    \endverbatim
170
171
    the call to finishPartialBond() will take priority if you set the
172
    \c BondType in both calls.
173
174
  */
175
  Bond *createPartialBond(unsigned int beginAtomIdx,
176
                          Bond::BondType order = Bond::UNSPECIFIED);
177
  //! finishes a partially constructed bond
178
  /*!
179
    \return the final number of Bonds
180
181
    See the documentation for createPartialBond() for more details
182
  */
183
  unsigned int finishPartialBond(unsigned int endAtomIdx, int bondBookmark,
184
                                 Bond::BondType order = Bond::UNSPECIFIED);
185
186
  //! removes a bond from the molecule
187
  void removeBond(unsigned int beginAtomIdx, unsigned int endAtomIdx);
188
189
  //! replaces a particular Bond
190
  /*!
191
    \param idx          the index of the Bond to replace
192
    \param bond         the new bond, which will be copied.
193
    \param preserveProps if true preserve the original bond property data
194
    \param keepSGroups if true, keep Substance groups referencing the bond
195
196
  */
197
  void replaceBond(unsigned int idx, Bond *bond, bool preserveProps = false,
198
                   bool keepSGroups = true);
199
200
  //! @}
201
202
  //! removes all atoms, bonds, properties, bookmarks, etc.
203
0
  void clear() {
204
0
    destroy();
205
0
    d_confs.clear();
206
0
    ROMol::initMol();  // make sure we have a "fresh" ready to go copy
207
0
    numBonds = 0;
208
0
  }
209
210
  void beginBatchEdit();
211
0
  void rollbackBatchEdit() {
212
0
    dp_delAtoms.reset();
213
0
    dp_delBonds.reset();
214
0
  }
215
  void commitBatchEdit();
216
217
 private:
218
  void batchRemoveBonds();
219
  void batchRemoveAtoms();
220
};
221
222
typedef boost::shared_ptr<RWMol> RWMOL_SPTR;
223
typedef std::vector<RWMOL_SPTR> RWMOL_SPTR_VECT;
224
225
};  // namespace RDKit
226
227
#endif