66
77namespace py = pybind11;
88
9+ class Iterator {
10+ public:
11+ explicit Iterator (std::generator<ds::rule_t *> _generator) : generator(std::move(_generator)), initialized(false ), iterator(nullptr ) { }
12+
13+ ds::rule_t * next () {
14+ if (initialized) {
15+ ++*iterator;
16+ } else {
17+ iterator = std::make_unique<iterator_t >(generator.begin ());
18+ initialized = true ;
19+ }
20+ if (*iterator == generator.end ()) {
21+ return nullptr ;
22+ }
23+ ds::rule_t * result = **iterator;
24+ return result;
25+ }
26+
27+ private:
28+ std::generator<ds::rule_t *> generator;
29+ bool initialized;
30+ using iterator_t = decltype (generator.begin());
31+ std::unique_ptr<iterator_t > iterator;
32+ };
33+
934template <typename T>
1035auto from_string (const std::string_view& string, int buffer_size) -> std::unique_ptr<T> {
1136 auto result = reinterpret_cast <T*>(operator new (buffer_size));
@@ -169,6 +194,11 @@ PYBIND11_MODULE(_ds, m, py::mod_gil_not_used()) {
169194 search_t .def (" reset" , &ds::search_t ::reset);
170195 search_t .def (" add" , &ds::search_t ::add);
171196 search_t .def (" execute" , &ds::search_t ::execute);
197+ search_t .def (
198+ " iter" ,
199+ [](ds::search_t & self) { return Iterator (std::move (self.iterator ())); },
200+ py::return_value_policy::reference_internal
201+ );
172202
173203 auto chain_t = py::class_<ds::chain_t >(m, " Chain" );
174204 chain_t .def (py::init<ds::length_t , ds::length_t >());
@@ -177,4 +207,12 @@ PYBIND11_MODULE(_ds, m, py::mod_gil_not_used()) {
177207 chain_t .def (" reset" , &ds::chain_t ::reset);
178208 chain_t .def (" add" , &ds::chain_t ::add);
179209 chain_t .def (" execute" , &ds::chain_t ::execute);
210+ chain_t .def (
211+ " iter" ,
212+ [](ds::chain_t & self) { return Iterator (std::move (self.iterator ())); },
213+ py::return_value_policy::reference_internal
214+ );
215+
216+ auto iterator_t = py::class_<Iterator>(m, " Iterator" );
217+ iterator_t .def (" next" , &Iterator::next, py::return_value_policy::reference_internal);
180218}
0 commit comments