// $Id$ // // Copyright (C) 2002-2006 Greg Landrum and Rational Discovery LLC // // @@ 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 "AtomIterators.h" #include "RDKitBase.h" #include "RDKitQueries.h" namespace RDKit{ template AtomIterator_::AtomIterator_(Mol_ * mol) { _mol = mol; _pos = 0; _max = mol->getNumAtoms(); }; template AtomIterator_::AtomIterator_(Mol_ * mol,int pos) { _mol = mol; _pos = pos; _max = mol->getNumAtoms(); }; template AtomIterator_::AtomIterator_(const AtomIterator_ &other){ _mol = other._mol; _pos = other._pos; _max = other._max; } template AtomIterator_ &AtomIterator_::operator=(const AtomIterator_ &other){ _mol = other._mol; _pos = other._pos; _max = other._max; return *this; } template AtomIterator_ &AtomIterator_::operator+=(int val){ _pos += val; if(_pos<0 || _pos>_max) _pos = _max; return *this; } template AtomIterator_ &AtomIterator_::operator-=(int val){ _pos -= val; if(_pos<0 || _pos>_max) _pos = _max; return *this; } template AtomIterator_ AtomIterator_::operator+(int val) const { AtomIterator_ res(*this); res += val; // += takes care of the pre/post conditions for us, so we're safe to return return res; } template AtomIterator_ AtomIterator_::operator-(int val) const { AtomIterator_ res(*this); // -= takes care of the pre/post conditions for us, so we're safe to return res -= val; return res; } // iterator subtraction template int AtomIterator_::operator-(AtomIterator_ &other) const { PRECONDITION(_mol==other._mol,"bad operator- call"); return _pos - other._pos; } // dereference template Atom_ * AtomIterator_::operator*() const { RANGE_CHECK(0,_pos,_max-1); return (*_mol)[_pos].get(); } // random access template Atom_ * AtomIterator_::operator[](const int which) const { RANGE_CHECK(0,which,_max-1); return (*_mol)[which].get(); } template bool AtomIterator_::operator==(const AtomIterator_ &other) const { return _mol==other._mol && _pos==other._pos; } template bool AtomIterator_::operator!=(const AtomIterator_ &other) const { return _mol!=other._mol || _pos!=other._pos; } template bool AtomIterator_::operator<(const AtomIterator_ &other) const { return _mol==other._mol && _pos bool AtomIterator_::operator<=(const AtomIterator_ &other) const { return _mol==other._mol && _pos<=other._pos; } template bool AtomIterator_::operator>(const AtomIterator_ &other) const { return _mol==other._mol && _pos>other._pos; } template bool AtomIterator_::operator>=(const AtomIterator_ &other) const { return _mol==other._mol && _pos>=other._pos; } // pre-increment template AtomIterator_ &AtomIterator_::operator++() { _pos++; return *this; } template AtomIterator_ AtomIterator_::operator++(int) { AtomIterator_ res(*this); _pos++; return res; } // pre-decrement template AtomIterator_ &AtomIterator_::operator--() { _pos--; return *this; } template AtomIterator_ AtomIterator_::operator--(int) { AtomIterator_ res(*this); if(_pos-1 < 0) _pos = _max; else _pos--; return res; } //----------------------------------------- // // HeteroatomIterator // //----------------------------------------- template HeteroatomIterator_::HeteroatomIterator_(Mol_ * mol){ _mol = mol; _qA = new QueryAtom(6); _qA->getQuery()->setNegation(true); _end = mol->getNumAtoms(); _pos = _findNext(0); }; template HeteroatomIterator_::HeteroatomIterator_(Mol_ * mol,int pos){ _mol = mol; _qA = new QueryAtom(6); _end = mol->getNumAtoms(); _pos = pos; }; template HeteroatomIterator_::~HeteroatomIterator_() { delete _qA; _qA=NULL; } template HeteroatomIterator_::HeteroatomIterator_(const ThisType &other){ _mol = other._mol; _end = other._end; _pos = other._pos; _qA = static_cast(other._qA->copy()); } template HeteroatomIterator_ &HeteroatomIterator_::operator=(const ThisType &other){ _mol = other._mol; _end = other._end; _pos = other._pos; _qA = static_cast(other._qA->copy()); return *this; } template bool HeteroatomIterator_::operator==(const ThisType &other) const{ return _mol==other._mol && _pos==other._pos; } template bool HeteroatomIterator_::operator!=(const ThisType &other) const{ return _mol!=other._mol || _pos!=other._pos; } template Atom_ * HeteroatomIterator_::operator*() const{ return (*_mol)[_pos].get(); } // pre-increment template HeteroatomIterator_ &HeteroatomIterator_::operator++() { _pos = _findNext(_pos+1); return *this; } template HeteroatomIterator_ HeteroatomIterator_::operator++(int) { HeteroatomIterator_ res(*this); _pos = _findNext(_pos+1); return res; } // pre-decrement template HeteroatomIterator_ &HeteroatomIterator_::operator--() { _pos = _findPrev(_pos-1); return *this; } template HeteroatomIterator_ HeteroatomIterator_::operator--(int) { HeteroatomIterator_ res(*this); _pos = _findPrev(_pos-1); return res; } template int HeteroatomIterator_::_findNext(int from){ while(from<_end){ if(_qA->Match((*_mol)[from])) break; else from++; } return from; } template int HeteroatomIterator_::_findPrev(int from){ while(from>0){ if(_qA->Match((*_mol)[from])) break; else from--; } if(from<0) from = _end; return from; } //----------------------------------------- // // AromaticAtomIterator // //----------------------------------------- template AromaticAtomIterator_::AromaticAtomIterator_(Mol_ * mol){ _mol = mol; _end = mol->getNumAtoms(); _pos = _findNext(0); }; template AromaticAtomIterator_::AromaticAtomIterator_(Mol_ * mol,int pos){ _mol = mol; _end = mol->getNumAtoms(); _pos = pos; }; template AromaticAtomIterator_::~AromaticAtomIterator_() { } template AromaticAtomIterator_::AromaticAtomIterator_(const ThisType &other){ _mol = other._mol; _end = other._end; _pos = other._pos; } template AromaticAtomIterator_ &AromaticAtomIterator_::operator=(const ThisType &other){ _mol = other._mol; _end = other._end; _pos = other._pos; return *this; } template bool AromaticAtomIterator_::operator==(const ThisType &other) const{ return _mol==other._mol && _pos==other._pos; } template bool AromaticAtomIterator_::operator!=(const ThisType &other) const{ return _mol!=other._mol || _pos!=other._pos; } template Atom_ * AromaticAtomIterator_::operator*() const { return (*_mol)[_pos].get(); } // pre-increment template AromaticAtomIterator_ &AromaticAtomIterator_::operator++() { _pos = _findNext(_pos+1); return *this; } template AromaticAtomIterator_ AromaticAtomIterator_::operator++(int) { AromaticAtomIterator_ res(*this); _pos = _findNext(_pos+1); return res; } // pre-decrement template AromaticAtomIterator_ &AromaticAtomIterator_::operator--() { _pos = _findPrev(_pos-1); return *this; } template AromaticAtomIterator_ AromaticAtomIterator_::operator--(int) { AromaticAtomIterator_ res(*this); _pos = _findPrev(_pos-1); return res; } template int AromaticAtomIterator_::_findNext(int from){ while(from<_end){ if((*_mol)[from]->getIsAromatic()) break; else from++; } return from; } template int AromaticAtomIterator_::_findPrev(int from){ while(from>0){ if((*_mol)[from]->getIsAromatic()) break; else from--; } if(from<0) from = _end; return from; } //----------------------------------------- // // QueryAtomIterator // //----------------------------------------- template QueryAtomIterator_::QueryAtomIterator_(Mol_ * mol,QueryAtom const *what){ PRECONDITION(what,"bad query atom"); _mol = mol; _qA = static_cast(what->copy()); _end = mol->getNumAtoms(); _pos = _findNext(0); }; template QueryAtomIterator_::QueryAtomIterator_(Mol_ * mol,int pos){ _mol = mol; _qA = NULL; _end = mol->getNumAtoms(); _pos = pos; }; template QueryAtomIterator_::~QueryAtomIterator_() { delete _qA; _qA=NULL; } template QueryAtomIterator_::QueryAtomIterator_(const QueryAtomIterator_ &other){ _mol = other._mol; _pos = other._pos; _end = other._end; if(other._qA) _qA = static_cast(other._qA->copy()); else _qA = NULL; } template QueryAtomIterator_ & QueryAtomIterator_::operator =(const QueryAtomIterator_ &other){ if(this!=&other){ _mol = other._mol; _pos = other._pos; _end = other._end; delete _qA; if(other._qA) _qA = static_cast(other._qA->copy()); else _qA = NULL; } return *this; } template bool QueryAtomIterator_::operator==(const QueryAtomIterator_ &other) const{ return _mol==other._mol && _pos==other._pos; } template bool QueryAtomIterator_::operator!=(const QueryAtomIterator_ &other) const{ return _mol!=other._mol || _pos!=other._pos; } template Atom_ * QueryAtomIterator_::operator*() const { PRECONDITION(_mol!=NULL,"no molecule"); return (*_mol)[_pos].get(); } // pre-increment template QueryAtomIterator_ &QueryAtomIterator_::operator++() { _pos = _findNext(_pos+1); return *this; } template QueryAtomIterator_ QueryAtomIterator_::operator++(int) { QueryAtomIterator_ res(*this); _pos = _findNext(_pos+1); return res; } // pre-decrement template QueryAtomIterator_ &QueryAtomIterator_::operator--() { _pos = _findPrev(_pos-1); return *this; } template QueryAtomIterator_ QueryAtomIterator_::operator--(int) { QueryAtomIterator_ res(*this); _pos = _findPrev(_pos-1); return res; } template int QueryAtomIterator_::_findNext(int from){ PRECONDITION(_mol!=NULL,"no molecule"); PRECONDITION(_qA!=NULL,"no query set"); while(from<_end){ if(_qA->Match((*_mol)[from])) break; else from++; } return from; } template int QueryAtomIterator_::_findPrev(int from){ PRECONDITION(_mol!=NULL,"no molecule"); PRECONDITION(_qA!=NULL,"no query set"); while(from>0){ if(_qA->Match((*_mol)[from])) break; else from--; } if(from<0) from = _end; return from; } //----------------------------------------- // // MatchingAtomIterator // //----------------------------------------- template MatchingAtomIterator_::MatchingAtomIterator_(Mol_ * mol,bool (*fn)(Atom_ *)){ PRECONDITION(fn,"bad query function"); _mol = mol; _qF = fn; _end = mol->getNumAtoms(); _pos = _findNext(0); }; template MatchingAtomIterator_::MatchingAtomIterator_(Mol_ * mol,int pos){ _mol = mol; _qF = NULL; _end = mol->getNumAtoms(); _pos = pos; }; template MatchingAtomIterator_::~MatchingAtomIterator_() {} template MatchingAtomIterator_::MatchingAtomIterator_(const MatchingAtomIterator_ &other){ _mol = other._mol; _pos = other._pos; _end = other._end; _qF = other._qF; } template MatchingAtomIterator_ & MatchingAtomIterator_::operator =(const MatchingAtomIterator_ &other){ if(this!=&other){ _mol = other._mol; _pos = other._pos; _end = other._end; _qF = other._qF; } return *this; } template bool MatchingAtomIterator_::operator==(const MatchingAtomIterator_ &other) const{ return _mol==other._mol && _pos==other._pos; } template bool MatchingAtomIterator_::operator!=(const MatchingAtomIterator_ &other) const{ return _mol!=other._mol || _pos!=other._pos; } template Atom_ * MatchingAtomIterator_::operator*() const { PRECONDITION(_mol!=NULL,"no molecule"); return (*_mol)[_pos].get(); } // pre-increment template MatchingAtomIterator_ &MatchingAtomIterator_::operator++() { _pos = _findNext(_pos+1); return *this; } template MatchingAtomIterator_ MatchingAtomIterator_::operator++(int) { MatchingAtomIterator_ res(*this); _pos = _findNext(_pos+1); return res; } // pre-decrement template MatchingAtomIterator_ &MatchingAtomIterator_::operator--() { _pos = _findPrev(_pos-1); return *this; } template MatchingAtomIterator_ MatchingAtomIterator_::operator--(int) { MatchingAtomIterator_ res(*this); _pos = _findPrev(_pos-1); return res; } template int MatchingAtomIterator_::_findNext(int from){ PRECONDITION(_mol!=NULL,"no molecule"); PRECONDITION(_qF!=NULL,"no query set"); while(from<_end){ if(_qF((*_mol)[from].get())) break; else ++from; } return from; } template int MatchingAtomIterator_::_findPrev(int from){ PRECONDITION(_mol!=NULL,"no molecule"); PRECONDITION(_qF!=NULL,"no query set"); while(from>0){ if(_qF((*_mol)[from].get())) break; else --from; } if(from<0) from = _end; return from; } template class AtomIterator_; template class AtomIterator_; template class AromaticAtomIterator_; template class AromaticAtomIterator_; template class HeteroatomIterator_; template class HeteroatomIterator_; template class QueryAtomIterator_; template class QueryAtomIterator_; template class MatchingAtomIterator_; template class MatchingAtomIterator_; }; // end o' namespace