1 //
2 // Copyright (C) 2002-2017 Greg Landrum and Rational Discovery LLC
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 "AtomIterators.h"
11 #include "RDKitBase.h"
12 #include "RDKitQueries.h"
13
14 namespace RDKit {
15 template <class Atom_, class Mol_>
AtomIterator_(Mol_ * mol)16 AtomIterator_<Atom_, Mol_>::AtomIterator_(Mol_ *mol) {
17 _mol = mol;
18 _pos = 0;
19 _max = mol->getNumAtoms();
20 };
21 template <class Atom_, class Mol_>
AtomIterator_(Mol_ * mol,int pos)22 AtomIterator_<Atom_, Mol_>::AtomIterator_(Mol_ *mol, int pos) {
23 _mol = mol;
24 _pos = pos;
25 _max = mol->getNumAtoms();
26 };
27 template <class Atom_, class Mol_>
AtomIterator_(const AtomIterator_<Atom_,Mol_> & other)28 AtomIterator_<Atom_, Mol_>::AtomIterator_(
29 const AtomIterator_<Atom_, Mol_> &other) {
30 _mol = other._mol;
31 _pos = other._pos;
32 _max = other._max;
33 }
34 template <class Atom_, class Mol_>
operator =(const AtomIterator_<Atom_,Mol_> & other)35 AtomIterator_<Atom_, Mol_> &AtomIterator_<Atom_, Mol_>::operator=(
36 const AtomIterator_<Atom_, Mol_> &other) {
37 _mol = other._mol;
38 _pos = other._pos;
39 _max = other._max;
40 return *this;
41 }
42
43 template <class Atom_, class Mol_>
operator +=(int val)44 AtomIterator_<Atom_, Mol_> &AtomIterator_<Atom_, Mol_>::operator+=(int val) {
45 _pos += val;
46 if (_pos < 0 || _pos > _max) {
47 _pos = _max;
48 }
49 return *this;
50 }
51 template <class Atom_, class Mol_>
operator -=(int val)52 AtomIterator_<Atom_, Mol_> &AtomIterator_<Atom_, Mol_>::operator-=(int val) {
53 _pos -= val;
54 if (_pos < 0 || _pos > _max) {
55 _pos = _max;
56 }
57 return *this;
58 }
59 template <class Atom_, class Mol_>
operator +(int val) const60 AtomIterator_<Atom_, Mol_> AtomIterator_<Atom_, Mol_>::operator+(
61 int val) const {
62 AtomIterator_<Atom_, Mol_> res(*this);
63 res += val;
64 // += takes care of the pre/post conditions for us, so we're safe to return
65 return res;
66 }
67 template <class Atom_, class Mol_>
operator -(int val) const68 AtomIterator_<Atom_, Mol_> AtomIterator_<Atom_, Mol_>::operator-(
69 int val) const {
70 AtomIterator_<Atom_, Mol_> res(*this);
71 // -= takes care of the pre/post conditions for us, so we're safe to return
72 res -= val;
73 return res;
74 }
75
76 // iterator subtraction
77 template <class Atom_, class Mol_>
operator -(AtomIterator_<Atom_,Mol_> & other) const78 int AtomIterator_<Atom_, Mol_>::operator-(
79 AtomIterator_<Atom_, Mol_> &other) const {
80 PRECONDITION(_mol == other._mol, "bad operator- call");
81 return _pos - other._pos;
82 }
83
84 // dereference
85 template <class Atom_, class Mol_>
86 Atom_ *AtomIterator_<Atom_, Mol_>::operator*() const {
87 PRECONDITION(_mol != nullptr, "no molecule");
88 RANGE_CHECK(0, _pos, _max - 1);
89 return (*_mol)[_pos];
90 }
91 // random access
92 template <class Atom_, class Mol_>
93 Atom_ *AtomIterator_<Atom_, Mol_>::operator[](const int which) const {
94 PRECONDITION(_mol != nullptr, "no molecule");
95 RANGE_CHECK(0, which, _max - 1);
96 return (*_mol)[which];
97 }
98
99 template <class Atom_, class Mol_>
operator ==(const AtomIterator_<Atom_,Mol_> & other) const100 bool AtomIterator_<Atom_, Mol_>::operator==(
101 const AtomIterator_<Atom_, Mol_> &other) const {
102 return _mol == other._mol && _pos == other._pos;
103 }
104 template <class Atom_, class Mol_>
operator !=(const AtomIterator_<Atom_,Mol_> & other) const105 bool AtomIterator_<Atom_, Mol_>::operator!=(
106 const AtomIterator_<Atom_, Mol_> &other) const {
107 return _mol != other._mol || _pos != other._pos;
108 }
109 template <class Atom_, class Mol_>
operator <(const AtomIterator_<Atom_,Mol_> & other) const110 bool AtomIterator_<Atom_, Mol_>::operator<(
111 const AtomIterator_<Atom_, Mol_> &other) const {
112 return _mol == other._mol && _pos < other._pos;
113 }
114 template <class Atom_, class Mol_>
operator <=(const AtomIterator_<Atom_,Mol_> & other) const115 bool AtomIterator_<Atom_, Mol_>::operator<=(
116 const AtomIterator_<Atom_, Mol_> &other) const {
117 return _mol == other._mol && _pos <= other._pos;
118 }
119 template <class Atom_, class Mol_>
operator >(const AtomIterator_<Atom_,Mol_> & other) const120 bool AtomIterator_<Atom_, Mol_>::operator>(
121 const AtomIterator_<Atom_, Mol_> &other) const {
122 return _mol == other._mol && _pos > other._pos;
123 }
124 template <class Atom_, class Mol_>
operator >=(const AtomIterator_<Atom_,Mol_> & other) const125 bool AtomIterator_<Atom_, Mol_>::operator>=(
126 const AtomIterator_<Atom_, Mol_> &other) const {
127 return _mol == other._mol && _pos >= other._pos;
128 }
129
130 // pre-increment
131 template <class Atom_, class Mol_>
operator ++()132 AtomIterator_<Atom_, Mol_> &AtomIterator_<Atom_, Mol_>::operator++() {
133 _pos++;
134 return *this;
135 }
136 template <class Atom_, class Mol_>
operator ++(int)137 AtomIterator_<Atom_, Mol_> AtomIterator_<Atom_, Mol_>::operator++(int) {
138 AtomIterator_<Atom_, Mol_> res(*this);
139 _pos++;
140 return res;
141 }
142 // pre-decrement
143 template <class Atom_, class Mol_>
operator --()144 AtomIterator_<Atom_, Mol_> &AtomIterator_<Atom_, Mol_>::operator--() {
145 _pos--;
146 return *this;
147 }
148 template <class Atom_, class Mol_>
operator --(int)149 AtomIterator_<Atom_, Mol_> AtomIterator_<Atom_, Mol_>::operator--(int) {
150 AtomIterator_<Atom_, Mol_> res(*this);
151 if (_pos - 1 < 0) {
152 _pos = _max;
153 } else {
154 _pos--;
155 }
156 return res;
157 }
158
159 //-----------------------------------------
160 //
161 // HeteroatomIterator
162 //
163 //-----------------------------------------
164 template <class Atom_, class Mol_>
HeteroatomIterator_(Mol_ * mol)165 HeteroatomIterator_<Atom_, Mol_>::HeteroatomIterator_(Mol_ *mol) {
166 _mol = mol;
167 _qA = new QueryAtom(6);
168 _qA->getQuery()->setNegation(true);
169 _end = mol->getNumAtoms();
170 _pos = _findNext(0);
171 };
172 template <class Atom_, class Mol_>
HeteroatomIterator_(Mol_ * mol,int pos)173 HeteroatomIterator_<Atom_, Mol_>::HeteroatomIterator_(Mol_ *mol, int pos) {
174 _mol = mol;
175 _qA = new QueryAtom(6);
176 _end = mol->getNumAtoms();
177 _pos = pos;
178 };
179
180 template <class Atom_, class Mol_>
~HeteroatomIterator_()181 HeteroatomIterator_<Atom_, Mol_>::~HeteroatomIterator_() {
182 delete _qA;
183 _qA = nullptr;
184 }
185
186 template <class Atom_, class Mol_>
HeteroatomIterator_(const ThisType & other)187 HeteroatomIterator_<Atom_, Mol_>::HeteroatomIterator_(const ThisType &other) {
188 _mol = other._mol;
189 _end = other._end;
190 _pos = other._pos;
191 _qA = static_cast<QueryAtom *>(other._qA->copy());
192 }
193
194 template <class Atom_, class Mol_>
operator =(const ThisType & other)195 HeteroatomIterator_<Atom_, Mol_> &HeteroatomIterator_<Atom_, Mol_>::operator=(
196 const ThisType &other) {
197 _mol = other._mol;
198 _end = other._end;
199 _pos = other._pos;
200 _qA = static_cast<QueryAtom *>(other._qA->copy());
201 return *this;
202 }
203
204 template <class Atom_, class Mol_>
operator ==(const ThisType & other) const205 bool HeteroatomIterator_<Atom_, Mol_>::operator==(const ThisType &other) const {
206 return _mol == other._mol && _pos == other._pos;
207 }
208 template <class Atom_, class Mol_>
operator !=(const ThisType & other) const209 bool HeteroatomIterator_<Atom_, Mol_>::operator!=(const ThisType &other) const {
210 return _mol != other._mol || _pos != other._pos;
211 }
212
213 template <class Atom_, class Mol_>
214 Atom_ *HeteroatomIterator_<Atom_, Mol_>::operator*() const {
215 PRECONDITION(_mol != nullptr, "no molecule");
216 return (*_mol)[_pos];
217 }
218 // pre-increment
219 template <class Atom_, class Mol_>
220 HeteroatomIterator_<Atom_, Mol_>
operator ++()221 &HeteroatomIterator_<Atom_, Mol_>::operator++() {
222 _pos = _findNext(_pos + 1);
223 return *this;
224 }
225 template <class Atom_, class Mol_>
operator ++(int)226 HeteroatomIterator_<Atom_, Mol_> HeteroatomIterator_<Atom_, Mol_>::operator++(
227 int) {
228 HeteroatomIterator_<Atom_, Mol_> res(*this);
229 _pos = _findNext(_pos + 1);
230 return res;
231 }
232 // pre-decrement
233 template <class Atom_, class Mol_>
234 HeteroatomIterator_<Atom_, Mol_>
operator --()235 &HeteroatomIterator_<Atom_, Mol_>::operator--() {
236 _pos = _findPrev(_pos - 1);
237 return *this;
238 }
239 template <class Atom_, class Mol_>
operator --(int)240 HeteroatomIterator_<Atom_, Mol_> HeteroatomIterator_<Atom_, Mol_>::operator--(
241 int) {
242 HeteroatomIterator_<Atom_, Mol_> res(*this);
243 _pos = _findPrev(_pos - 1);
244 return res;
245 }
246 template <class Atom_, class Mol_>
_findNext(int from)247 int HeteroatomIterator_<Atom_, Mol_>::_findNext(int from) {
248 while (from < _end) {
249 if (_qA->Match((*_mol)[from])) {
250 break;
251 } else {
252 from++;
253 }
254 }
255 return from;
256 }
257
258 template <class Atom_, class Mol_>
_findPrev(int from)259 int HeteroatomIterator_<Atom_, Mol_>::_findPrev(int from) {
260 while (from > 0) {
261 if (_qA->Match((*_mol)[from])) {
262 break;
263 } else {
264 from--;
265 }
266 }
267 if (from < 0) {
268 from = _end;
269 }
270 return from;
271 }
272
273 //-----------------------------------------
274 //
275 // AromaticAtomIterator
276 //
277 //-----------------------------------------
278 template <class Atom_, class Mol_>
AromaticAtomIterator_(Mol_ * mol)279 AromaticAtomIterator_<Atom_, Mol_>::AromaticAtomIterator_(Mol_ *mol) {
280 _mol = mol;
281 _end = mol->getNumAtoms();
282 _pos = _findNext(0);
283 };
284 template <class Atom_, class Mol_>
AromaticAtomIterator_(Mol_ * mol,int pos)285 AromaticAtomIterator_<Atom_, Mol_>::AromaticAtomIterator_(Mol_ *mol, int pos) {
286 _mol = mol;
287 _end = mol->getNumAtoms();
288 _pos = pos;
289 };
290
291 template <class Atom_, class Mol_>
~AromaticAtomIterator_()292 AromaticAtomIterator_<Atom_, Mol_>::~AromaticAtomIterator_() {}
293
294 template <class Atom_, class Mol_>
AromaticAtomIterator_(const ThisType & other)295 AromaticAtomIterator_<Atom_, Mol_>::AromaticAtomIterator_(
296 const ThisType &other) {
297 _mol = other._mol;
298 _end = other._end;
299 _pos = other._pos;
300 }
301
302 template <class Atom_, class Mol_>
303 AromaticAtomIterator_<Atom_, Mol_>
operator =(const ThisType & other)304 &AromaticAtomIterator_<Atom_, Mol_>::operator=(const ThisType &other) {
305 _mol = other._mol;
306 _end = other._end;
307 _pos = other._pos;
308 return *this;
309 }
310
311 template <class Atom_, class Mol_>
operator ==(const ThisType & other) const312 bool AromaticAtomIterator_<Atom_, Mol_>::operator==(
313 const ThisType &other) const {
314 return _mol == other._mol && _pos == other._pos;
315 }
316 template <class Atom_, class Mol_>
operator !=(const ThisType & other) const317 bool AromaticAtomIterator_<Atom_, Mol_>::operator!=(
318 const ThisType &other) const {
319 return _mol != other._mol || _pos != other._pos;
320 }
321
322 template <class Atom_, class Mol_>
323 Atom_ *AromaticAtomIterator_<Atom_, Mol_>::operator*() const {
324 PRECONDITION(_mol != nullptr, "no molecule");
325 return (*_mol)[_pos];
326 }
327 // pre-increment
328 template <class Atom_, class Mol_>
329 AromaticAtomIterator_<Atom_, Mol_>
operator ++()330 &AromaticAtomIterator_<Atom_, Mol_>::operator++() {
331 _pos = _findNext(_pos + 1);
332 return *this;
333 }
334 template <class Atom_, class Mol_>
335 AromaticAtomIterator_<Atom_, Mol_> AromaticAtomIterator_<Atom_, Mol_>::
operator ++(int)336 operator++(int) {
337 AromaticAtomIterator_<Atom_, Mol_> res(*this);
338 _pos = _findNext(_pos + 1);
339 return res;
340 }
341 // pre-decrement
342 template <class Atom_, class Mol_>
343 AromaticAtomIterator_<Atom_, Mol_>
operator --()344 &AromaticAtomIterator_<Atom_, Mol_>::operator--() {
345 _pos = _findPrev(_pos - 1);
346 return *this;
347 }
348 template <class Atom_, class Mol_>
349 AromaticAtomIterator_<Atom_, Mol_> AromaticAtomIterator_<Atom_, Mol_>::
operator --(int)350 operator--(int) {
351 AromaticAtomIterator_<Atom_, Mol_> res(*this);
352 _pos = _findPrev(_pos - 1);
353 return res;
354 }
355 template <class Atom_, class Mol_>
_findNext(int from)356 int AromaticAtomIterator_<Atom_, Mol_>::_findNext(int from) {
357 while (from < _end) {
358 if ((*_mol)[from]->getIsAromatic()) {
359 break;
360 } else {
361 from++;
362 }
363 }
364 return from;
365 }
366
367 template <class Atom_, class Mol_>
_findPrev(int from)368 int AromaticAtomIterator_<Atom_, Mol_>::_findPrev(int from) {
369 while (from > 0) {
370 if ((*_mol)[from]->getIsAromatic()) {
371 break;
372 } else {
373 from--;
374 }
375 }
376 if (from < 0) {
377 from = _end;
378 }
379 return from;
380 }
381
382 //-----------------------------------------
383 //
384 // QueryAtomIterator
385 //
386 //-----------------------------------------
387 template <class Atom_, class Mol_>
QueryAtomIterator_(Mol_ * mol,QueryAtom const * what)388 QueryAtomIterator_<Atom_, Mol_>::QueryAtomIterator_(Mol_ *mol,
389 QueryAtom const *what) {
390 PRECONDITION(what, "bad query atom");
391 _mol = mol;
392 _qA = static_cast<QueryAtom *>(what->copy());
393 _end = mol->getNumAtoms();
394 _pos = _findNext(0);
395 };
396 template <class Atom_, class Mol_>
QueryAtomIterator_(Mol_ * mol,int pos)397 QueryAtomIterator_<Atom_, Mol_>::QueryAtomIterator_(Mol_ *mol, int pos) {
398 _mol = mol;
399 _qA = nullptr;
400 _end = mol->getNumAtoms();
401 _pos = pos;
402 };
403 template <class Atom_, class Mol_>
~QueryAtomIterator_()404 QueryAtomIterator_<Atom_, Mol_>::~QueryAtomIterator_() {
405 delete _qA;
406 _qA = nullptr;
407 }
408 template <class Atom_, class Mol_>
QueryAtomIterator_(const QueryAtomIterator_<Atom_,Mol_> & other)409 QueryAtomIterator_<Atom_, Mol_>::QueryAtomIterator_(
410 const QueryAtomIterator_<Atom_, Mol_> &other) {
411 _mol = other._mol;
412 _pos = other._pos;
413 _end = other._end;
414 if (other._qA) {
415 _qA = static_cast<QueryAtom *>(other._qA->copy());
416 } else {
417 _qA = nullptr;
418 }
419 }
420
421 template <class Atom_, class Mol_>
operator =(const QueryAtomIterator_<Atom_,Mol_> & other)422 QueryAtomIterator_<Atom_, Mol_> &QueryAtomIterator_<Atom_, Mol_>::operator=(
423 const QueryAtomIterator_<Atom_, Mol_> &other) {
424 if (this != &other) {
425 _mol = other._mol;
426 _pos = other._pos;
427 _end = other._end;
428 delete _qA;
429 if (other._qA) {
430 _qA = static_cast<QueryAtom *>(other._qA->copy());
431 } else {
432 _qA = nullptr;
433 }
434 }
435 return *this;
436 }
437 template <class Atom_, class Mol_>
operator ==(const QueryAtomIterator_<Atom_,Mol_> & other) const438 bool QueryAtomIterator_<Atom_, Mol_>::operator==(
439 const QueryAtomIterator_<Atom_, Mol_> &other) const {
440 return _mol == other._mol && _pos == other._pos;
441 }
442 template <class Atom_, class Mol_>
operator !=(const QueryAtomIterator_<Atom_,Mol_> & other) const443 bool QueryAtomIterator_<Atom_, Mol_>::operator!=(
444 const QueryAtomIterator_<Atom_, Mol_> &other) const {
445 return _mol != other._mol || _pos != other._pos;
446 }
447
448 template <class Atom_, class Mol_>
449 Atom_ *QueryAtomIterator_<Atom_, Mol_>::operator*() const {
450 PRECONDITION(_mol != nullptr, "no molecule");
451 return (*_mol)[_pos];
452 }
453 // pre-increment
454 template <class Atom_, class Mol_>
operator ++()455 QueryAtomIterator_<Atom_, Mol_> &QueryAtomIterator_<Atom_, Mol_>::operator++() {
456 _pos = _findNext(_pos + 1);
457 return *this;
458 }
459 template <class Atom_, class Mol_>
operator ++(int)460 QueryAtomIterator_<Atom_, Mol_> QueryAtomIterator_<Atom_, Mol_>::operator++(
461 int) {
462 QueryAtomIterator_ res(*this);
463 _pos = _findNext(_pos + 1);
464 return res;
465 }
466 // pre-decrement
467 template <class Atom_, class Mol_>
operator --()468 QueryAtomIterator_<Atom_, Mol_> &QueryAtomIterator_<Atom_, Mol_>::operator--() {
469 _pos = _findPrev(_pos - 1);
470 return *this;
471 }
472 template <class Atom_, class Mol_>
operator --(int)473 QueryAtomIterator_<Atom_, Mol_> QueryAtomIterator_<Atom_, Mol_>::operator--(
474 int) {
475 QueryAtomIterator_<Atom_, Mol_> res(*this);
476 _pos = _findPrev(_pos - 1);
477 return res;
478 }
479 template <class Atom_, class Mol_>
_findNext(int from)480 int QueryAtomIterator_<Atom_, Mol_>::_findNext(int from) {
481 PRECONDITION(_mol != nullptr, "no molecule");
482 PRECONDITION(_qA != nullptr, "no query set");
483 while (from < _end) {
484 if (_qA->Match((*_mol)[from])) {
485 break;
486 } else {
487 from++;
488 }
489 }
490 return from;
491 }
492
493 template <class Atom_, class Mol_>
_findPrev(int from)494 int QueryAtomIterator_<Atom_, Mol_>::_findPrev(int from) {
495 PRECONDITION(_mol != nullptr, "no molecule");
496 PRECONDITION(_qA != nullptr, "no query set");
497 while (from > 0) {
498 if (_qA->Match((*_mol)[from])) {
499 break;
500 } else {
501 from--;
502 }
503 }
504 if (from < 0) {
505 from = _end;
506 }
507 return from;
508 }
509
510 //-----------------------------------------
511 //
512 // MatchingAtomIterator
513 //
514 //-----------------------------------------
515 template <class Atom_, class Mol_>
MatchingAtomIterator_(Mol_ * mol,bool (* fn)(Atom_ *))516 MatchingAtomIterator_<Atom_, Mol_>::MatchingAtomIterator_(Mol_ *mol,
517 bool (*fn)(Atom_ *)) {
518 PRECONDITION(fn, "bad query function");
519 _mol = mol;
520 _qF = fn;
521 _end = mol->getNumAtoms();
522 _pos = _findNext(0);
523 };
524 template <class Atom_, class Mol_>
MatchingAtomIterator_(Mol_ * mol,int pos)525 MatchingAtomIterator_<Atom_, Mol_>::MatchingAtomIterator_(Mol_ *mol, int pos) {
526 _mol = mol;
527 _qF = nullptr;
528 _end = mol->getNumAtoms();
529 _pos = pos;
530 };
531
532 template <class Atom_, class Mol_>
~MatchingAtomIterator_()533 MatchingAtomIterator_<Atom_, Mol_>::~MatchingAtomIterator_() {}
534
535 template <class Atom_, class Mol_>
MatchingAtomIterator_(const MatchingAtomIterator_<Atom_,Mol_> & other)536 MatchingAtomIterator_<Atom_, Mol_>::MatchingAtomIterator_(
537 const MatchingAtomIterator_<Atom_, Mol_> &other) {
538 _mol = other._mol;
539 _pos = other._pos;
540 _end = other._end;
541 _qF = other._qF;
542 }
543
544 template <class Atom_, class Mol_>
545 MatchingAtomIterator_<Atom_, Mol_> &MatchingAtomIterator_<Atom_, Mol_>::
operator =(const MatchingAtomIterator_<Atom_,Mol_> & other)546 operator=(const MatchingAtomIterator_<Atom_, Mol_> &other) {
547 if (this != &other) {
548 _mol = other._mol;
549 _pos = other._pos;
550 _end = other._end;
551 _qF = other._qF;
552 }
553 return *this;
554 }
555 template <class Atom_, class Mol_>
operator ==(const MatchingAtomIterator_<Atom_,Mol_> & other) const556 bool MatchingAtomIterator_<Atom_, Mol_>::operator==(
557 const MatchingAtomIterator_<Atom_, Mol_> &other) const {
558 return _mol == other._mol && _pos == other._pos;
559 }
560 template <class Atom_, class Mol_>
operator !=(const MatchingAtomIterator_<Atom_,Mol_> & other) const561 bool MatchingAtomIterator_<Atom_, Mol_>::operator!=(
562 const MatchingAtomIterator_<Atom_, Mol_> &other) const {
563 return _mol != other._mol || _pos != other._pos;
564 }
565
566 template <class Atom_, class Mol_>
567 Atom_ *MatchingAtomIterator_<Atom_, Mol_>::operator*() const {
568 PRECONDITION(_mol != nullptr, "no molecule");
569 return (*_mol)[_pos];
570 }
571 // pre-increment
572 template <class Atom_, class Mol_>
573 MatchingAtomIterator_<Atom_, Mol_>
operator ++()574 &MatchingAtomIterator_<Atom_, Mol_>::operator++() {
575 _pos = _findNext(_pos + 1);
576 return *this;
577 }
578 template <class Atom_, class Mol_>
579 MatchingAtomIterator_<Atom_, Mol_> MatchingAtomIterator_<Atom_, Mol_>::
operator ++(int)580 operator++(int) {
581 MatchingAtomIterator_ res(*this);
582 _pos = _findNext(_pos + 1);
583 return res;
584 }
585 // pre-decrement
586 template <class Atom_, class Mol_>
587 MatchingAtomIterator_<Atom_, Mol_>
operator --()588 &MatchingAtomIterator_<Atom_, Mol_>::operator--() {
589 _pos = _findPrev(_pos - 1);
590 return *this;
591 }
592 template <class Atom_, class Mol_>
593 MatchingAtomIterator_<Atom_, Mol_> MatchingAtomIterator_<Atom_, Mol_>::
operator --(int)594 operator--(int) {
595 MatchingAtomIterator_<Atom_, Mol_> res(*this);
596 _pos = _findPrev(_pos - 1);
597 return res;
598 }
599 template <class Atom_, class Mol_>
_findNext(int from)600 int MatchingAtomIterator_<Atom_, Mol_>::_findNext(int from) {
601 PRECONDITION(_mol != nullptr, "no molecule");
602 PRECONDITION(_qF != nullptr, "no query set");
603 while (from < _end) {
604 if (_qF((*_mol)[from])) {
605 break;
606 } else {
607 ++from;
608 }
609 }
610 return from;
611 }
612
613 template <class Atom_, class Mol_>
_findPrev(int from)614 int MatchingAtomIterator_<Atom_, Mol_>::_findPrev(int from) {
615 PRECONDITION(_mol != nullptr, "no molecule");
616 PRECONDITION(_qF != nullptr, "no query set");
617 while (from > 0) {
618 if (_qF((*_mol)[from])) {
619 break;
620 } else {
621 --from;
622 }
623 }
624 if (from < 0) {
625 from = _end;
626 }
627 return from;
628 }
629
630 template class AtomIterator_<Atom, ROMol>;
631 template class AtomIterator_<const Atom, const ROMol>;
632
633 template class AromaticAtomIterator_<Atom, ROMol>;
634 template class AromaticAtomIterator_<const Atom, const ROMol>;
635 template class HeteroatomIterator_<Atom, ROMol>;
636 template class HeteroatomIterator_<const Atom, const ROMol>;
637 template class QueryAtomIterator_<Atom, ROMol>;
638 template class QueryAtomIterator_<const Atom, const ROMol>;
639 template class MatchingAtomIterator_<Atom, ROMol>;
640 template class MatchingAtomIterator_<const Atom, const ROMol>;
641
642 }; // end o' namespace
643