| 1 | /********************************************************************** | 
| 2 | base.h - Base classes to build a graph | 
| 3 |  | 
| 4 | Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc. | 
| 5 | Some portions Copyright (C) 2001-2005 by Geoffrey R. Hutchison | 
| 6 |  | 
| 7 | This file is part of the Open Babel project. | 
| 8 | For more information, see <http://openbabel.sourceforge.net/> | 
| 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 "babelconfig.hpp" | 
| 24 |  | 
| 25 | #include <vector> | 
| 26 | #include <map> | 
| 27 |  | 
| 28 | #if HAVE_IOSTREAM | 
| 29 | #include <iostream> | 
| 30 | #elif HAVE_IOSTREAM_H | 
| 31 | #include <iostream.h> | 
| 32 | #endif | 
| 33 |  | 
| 34 | namespace OpenBabel | 
| 35 | { | 
| 36 |  | 
| 37 | class OBBase; | 
| 38 | class OBNodeBase; | 
| 39 | class OBEdgeBase; | 
| 40 | class OBGraphBase; | 
| 41 |  | 
| 42 | /** \brief Base Class | 
| 43 |  | 
| 44 | The various classes (Atom, Bond, Molecule) inherit from base classes-- | 
| 45 | OBBase is just a placeholder class | 
| 46 | */ | 
| 47 | class OBAPI OBBase | 
| 48 | { | 
| 49 | public: | 
| 50 | virtual ~OBBase() | 
| 51 | {} | 
| 52 | ; //NF | 
| 53 | virtual OBBase* DoTransformations(const std::map<std::string,std::string>*pOptions) | 
| 54 | { | 
| 55 | return this; | 
| 56 | } //NF Base type does nothing | 
| 57 | static const char* ClassDescription() | 
| 58 | { | 
| 59 | return ""; | 
| 60 | } //NF | 
| 61 |  | 
| 62 | }; | 
| 63 |  | 
| 64 | /** \brief Node Base Class | 
| 65 |  | 
| 66 | The base class for nodes (e.g. atoms) in a graph-theoretical representation. | 
| 67 | */ | 
| 68 | class OBAPI OBNodeBase : public OBBase | 
| 69 | { | 
| 70 | protected: | 
| 71 | //! What is my unique node index?   GetIdx(), SetIdx(int idx). | 
| 72 | unsigned short int  _idx; | 
| 73 | //! To which graph do I belong?     GetParent(), SetParent(OBGraphBase*). | 
| 74 | OBGraphBase        *_parent; | 
| 75 | /** \brief What edges or bonds do I have? \sa AddEdge(), GetValence(), | 
| 76 | This node is assumed to be one of the edge endpoints. | 
| 77 | */ | 
| 78 | std::vector<OBEdgeBase*> _vbond; | 
| 79 |  | 
| 80 | public: | 
| 81 | //! Used internally by graph traversal algorithms | 
| 82 | bool Visit; | 
| 83 |  | 
| 84 | //! Constructor | 
| 85 | OBNodeBase() | 
| 86 | { | 
| 87 | Visit = false; | 
| 88 | } | 
| 89 | //! Destructor | 
| 90 | virtual ~OBNodeBase() | 
| 91 | {} | 
| 92 | virtual unsigned int  GetIdx()                   const | 
| 93 | { | 
| 94 | return(_idx); | 
| 95 | } | 
| 96 | //! Set my unique node number. | 
| 97 | void                  SetIdx(int idx) | 
| 98 | { | 
| 99 | _idx = idx; | 
| 100 | } | 
| 101 | virtual OBGraphBase  *GetParent() | 
| 102 | { | 
| 103 | return(_parent); | 
| 104 | } | 
| 105 | //! Set my parent graph. | 
| 106 | void                  SetParent(OBGraphBase*); | 
| 107 | //! Add an edge. Assumes this node is an endpoint of \a b. | 
| 108 | void                  AddEdge(OBEdgeBase *b) | 
| 109 | { | 
| 110 | _vbond.push_back(b); | 
| 111 | } | 
| 112 | //! How many edges? | 
| 113 | virtual unsigned int  GetValence()               const | 
| 114 | { | 
| 115 | return(_vbond.size()); | 
| 116 | } | 
| 117 | //! Iterate over my edges, returning my connected nodes. | 
| 118 | OBNodeBase           *BeginNbr(std::vector<OBEdgeBase*>::iterator&); | 
| 119 | OBNodeBase           *NextNbr(std::vector<OBEdgeBase*>::iterator&); | 
| 120 | //! Iterate over my edges, returning the edges. | 
| 121 | OBEdgeBase           *Begin(std::vector<OBEdgeBase*>::iterator&); | 
| 122 | OBEdgeBase           *Next(std::vector<OBEdgeBase*>::iterator&); | 
| 123 | //! Is \a OBNodeBase* a beginning or end of some edge of mine? | 
| 124 | virtual bool          IsConnected(OBNodeBase*); | 
| 125 |  | 
| 126 | //! Used to signal erroneously calling some of the nonfunctional members | 
| 127 | void Error(int f) | 
| 128 | { | 
| 129 | std::cerr << "atom vf called = " << f << std::endl; | 
| 130 | } | 
| 131 | /**  \name Nonfunctional members | 
| 132 | Nonfunctional or unused members of OpenBabel::OBNodeBase | 
| 133 | are to be added by a derived class (e.g., OpenBabel::OBAtom) | 
| 134 | @{ | 
| 135 | */ | 
| 136 | virtual int           GetFormalCharge()          const | 
| 137 | { | 
| 138 | ((OBNodeBase*)this)->Error(1); | 
| 139 | return(0); | 
| 140 | } | 
| 141 | virtual unsigned int  ExplicitHydrogenCount()    const | 
| 142 | { | 
| 143 | ((OBNodeBase*)this)->Error(22); | 
| 144 | return(0); | 
| 145 | } | 
| 146 | virtual unsigned int  ImplicitHydrogenCount()    const | 
| 147 | { | 
| 148 | ((OBNodeBase*)this)->Error(22); | 
| 149 | return(0); | 
| 150 | } | 
| 151 | virtual unsigned int  GetImplicitValence()       const | 
| 152 | { | 
| 153 | ((OBNodeBase*)this)->Error(3); | 
| 154 | return(0); | 
| 155 | } | 
| 156 | virtual unsigned int  GetHvyValence()            const | 
| 157 | { | 
| 158 | ((OBNodeBase*)this)->Error(4); | 
| 159 | return(0); | 
| 160 | } | 
| 161 | virtual unsigned int  KBOSum()                const | 
| 162 | { | 
| 163 | ((OBNodeBase*)this)->Error(5); | 
| 164 | return(0); | 
| 165 | } | 
| 166 | virtual unsigned int  GetHyb()                   const | 
| 167 | { | 
| 168 | ((OBNodeBase*)this)->Error(6); | 
| 169 | return(0); | 
| 170 | } | 
| 171 | virtual unsigned int  MemberOfRingCount()        const | 
| 172 | { | 
| 173 | ((OBNodeBase*)this)->Error(7); | 
| 174 | return(0); | 
| 175 | } | 
| 176 | virtual unsigned int  GetAtomicNum()                         const | 
| 177 | { | 
| 178 | ((OBNodeBase*)this)->Error(8); | 
| 179 | return(0); | 
| 180 | } | 
| 181 | virtual void          SetMatch(OBNodeBase*) | 
| 182 | {} | 
| 183 | virtual void          SetAromatic() | 
| 184 | {} | 
| 185 | virtual bool          IsInRingSize(int)          const | 
| 186 | { | 
| 187 | ((OBNodeBase*)this)->Error(9); | 
| 188 | return(false); | 
| 189 | } | 
| 190 | virtual bool          IsAromatic()               const | 
| 191 | { | 
| 192 | ((OBNodeBase*)this)->Error(10); | 
| 193 | return(false); | 
| 194 | } | 
| 195 | virtual bool          IsInRing()                 const | 
| 196 | { | 
| 197 | ((OBNodeBase*)this)->Error(11); | 
| 198 | return(false); | 
| 199 | } | 
| 200 | virtual bool          Eval(OBNodeBase*)          const | 
| 201 | { | 
| 202 | ((OBNodeBase*)this)->Error(12); | 
| 203 | return(false); | 
| 204 | } | 
| 205 | virtual OBNodeBase   *GetMatch() | 
| 206 | { | 
| 207 | ((OBNodeBase*)this)->Error(13); | 
| 208 | return(NULL); | 
| 209 | } | 
| 210 | //@} | 
| 211 | }; | 
| 212 |  | 
| 213 | /** \brief Edge Base Class | 
| 214 |  | 
| 215 | The base class for edges (e.g. bonds) in a graph-theoretical representation. | 
| 216 | */ | 
| 217 | class OBAPI OBEdgeBase : public OBBase | 
| 218 | { | 
| 219 | protected: | 
| 220 | /// What is my unique edge index? GetIdx(), SetIdx(int idx) | 
| 221 | unsigned short int _idx; | 
| 222 | OBNodeBase        *_bgn;     //!< I connect one node | 
| 223 | OBNodeBase        *_end;     //!< to another node | 
| 224 | //! To which graph do I belong?       GetParent(), SetParent(OBGraphBase*). | 
| 225 | OBGraphBase       *_parent; | 
| 226 | public: | 
| 227 | bool Visit; | 
| 228 |  | 
| 229 | //! Constructor | 
| 230 | OBEdgeBase() | 
| 231 | { | 
| 232 | Visit = false; | 
| 233 | _bgn = _end = NULL; | 
| 234 | } | 
| 235 | //! Constructor (populate from two OBNodeBase objects) | 
| 236 | OBEdgeBase(OBNodeBase *bgn,OBNodeBase *end) | 
| 237 | {} | 
| 238 | //! Destructor | 
| 239 | virtual ~OBEdgeBase() | 
| 240 | {} | 
| 241 |  | 
| 242 | virtual OBGraphBase* GetParent() | 
| 243 | { | 
| 244 | return(_parent); | 
| 245 | } | 
| 246 | void SetParent(OBGraphBase*); | 
| 247 | unsigned int GetIdx() | 
| 248 | { | 
| 249 | return(_idx); | 
| 250 | } | 
| 251 | void SetIdx(int idx) | 
| 252 | { | 
| 253 | _idx = idx; | 
| 254 | } | 
| 255 | void SetBgn(OBNodeBase *n) | 
| 256 | { | 
| 257 | _bgn = n; | 
| 258 | } | 
| 259 | void SetEnd(OBNodeBase *n) | 
| 260 | { | 
| 261 | _end = n; | 
| 262 | } | 
| 263 | void SwapEnds() | 
| 264 | { | 
| 265 | std::swap(_bgn,_end); | 
| 266 | } | 
| 267 | OBNodeBase *GetBgn() | 
| 268 | { | 
| 269 | return(_bgn); | 
| 270 | } | 
| 271 | OBNodeBase *GetEnd() | 
| 272 | { | 
| 273 | return(_end); | 
| 274 | } | 
| 275 |  | 
| 276 | void Error(int f) | 
| 277 | { | 
| 278 | std::cerr << "bond vf err = " << f << std::endl; | 
| 279 | } | 
| 280 | /**  \name Nonfunctional members | 
| 281 | Nonfunctional or unused members of OpenBabel::OBEdgeBase | 
| 282 | are to be added by a derived class (e.g., OpenBabel::OBBond) | 
| 283 | @{ | 
| 284 | */ | 
| 285 | virtual void SetClosure() | 
| 286 | {} | 
| 287 | virtual bool IsAromatic()      const | 
| 288 | { | 
| 289 | ((OBEdgeBase*)this)->Error(1); | 
| 290 | return(false); | 
| 291 | } | 
| 292 | virtual bool IsInRing()        const | 
| 293 | { | 
| 294 | ((OBEdgeBase*)this)->Error(2); | 
| 295 | return(false); | 
| 296 | } | 
| 297 | virtual bool IsClosure() | 
| 298 | { | 
| 299 | ((OBEdgeBase*)this)->Error(3); | 
| 300 | return(false); | 
| 301 | } | 
| 302 | virtual bool Eval(OBEdgeBase*) | 
| 303 | { | 
| 304 | ((OBEdgeBase*)this)->Error(4); | 
| 305 | return(false); | 
| 306 | } | 
| 307 | virtual unsigned int  GetBO()  const | 
| 308 | { | 
| 309 | ((OBEdgeBase*)this)->Error(5); | 
| 310 | return(0); | 
| 311 | } | 
| 312 | //@} | 
| 313 | }; | 
| 314 |  | 
| 315 | /*! \brief Graph Base Class | 
| 316 |  | 
| 317 | The base class for graphs (e.g. rings, molecules, etc.) in a | 
| 318 | graph-theoretical representation. | 
| 319 | */ | 
| 320 | class OBAPI OBGraphBase : public OBBase | 
| 321 | { | 
| 322 | protected: | 
| 323 | bool                 _vlock; | 
| 324 | std::vector<OBNodeBase*>  _vatom; | 
| 325 | std::vector<OBEdgeBase*>  _vbond; | 
| 326 | public: | 
| 327 | OBGraphBase() | 
| 328 | { | 
| 329 | _vlock = false; | 
| 330 | _vatom.clear(); | 
| 331 | _vbond.clear(); | 
| 332 | } | 
| 333 | OBGraphBase(const OBGraphBase &src) : OBBase() { } | 
| 334 | virtual     ~OBGraphBase()          { } | 
| 335 | unsigned int NumNodes() | 
| 336 | { | 
| 337 | return(_vatom.empty() ? 0 : _vatom.size()); | 
| 338 | } | 
| 339 | unsigned int NumEdges() | 
| 340 | { | 
| 341 | return(_vbond.empty() ? 0 : _vbond.size()); | 
| 342 | } | 
| 343 | void        ResetVisitFlags(); | 
| 344 | bool        SetVisitLock(bool); | 
| 345 | bool        GetVisitLock() | 
| 346 | { | 
| 347 | return(_vlock); | 
| 348 | } | 
| 349 | OBNodeBase *Begin(std::vector<OBNodeBase*>::iterator&); | 
| 350 | OBNodeBase *Next(std::vector<OBNodeBase*>::iterator&); | 
| 351 | OBEdgeBase *Begin(std::vector<OBEdgeBase*>::iterator&); | 
| 352 | OBEdgeBase *Next(std::vector<OBEdgeBase*>::iterator&); | 
| 353 |  | 
| 354 | /*The following (placeholder) routines removed to avoid finding solution to | 
| 355 | iterators being illegally returned as NULL | 
| 356 | //substructure search functions | 
| 357 | virtual bool SingleMatch()                  const | 
| 358 | { | 
| 359 | return(false); | 
| 360 | } | 
| 361 | virtual void SetSingleMatch(bool) | 
| 362 | {} | 
| 363 | virtual bool FinishedMatch()                const | 
| 364 | { | 
| 365 | return(false); | 
| 366 | } | 
| 367 | virtual void SetFinishedMatch(bool) | 
| 368 | {} | 
| 369 | virtual void ClearMatches() | 
| 370 | {} | 
| 371 | virtual void PushBack(std::vector<OBNodeBase*>&) | 
| 372 | {} | 
| 373 | virtual void PrepForMatch() | 
| 374 | {} | 
| 375 | virtual std::vector<std::pair<OBNodeBase*,std::vector<OBEdgeBase*> > >::iterator BgnMatch() | 
| 376 | { | 
| 377 | return((std::vector<std::pair<OBNodeBase*,std::vector<OBEdgeBase*> > >::iterator) NULL); | 
| 378 | } | 
| 379 | virtual std::vector<std::pair<OBNodeBase*,std::vector<OBEdgeBase*> > >::iterator EndMatch() | 
| 380 | { | 
| 381 | return((std::vector<std::pair<OBNodeBase*,std::vector<OBEdgeBase*> > >::iterator) NULL); | 
| 382 | } | 
| 383 | virtual OBNodeBase *GetFirstSeed() | 
| 384 | { | 
| 385 | return((OBNodeBase*)NULL); | 
| 386 | } | 
| 387 | bool Match(OBGraphBase &,bool singleMatch=false); | 
| 388 | bool Match(OBGraphBase &, | 
| 389 | std::vector<std::pair<OBNodeBase*,std::vector<OBEdgeBase*> > >::iterator, | 
| 390 | std::vector<OBEdgeBase*>::iterator); | 
| 391 | */ | 
| 392 | }; | 
| 393 |  | 
| 394 | } //namespace OpenBabel | 
| 395 |  | 
| 396 | #endif // OB_BASE_H | 
| 397 |  | 
| 398 | //! \file base.h | 
| 399 | //! \brief Base classes to build a graph |