File: seqs.hpp

package info (click to toggle)
rdkit 201809.1%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 123,688 kB
  • sloc: cpp: 230,509; python: 70,501; java: 6,329; ansic: 5,427; sql: 1,899; yacc: 1,739; lex: 1,243; makefile: 445; xml: 229; fortran: 183; sh: 123; cs: 93
file content (118 lines) | stat: -rw-r--r-- 3,101 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//
//  Copyright (C) 2003-2006 greg Landrum and Rational Discovery LLC
//
//   @@ All Rights Reserved  @@
//
#ifndef _SEQS_HPP_
#define _SEQS_HPP_

#include <GraphMol/RDKitBase.h>
#include <iostream>
#include <RDBoost/python.h>
namespace python = boost::python;

namespace RDKit {

class AtomCountFunctor {
 private:
  const ROMol &_mol;

 public:
  AtomCountFunctor(const ROMol &mol) : _mol(mol){};
  unsigned int operator()() const { return _mol.getNumAtoms(); };
};
class BondCountFunctor {
 private:
  const ROMol &_mol;

 public:
  BondCountFunctor(const ROMol &mol) : _mol(mol){};
  unsigned int operator()() const { return _mol.getNumBonds(); };
};

// Note: T1 should be some iterator type,
//       T2 is the value when we dereference T
template <class T1, class T2, class T3>
class ReadOnlySeq {
 private:
  T1 _start, _end, _pos;
  int _size;
  T3 _lenFunc;
  size_t _origLen;

 public:
  ~ReadOnlySeq() {}
  ReadOnlySeq(T1 start, T1 end, T3 lenFunc)
      : _start(start),
        _end(end),
        _pos(start),
        _size(-1),
        _lenFunc(lenFunc),
        _origLen(lenFunc()){};
  ReadOnlySeq(const ReadOnlySeq<T1, T2, T3> &other)
      : _start(other._start),
        _end(other._end),
        _pos(other._pos),
        _size(other._size),
        _lenFunc(other._lenFunc),
        _origLen(other._origLen){};
  void reset() {
    // std::cerr << "**** reset ****" << this<< std::endl;
    _pos = _start;
  }
  ReadOnlySeq<T1, T2, T3> *__iter__() {
    // std::cerr << "**** ITER ****" << this << std::endl;
    reset();
    // std::cerr << "  finish ****" << this << std::endl;
    return this;
  };
  T2 next() {
    // std::cerr << "\tnext: " << _pos._pos << " " << _end._pos << std::endl;
    if (_pos == _end) {
      PyErr_SetString(PyExc_StopIteration, "End of sequence hit");
      throw python::error_already_set();
    }
    if (_lenFunc() != _origLen) {
      PyErr_SetString(PyExc_RuntimeError, "Sequence modified during iteration");
      throw python::error_already_set();
    }
    T2 res = *_pos;
    ++_pos;
    return res;
  }
  T2 get_item(int which) {
    // std::cerr << "get_item: " <<which<< std::endl;
    if (which >= len()) {
      PyErr_SetString(PyExc_IndexError, "End of sequence hit");
      throw python::error_already_set();
    }
    if (_lenFunc() != _origLen) {
      PyErr_SetString(PyExc_RuntimeError, "Sequence modified during iteration");
      throw python::error_already_set();
    }
    T1 it = _start;
    for (int i = 0; i < which; i++) {
      ++it;
    }
    return *it;
  }
  int len() {
    // std::cerr << "len " << std::endl;
    if (_size < 0) {
      _size = 0;
      for (T1 tmp = _start; tmp != _end; tmp++) {
        // std::cerr << "\tincr: "  <<  std::endl;
        _size++;
      }
    }
    // std::cerr << "\tret" << std::endl;
    return _size;
  }
};

typedef ReadOnlySeq<ROMol::AtomIterator, Atom *, AtomCountFunctor> AtomIterSeq;
typedef ReadOnlySeq<ROMol::QueryAtomIterator, Atom *, AtomCountFunctor>
    QueryAtomIterSeq;
typedef ReadOnlySeq<ROMol::BondIterator, Bond *, BondCountFunctor> BondIterSeq;
}
#endif