From f07d5069d86e31ecf195664850f79fb00c445bd3 Mon Sep 17 00:00:00 2001 From: Jason Lowe-Power Date: Fri, 17 Nov 2017 17:02:05 -0800 Subject: ext: Upgrade PyBind11 to version 2.2.1 This upgrade is necessary for pybind to build with GCC 7.2. We still need to add the patch for stl.h. MSC_FULL_VER change is no longer needed. See https://gem5-review.googlesource.com/c/public/gem5/+/2230 Change-Id: I806729217d022070583994c2dfcaa74476aef30f Signed-off-by: Jason Lowe-Power Reviewed-on: https://gem5-review.googlesource.com/5801 Reviewed-by: Andreas Sandberg Maintainer: Andreas Sandberg --- .../tests/test_sequences_and_iterators.cpp | 334 ++++++++++----------- 1 file changed, 157 insertions(+), 177 deletions(-) (limited to 'ext/pybind11/tests/test_sequences_and_iterators.cpp') diff --git a/ext/pybind11/tests/test_sequences_and_iterators.cpp b/ext/pybind11/tests/test_sequences_and_iterators.cpp index c2051fadb..a45521256 100644 --- a/ext/pybind11/tests/test_sequences_and_iterators.cpp +++ b/ext/pybind11/tests/test_sequences_and_iterators.cpp @@ -13,146 +13,6 @@ #include #include -class Sequence { -public: - Sequence(size_t size) : m_size(size) { - print_created(this, "of size", m_size); - m_data = new float[size]; - memset(m_data, 0, sizeof(float) * size); - } - - Sequence(const std::vector &value) : m_size(value.size()) { - print_created(this, "of size", m_size, "from std::vector"); - m_data = new float[m_size]; - memcpy(m_data, &value[0], sizeof(float) * m_size); - } - - Sequence(const Sequence &s) : m_size(s.m_size) { - print_copy_created(this); - m_data = new float[m_size]; - memcpy(m_data, s.m_data, sizeof(float)*m_size); - } - - Sequence(Sequence &&s) : m_size(s.m_size), m_data(s.m_data) { - print_move_created(this); - s.m_size = 0; - s.m_data = nullptr; - } - - ~Sequence() { - print_destroyed(this); - delete[] m_data; - } - - Sequence &operator=(const Sequence &s) { - if (&s != this) { - delete[] m_data; - m_size = s.m_size; - m_data = new float[m_size]; - memcpy(m_data, s.m_data, sizeof(float)*m_size); - } - - print_copy_assigned(this); - - return *this; - } - - Sequence &operator=(Sequence &&s) { - if (&s != this) { - delete[] m_data; - m_size = s.m_size; - m_data = s.m_data; - s.m_size = 0; - s.m_data = nullptr; - } - - print_move_assigned(this); - - return *this; - } - - bool operator==(const Sequence &s) const { - if (m_size != s.size()) - return false; - for (size_t i=0; i> data) : data_(std::move(data)) {} - const std::pair* begin() const { return data_.data(); } - -private: - std::vector> data_; -}; - -// Interface of a map-like object that isn't (directly) an unordered_map, but provides some basic -// map-like functionality. -class StringMap { -public: - StringMap() = default; - StringMap(std::unordered_map init) - : map(std::move(init)) {} - - void set(std::string key, std::string val) { - map[key] = val; - } - - std::string get(std::string key) const { - return map.at(key); - } - - size_t size() const { - return map.size(); - } - -private: - std::unordered_map map; - -public: - decltype(map.cbegin()) begin() const { return map.cbegin(); } - decltype(map.cend()) end() const { return map.cend(); } -}; - template class NonZeroIterator { const T* ptr_; @@ -210,66 +70,164 @@ py::list test_random_access_iterator(PythonType x) { return checks; } -test_initializer sequences_and_iterators([](py::module &pm) { - auto m = pm.def_submodule("sequences_and_iterators"); +TEST_SUBMODULE(sequences_and_iterators, m) { + + // test_sequence + class Sequence { + public: + Sequence(size_t size) : m_size(size) { + print_created(this, "of size", m_size); + m_data = new float[size]; + memset(m_data, 0, sizeof(float) * size); + } + Sequence(const std::vector &value) : m_size(value.size()) { + print_created(this, "of size", m_size, "from std::vector"); + m_data = new float[m_size]; + memcpy(m_data, &value[0], sizeof(float) * m_size); + } + Sequence(const Sequence &s) : m_size(s.m_size) { + print_copy_created(this); + m_data = new float[m_size]; + memcpy(m_data, s.m_data, sizeof(float)*m_size); + } + Sequence(Sequence &&s) : m_size(s.m_size), m_data(s.m_data) { + print_move_created(this); + s.m_size = 0; + s.m_data = nullptr; + } + + ~Sequence() { print_destroyed(this); delete[] m_data; } - py::class_ seq(m, "Sequence"); + Sequence &operator=(const Sequence &s) { + if (&s != this) { + delete[] m_data; + m_size = s.m_size; + m_data = new float[m_size]; + memcpy(m_data, s.m_data, sizeof(float)*m_size); + } + print_copy_assigned(this); + return *this; + } - seq.def(py::init()) - .def(py::init&>()) - /// Bare bones interface - .def("__getitem__", [](const Sequence &s, size_t i) { - if (i >= s.size()) - throw py::index_error(); + Sequence &operator=(Sequence &&s) { + if (&s != this) { + delete[] m_data; + m_size = s.m_size; + m_data = s.m_data; + s.m_size = 0; + s.m_data = nullptr; + } + print_move_assigned(this); + return *this; + } + + bool operator==(const Sequence &s) const { + if (m_size != s.size()) return false; + for (size_t i = 0; i < m_size; ++i) + if (m_data[i] != s[i]) + return false; + return true; + } + bool operator!=(const Sequence &s) const { return !operator==(s); } + + float operator[](size_t index) const { return m_data[index]; } + float &operator[](size_t index) { return m_data[index]; } + + bool contains(float v) const { + for (size_t i = 0; i < m_size; ++i) + if (v == m_data[i]) + return true; + return false; + } + + Sequence reversed() const { + Sequence result(m_size); + for (size_t i = 0; i < m_size; ++i) + result[m_size - i - 1] = m_data[i]; + return result; + } + + size_t size() const { return m_size; } + + const float *begin() const { return m_data; } + const float *end() const { return m_data+m_size; } + + private: + size_t m_size; + float *m_data; + }; + py::class_(m, "Sequence") + .def(py::init()) + .def(py::init&>()) + /// Bare bones interface + .def("__getitem__", [](const Sequence &s, size_t i) { + if (i >= s.size()) throw py::index_error(); return s[i]; }) - .def("__setitem__", [](Sequence &s, size_t i, float v) { - if (i >= s.size()) - throw py::index_error(); + .def("__setitem__", [](Sequence &s, size_t i, float v) { + if (i >= s.size()) throw py::index_error(); s[i] = v; }) - .def("__len__", &Sequence::size) - /// Optional sequence protocol operations - .def("__iter__", [](const Sequence &s) { return py::make_iterator(s.begin(), s.end()); }, - py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - .def("__contains__", [](const Sequence &s, float v) { return s.contains(v); }) - .def("__reversed__", [](const Sequence &s) -> Sequence { return s.reversed(); }) - /// Slicing protocol (optional) - .def("__getitem__", [](const Sequence &s, py::slice slice) -> Sequence* { + .def("__len__", &Sequence::size) + /// Optional sequence protocol operations + .def("__iter__", [](const Sequence &s) { return py::make_iterator(s.begin(), s.end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) + .def("__contains__", [](const Sequence &s, float v) { return s.contains(v); }) + .def("__reversed__", [](const Sequence &s) -> Sequence { return s.reversed(); }) + /// Slicing protocol (optional) + .def("__getitem__", [](const Sequence &s, py::slice slice) -> Sequence* { size_t start, stop, step, slicelength; if (!slice.compute(s.size(), &start, &stop, &step, &slicelength)) throw py::error_already_set(); Sequence *seq = new Sequence(slicelength); - for (size_t i=0; i map(m, "StringMap"); + /// Comparisons + .def(py::self == py::self) + .def(py::self != py::self) + // Could also define py::self + py::self for concatenation, etc. + ; - map .def(py::init<>()) + // test_map_iterator + // Interface of a map-like object that isn't (directly) an unordered_map, but provides some basic + // map-like functionality. + class StringMap { + public: + StringMap() = default; + StringMap(std::unordered_map init) + : map(std::move(init)) {} + + void set(std::string key, std::string val) { map[key] = val; } + std::string get(std::string key) const { return map.at(key); } + size_t size() const { return map.size(); } + private: + std::unordered_map map; + public: + decltype(map.cbegin()) begin() const { return map.cbegin(); } + decltype(map.cend()) end() const { return map.cend(); } + }; + py::class_(m, "StringMap") + .def(py::init<>()) .def(py::init>()) .def("__getitem__", [](const StringMap &map, std::string key) { try { return map.get(key); } catch (const std::out_of_range&) { throw py::key_error("key '" + key + "' does not exist"); } - }) + }) .def("__setitem__", &StringMap::set) .def("__len__", &StringMap::size) .def("__iter__", [](const StringMap &map) { return py::make_key_iterator(map.begin(), map.end()); }, @@ -278,14 +236,23 @@ test_initializer sequences_and_iterators([](py::module &pm) { py::keep_alive<0, 1>()) ; + // test_generalized_iterators + class IntPairs { + public: + IntPairs(std::vector> data) : data_(std::move(data)) {} + const std::pair* begin() const { return data_.data(); } + private: + std::vector> data_; + }; py::class_(m, "IntPairs") .def(py::init>>()) .def("nonzero", [](const IntPairs& s) { return py::make_iterator(NonZeroIterator>(s.begin()), NonZeroSentinel()); - }, py::keep_alive<0, 1>()) + }, py::keep_alive<0, 1>()) .def("nonzero_keys", [](const IntPairs& s) { return py::make_key_iterator(NonZeroIterator>(s.begin()), NonZeroSentinel()); - }, py::keep_alive<0, 1>()); + }, py::keep_alive<0, 1>()) + ; #if 0 @@ -315,6 +282,7 @@ test_initializer sequences_and_iterators([](py::module &pm) { .def("__iter__", [](py::object s) { return PySequenceIterator(s.cast(), s); }) #endif + // test_python_iterator_in_cpp m.def("object_to_list", [](py::object o) { auto l = py::list(); for (auto item : o) { @@ -348,7 +316,19 @@ test_initializer sequences_and_iterators([](py::module &pm) { }); }); - m.def("tuple_iterator", [](py::tuple x) { return test_random_access_iterator(x); }); - m.def("list_iterator", [](py::list x) { return test_random_access_iterator(x); }); - m.def("sequence_iterator", [](py::sequence x) { return test_random_access_iterator(x); }); -}); + m.def("tuple_iterator", &test_random_access_iterator); + m.def("list_iterator", &test_random_access_iterator); + m.def("sequence_iterator", &test_random_access_iterator); + + // test_iterator_passthrough + // #181: iterator passthrough did not compile + m.def("iterator_passthrough", [](py::iterator s) -> py::iterator { + return py::make_iterator(std::begin(s), std::end(s)); + }); + + // test_iterator_rvp + // #388: Can't make iterators via make_iterator() with different r/v policies + static std::vector list = { 1, 2, 3 }; + m.def("make_iterator_1", []() { return py::make_iterator(list); }); + m.def("make_iterator_2", []() { return py::make_iterator(list); }); +} -- cgit v1.2.3