Coverage Report

Created: 2025-08-26 06:51

/src/openbabel/include/openbabel/base.h
Line
Count
Source (jump to first uncovered line)
1
/**********************************************************************
2
base.h - Base class for OpenBabel objects
3
4
Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
5
Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison
6
7
This file is part of the Open Babel project.
8
For more information, see <http://openbabel.org/>
9
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation version 2 of the License.
13
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
GNU General Public License for more details.
18
***********************************************************************/
19
20
#ifndef OB_BASE_H
21
#define OB_BASE_H
22
23
#include <openbabel/babelconfig.h>
24
25
#include <vector>
26
#include <map>
27
#include <string>
28
#include <iostream>
29
#include <openbabel/tokenst.h>
30
31
#ifdef UNUSED
32
#elif (__GNUC__ == 4)
33
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
34
#elif defined(__LCLINT__)
35
# define UNUSED(x) /*@unused@*/ x
36
#else
37
# define UNUSED(x) x
38
#endif
39
40
namespace OpenBabel
41
{
42
43
  //Forward declaration of the base class for OBMol OBReaction, OBAtom, etc.
44
  //Declaration later in this file.
45
class OBBase;
46
class OBConversion; //used only as pointer
47
48
//! \return the version of the Open Babel library for feature-detection (e.g. "2.3.1")
49
  OBAPI std::string OBReleaseVersion();
50
51
  //! \brief Classification of data stored via OBGenericData class and subclasses.
52
  //!
53
  //! OBGenericDataType can be used as a faster, direct access to a particular category
54
  //! instead of the slower access via GetData(std::string), which must loop
55
  //! through all data to find a match with the supplied key. It is implemented
56
  //! as a set of unsigned integer constants for maximum flexibility and future
57
  //! expansion.
58
  //!
59
  //! CustomData0 through CustomData15 are data slots that are not used in
60
  //! OpenBabel directly and are meant for use in derivative programs.
61
  //! Macro definitions can be used to define what each data slot is used in your code.
62
  namespace OBGenericDataType
63
  {
64
    enum
65
    {
66
      //! Unknown data type (default)
67
      UndefinedData =      0,
68
69
      //! Arbitrary key/value data, i.e., OBPairData
70
      PairData      =      1,
71
72
      //! Energetics data (e.g., total energy, heat of formation, etc.)
73
      EnergyData    =      2,
74
75
      //! Storing text comments (one per molecule, atom, bond, etc.) (for other data, e.g., author, keyword, ... use OBPairData)
76
      CommentData   =      3,
77
78
      //! Arbitrary information about conformers, i.e., OBConformerData
79
      ConformerData =      4,
80
81
      //! Bond data external to OpenBabel, i.e., OBExternalBond, OBExternalBondData
82
      ExternalBondData =   5,
83
84
      //! Information for generating & manipulating rotamers, i.e. OBRotamerList
85
      RotamerList =        6,
86
87
      //! Info. for storing bonds to atoms yet to be added, i.e. OBVirtualBond
88
      VirtualBondData =    7,
89
90
      //! Information on rings in a molecule, i.e., OBRingData
91
      RingData =           8,
92
93
      //! Information about torsion/dihedral angles, i.e., OBTorsionData and OBTorsion
94
      TorsionData =        9,
95
96
      //! Bond angles in a molecule, i.e., OBAngle, OBAngleData
97
      AngleData =         10,
98
99
      //! Residue serial numbers
100
      SerialNums =        11,
101
102
      //! Crystallographic unit cell data, i.e., OBUnitCell
103
      UnitCell =          12,
104
105
      //! Spin data, including NMR, atomic and molecular spin, etc.
106
      SpinData =          13,
107
108
      //! Arbitrary partial and total charges, dipole moments, etc.
109
      ChargeData =        14,
110
111
      //! Symmetry data -- point and space groups, transforms, etc. i.e., OBSymmetryData
112
      SymmetryData =      15,
113
114
      // 16 - Value unused, formerly ChiralData
115
116
      //! Atomic and molecular occupation data (e.g., for crystal structures)
117
      OccupationData =    17,
118
119
      //! Density (cube) data and surfaces
120
      DensityData =       18,
121
122
      //! Electronic levels, redox states, orbitals, etc.
123
      ElectronicData =    19,
124
125
      //! Vibrational modes, frequencies, etc.
126
      VibrationData =     20,
127
128
      //! Rotational energy information
129
      RotationData =      21,
130
131
      //! Nuclear transitions (e.g., decay, capture, fission, fusion)
132
      NuclearData =       22,
133
134
      //! Set Data (a set of OBGenericData)
135
      SetData =           23,
136
137
      //! Grid Data (e.g., 3D grids of data a.k.a. cubes)
138
      GridData =          24,
139
140
      //! Vector Data (i.e., one vector like a dipole moment)
141
      VectorData =        25,
142
143
      //! Matrix data (i.e., a 3x3 matrix like a rotation or quadrupole moment)
144
      MatrixData =        26,
145
146
      //! Stereochemistry data (see OBStereoBase)
147
      StereoData =        27,
148
149
      //! Density of States data (fermi energy and energy vs. density data)
150
      DOSData =           28,
151
152
      //! Electronic transition data (e.g., UV/Vis, excitation energies, etc.)
153
      ElectronicTransitionData = 29,
154
155
      // space for up to 2^14 more entries...
156
157
      //! Custom (user-defined data)
158
      CustomData0 = 16384,
159
      CustomData1 = 16385,
160
      CustomData2 = 16386,
161
      CustomData3 = 16387,
162
      CustomData4 = 16388,
163
      CustomData5 = 16389,
164
      CustomData6 = 16390,
165
      CustomData7 = 16391,
166
      CustomData8 = 16392,
167
      CustomData9 = 16393,
168
      CustomData10 = 16394,
169
      CustomData11 = 16395,
170
      CustomData12 = 16396,
171
      CustomData13 = 16397,
172
      CustomData14 = 16398,
173
      CustomData15 = 16399
174
    };
175
  } // end namespace
176
  enum DataOrigin {
177
    any,                 //!< Undefined or unspecified (default)
178
    fileformatInput,     //!< Read from an input file
179
    userInput,           //!< Added by the user
180
    perceived,           //!< Perceived by Open Babel library methods
181
    external,            //!< Added by an external program
182
    local                //!< Not for routine external use (e.g. in sdf or cml properties)
183
  };
184
185
  //! \brief Base class for generic data
186
  // Class introduction in generic.cpp
187
  // This base class declaration  has no dependence on mol.h
188
  class OBAPI OBGenericData
189
  {
190
  protected:
191
    std::string  _attr;  //!< attribute tag (e.g., "UnitCell", "Comment" or "Author")
192
    unsigned int _type;  //!< attribute type -- declared for each subclass
193
    DataOrigin   _source;//!< source of data for accounting
194
  public:
195
    OBGenericData(const std::string attr = "undefined",
196
                  const unsigned int type =  OBGenericDataType::UndefinedData,
197
                  const DataOrigin source = any);
198
    //Use default copy constructor and assignment operators
199
    //OBGenericData(const OBGenericData&);
200
201
    /* Virtual constructors added. see
202
       http://www.parashift.com/c++-faq-lite/abcs.html#faq-22.5
203
       to allow copying given only a base class OBGenericData pointer.
204
       It may be necessary to cast the return pointer to the derived class
205
       type, since we are doing without Covariant Return Types
206
       http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8
207
208
       A derived class may return NULL if copying is inappropriate */
209
    virtual OBGenericData* Clone(OBBase* /*parent*/) const
210
0
    { return nullptr; }
211
459k
    virtual ~OBGenericData()    {}
212
    //Use default copy constructor and assignment operators
213
    //OBGenericData& operator=(const OBGenericData &src);
214
215
    //! Set the attribute (key), which can be used to retrieve this data
216
    void                      SetAttribute(const std::string &v)
217
168k
    {        _attr = v;        }
218
    //! Set the origin of this data, which can be used to filter the data
219
482k
    void SetOrigin(const DataOrigin s) { _source = s; }
220
    //! \return The attribute (key), which can be used to retrieve this data
221
    virtual const std::string &GetAttribute()  const
222
1.02M
    {        return(_attr);    }
223
    //! \return the data type for this object as defined in OBGenericDataType
224
    unsigned int                GetDataType()    const
225
362k
    {        return(_type);    }
226
    //! \brief Base class returns a default value (the attribute type)
227
    //! but should never be called
228
    virtual const std::string &GetValue()  const
229
0
    {     return _attr; }
230
    virtual DataOrigin GetOrigin() const
231
0
    {     return _source; }
232
  };
233
234
  //! A standard iterator over vectors of OBGenericData (e.g., inherited from OBBase)
235
  typedef std::vector<OBGenericData*>::iterator OBDataIterator;
236
237
  //! Base Class
238
  // introduction in base.cpp
239
  class OBAPI OBBase
240
    {
241
    public:
242
      virtual ~OBBase()
243
1.04M
        {
244
1.04M
          if (!_vdata.empty())
245
21.2k
            {
246
21.2k
              std::vector<OBGenericData*>::iterator m;
247
479k
              for (m = _vdata.begin();m != _vdata.end();m++)
248
458k
                delete *m;
249
21.2k
              _vdata.clear();
250
21.2k
            }
251
1.04M
        }
252
253
      //! \brief Clear any and all data associated with this object
254
      virtual bool Clear();
255
256
      //! Perform a set of transformations specified by the user
257
      //!
258
      //! Typically these are program options to filter or modify an object
259
      //! For example, see OBMol::DoTransformations() and OBMol::ClassDescription()
260
      //! Base type does nothing
261
      virtual OBBase* DoTransformations(const std::map<std::string,std::string>* /*pOptions*/,
262
                                        OBConversion* /*pConv*/)
263
0
        {
264
0
          return this;
265
0
        }
266
267
      //! \return A list of descriptions of command-line options for DoTransformations()
268
      static const char* ClassDescription()
269
0
        {
270
0
          return "";
271
0
        }
272
273
      //! \brief By default clears the object. Called from ReadMolecule of most format classes
274
      template< class T >
275
      T* CastAndClear(bool clear=true)
276
14.3k
        {
277
14.3k
          T* pOb = dynamic_cast<T*>(this);
278
14.3k
          if(pOb && clear)// Clear only if this is of target class
279
14.3k
            Clear();
280
14.3k
          return pOb;
281
14.3k
        }
OpenBabel::OBMol* OpenBabel::OBBase::CastAndClear<OpenBabel::OBMol>(bool)
Line
Count
Source
276
14.3k
        {
277
14.3k
          T* pOb = dynamic_cast<T*>(this);
278
14.3k
          if(pOb && clear)// Clear only if this is of target class
279
14.3k
            Clear();
280
14.3k
          return pOb;
281
14.3k
        }
Unexecuted instantiation: OpenBabel::OBReaction* OpenBabel::OBBase::CastAndClear<OpenBabel::OBReaction>(bool)
282
283
      //! \brief  Base type does nothing
284
      //! Made virtual around r3535 to simplify code which passes around OBBase*.
285
      //Currently no title data member in base class.
286
0
      virtual const char  *GetTitle(bool UNUSED(replaceNewlines) = true) const { return "";}
287
0
      virtual void  SetTitle(const char *) {}
288
289
      //! \name Generic data handling methods (via OBGenericData)
290
      //@{
291
      //! \return whether the generic attribute/value pair exists
292
      bool                              HasData(const std::string &);
293
      //! \return whether the generic attribute/value pair exists
294
      bool                              HasData(const char *);
295
      //! \return whether the generic attribute/value pair exists, for a given OBGenericDataType
296
      bool                              HasData(const unsigned int type);
297
      //! Delete any data matching the given OBGenericDataType
298
      void                              DeleteData(unsigned int type);
299
      //! Delete the given generic data from this object
300
      void                              DeleteData(OBGenericData*);
301
      //! Delete all of the given generic data from this object
302
      void                              DeleteData(std::vector<OBGenericData*>&);
303
      //! Deletes the generic data with the specified attribute, returning false if not found
304
      bool                              DeleteData(const std::string& s);
305
      //! Adds a data object; does nothing if d==NULL
306
      void                              SetData(OBGenericData *d)
307
459k
        {
308
459k
          if(d) _vdata.push_back(d);
309
459k
        }
310
      //! Adds a copy of a data object; does nothing if d == NULL
311
      //! \since version 2.2
312
      void                              CloneData(OBGenericData *d);
313
      //! \return the number of OBGenericData items attached to this molecule.
314
      size_t                      DataSize() const
315
0
        { return(_vdata.size()); }
316
      //! \return the first matching data for a given type from OBGenericDataType
317
      //!    or NULL if nothing matches
318
      OBGenericData                    *GetData(const unsigned int type);
319
      //! \return any data matching the given attribute name or NULL if nothing matches
320
      OBGenericData                    *GetData(const std::string&);
321
      //! \return any data matching the given attribute name or NULL if nothing matches
322
      OBGenericData                    *GetData(const char *);
323
      //! \return the all matching data for a given type from OBGenericDataType
324
      //!    or an empty vector if nothing matches
325
      //! \since version 2.2
326
      std::vector<OBGenericData*>       GetAllData(const unsigned int type);
327
      //! \return all data, suitable for iterating
328
0
      std::vector<OBGenericData*>      &GetData() { return(_vdata); }
329
      //! \return all data with a specific origin, suitable for iterating
330
      std::vector<OBGenericData*>      GetData(DataOrigin source);
331
      //! \return An iterator pointing to the beginning of the data
332
      OBDataIterator  BeginData()
333
818k
        { return(_vdata.begin());        }
334
      //! \return An iterator pointing to the end of the data
335
      OBDataIterator  EndData()
336
818k
        { return(_vdata.end());          }
337
      //@}
338
    protected:
339
      std::vector<OBGenericData*> _vdata; //!< Custom data
340
341
    };
342
343
  template<typename T, typename Iter = typename std::vector<T>::const_iterator>
344
  class OBAPI OBRange
345
  {
346
    public:
347
86.0k
      OBRange(Iter begin, Iter end) : m_begin{begin}, m_end{end}
348
86.0k
      {
349
86.0k
      }
OpenBabel::OBRange<OpenBabel::OBAtom*, std::__1::__wrap_iter<OpenBabel::OBAtom* const*> >::OBRange(std::__1::__wrap_iter<OpenBabel::OBAtom* const*>, std::__1::__wrap_iter<OpenBabel::OBAtom* const*>)
Line
Count
Source
347
49.5k
      OBRange(Iter begin, Iter end) : m_begin{begin}, m_end{end}
348
49.5k
      {
349
49.5k
      }
OpenBabel::OBRange<OpenBabel::OBAtom*, OpenBabel::OBAtomAtomIterAdaptor>::OBRange(OpenBabel::OBAtomAtomIterAdaptor, OpenBabel::OBAtomAtomIterAdaptor)
Line
Count
Source
347
8.00k
      OBRange(Iter begin, Iter end) : m_begin{begin}, m_end{end}
348
8.00k
      {
349
8.00k
      }
OpenBabel::OBRange<OpenBabel::OBBond*, std::__1::__wrap_iter<OpenBabel::OBBond* const*> >::OBRange(std::__1::__wrap_iter<OpenBabel::OBBond* const*>, std::__1::__wrap_iter<OpenBabel::OBBond* const*>)
Line
Count
Source
347
28.4k
      OBRange(Iter begin, Iter end) : m_begin{begin}, m_end{end}
348
28.4k
      {
349
28.4k
      }
350
351
86.0k
      Iter begin() const { return m_begin; }
OpenBabel::OBRange<OpenBabel::OBAtom*, std::__1::__wrap_iter<OpenBabel::OBAtom* const*> >::begin() const
Line
Count
Source
351
49.5k
      Iter begin() const { return m_begin; }
OpenBabel::OBRange<OpenBabel::OBAtom*, OpenBabel::OBAtomAtomIterAdaptor>::begin() const
Line
Count
Source
351
8.00k
      Iter begin() const { return m_begin; }
OpenBabel::OBRange<OpenBabel::OBBond*, std::__1::__wrap_iter<OpenBabel::OBBond* const*> >::begin() const
Line
Count
Source
351
28.4k
      Iter begin() const { return m_begin; }
352
86.0k
      Iter end() const { return m_end; }
OpenBabel::OBRange<OpenBabel::OBAtom*, std::__1::__wrap_iter<OpenBabel::OBAtom* const*> >::end() const
Line
Count
Source
352
49.5k
      Iter end() const { return m_end; }
OpenBabel::OBRange<OpenBabel::OBAtom*, OpenBabel::OBAtomAtomIterAdaptor>::end() const
Line
Count
Source
352
8.00k
      Iter end() const { return m_end; }
OpenBabel::OBRange<OpenBabel::OBBond*, std::__1::__wrap_iter<OpenBabel::OBBond* const*> >::end() const
Line
Count
Source
352
28.4k
      Iter end() const { return m_end; }
353
354
    private:
355
      Iter m_begin;
356
      Iter m_end;
357
  };
358
359
} //namespace OpenBabel
360
361
#endif // OB_BASE_H
362
363
//! \file base.h
364
//! \brief Base classes to build a graph