File: test_make_iterator.cpp

package info (click to toggle)
nanobind 2.9.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,060 kB
  • sloc: cpp: 11,838; python: 5,862; ansic: 4,820; makefile: 22; sh: 15
file content (102 lines) | stat: -rw-r--r-- 4,299 bytes parent folder | download | duplicates (3)
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
#include <nanobind/make_iterator.h>
#include <nanobind/stl/unordered_map.h>
#include <nanobind/stl/string.h>

namespace nb = nanobind;

NB_MODULE(test_make_iterator_ext, m) {
    struct StringMap {
        std::unordered_map<std::string, std::string> map;
        decltype(map.cbegin()) begin() const { return map.cbegin(); }
        decltype(map.cend()) end() const { return map.cend(); }
    };

    nb::class_<StringMap>(m, "StringMap")
        .def(nb::init<>())
        .def(nb::init<std::unordered_map<std::string, std::string>>())
        .def("__iter__",
             [](const StringMap &map) {
                 return nb::make_key_iterator(nb::type<StringMap>(),
                                              "key_iterator",
                                              map.begin(),
                                              map.end());
             }, nb::keep_alive<0, 1>())
        .def("items",
             [](const StringMap &map) {
                 return nb::make_iterator(nb::type<StringMap>(),
                                          "item_iterator",
                                          map.begin(),
                                          map.end());
             }, nb::keep_alive<0, 1>())
        .def("items_l",
             [](const StringMap &map) {
                 // Make sure iterators don't dangle even if passed as lvalue
                 auto begin = map.begin(), end = map.end();
                 return nb::make_iterator(nb::type<StringMap>(),
                                          "item_iterator_l",
                                          begin, end);
             }, nb::keep_alive<0, 1>())
        .def("values", [](const StringMap &map) {
            return nb::make_value_iterator(nb::type<StringMap>(),
                                           "value_iterator",
                                           map.begin(),
                                           map.end());
        }, nb::keep_alive<0, 1>());

    nb::handle mod = m;
    m.def("iterator_passthrough", [mod](nb::iterator s) -> nb::iterator {
        return nb::make_iterator(mod, "pt_iterator", std::begin(s), std::end(s));
    });

    // test of map where dereferencing the iterator returns a value,
    // not a reference
    struct IdentityMap {
        struct iterator {
            int val;
            std::pair<int, int> operator*() const { return {val, val}; }
            iterator& operator++() { ++val; return *this; }
            bool operator==(const iterator& other) const {
                return val == other.val;
            }
        };

        iterator begin() const { return iterator{0}; }
        iterator end() const { return iterator{10}; }
    };

    nb::class_<IdentityMap>(m, "IdentityMap")
        .def(nb::init<>())
        .def("__iter__",
             [](const IdentityMap &map) {
                 return nb::make_key_iterator(nb::type<IdentityMap>(),
                                              "key_iterator",
                                              map.begin(),
                                              map.end());
             }, nb::keep_alive<0, 1>())
        .def("items",
             [](const IdentityMap &map) {
                 return nb::make_iterator(nb::type<IdentityMap>(),
                                          "item_iterator",
                                          map.begin(),
                                          map.end());
             }, nb::keep_alive<0, 1>())
        .def("items_l",
             [](const IdentityMap &map) {
                 auto begin = map.begin(), end = map.end();
                 return nb::make_iterator(nb::type<IdentityMap>(),
                                          "item_iterator_l",
                                          begin, end);
             }, nb::keep_alive<0, 1>())
        .def("values", [](const IdentityMap &map) {
            return nb::make_value_iterator(nb::type<IdentityMap>(),
                                           "value_iterator",
                                           map.begin(),
                                           map.end());
        }, nb::keep_alive<0, 1>());

    nb::list all;
    all.append("iterator_passthrough");
    all.append("StringMap");
    all.append("IdentityMap");
    m.attr("__all__") = all;
}