Skip to content

Commit

Permalink
fix(stl_bind): Enable bind_map with using declarations. (#4952)
Browse files Browse the repository at this point in the history
* Enable `bind_map` with `using` declarations.

* style: pre-commit fixes

* Enable directives in bind_vector

* Add tests for bind_ and using directives

* style: pre-commit fixes

* Remove C++17 functions

* Fix test comment

* Add minimal user like map py test

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
AntoinePrv and pre-commit-ci[bot] committed Nov 29, 2023
1 parent 4bb6163 commit a67d786
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 2 deletions.
5 changes: 3 additions & 2 deletions include/pybind11/stl_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ class_<Vector, holder_type> bind_vector(handle scope, std::string const &name, A
[](const Vector &v) -> bool { return !v.empty(); },
"Check whether the list is nonempty");

cl.def("__len__", &Vector::size);
cl.def("__len__", [](const Vector &vec) { return vec.size(); });

#if 0
// C++ style functions deprecated, leaving it here as an example
Expand Down Expand Up @@ -843,7 +843,8 @@ class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&
m.erase(it);
});

cl.def("__len__", &Map::size);
// Always use a lambda in case of `using` declaration
cl.def("__len__", [](const Map &m) { return m.size(); });

return cl;
}
Expand Down
70 changes: 70 additions & 0 deletions tests/test_stl_binders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <deque>
#include <map>
#include <unordered_map>
#include <vector>

class El {
public:
Expand Down Expand Up @@ -83,6 +84,71 @@ struct RecursiveMap : std::map<int, RecursiveMap> {
using Parent::Parent;
};

class UserVectorLike : private std::vector<int> {
public:
// This is only a subset of the member functions, as needed at the time.
using Base = std::vector<int>;
using typename Base::const_iterator;
using typename Base::difference_type;
using typename Base::iterator;
using typename Base::size_type;
using typename Base::value_type;

using Base::at;
using Base::back;
using Base::Base;
using Base::begin;
using Base::cbegin;
using Base::cend;
using Base::clear;
using Base::empty;
using Base::end;
using Base::erase;
using Base::front;
using Base::insert;
using Base::pop_back;
using Base::push_back;
using Base::reserve;
using Base::shrink_to_fit;
using Base::swap;
using Base::operator[];
using Base::capacity;
using Base::size;
};

bool operator==(UserVectorLike const &, UserVectorLike const &) { return true; }
bool operator!=(UserVectorLike const &, UserVectorLike const &) { return false; }

class UserMapLike : private std::map<int, int> {
public:
// This is only a subset of the member functions, as needed at the time.
using Base = std::map<int, int>;
using typename Base::const_iterator;
using typename Base::iterator;
using typename Base::key_type;
using typename Base::mapped_type;
using typename Base::size_type;
using typename Base::value_type;

using Base::at;
using Base::Base;
using Base::begin;
using Base::cbegin;
using Base::cend;
using Base::clear;
using Base::emplace;
using Base::emplace_hint;
using Base::empty;
using Base::end;
using Base::erase;
using Base::find;
using Base::insert;
using Base::max_size;
using Base::swap;
using Base::operator[];
using Base::size;
};

/*
* Pybind11 does not catch more complicated recursion schemes, such as mutual
* recursion.
Expand Down Expand Up @@ -173,6 +239,10 @@ TEST_SUBMODULE(stl_binders, m) {
py::bind_map<MutuallyRecursiveContainerPairMV>(m, "MutuallyRecursiveContainerPairMV");
py::bind_vector<MutuallyRecursiveContainerPairVM>(m, "MutuallyRecursiveContainerPairVM");

// Bind with private inheritance + `using` directives.
py::bind_vector<UserVectorLike>(m, "UserVectorLike");
py::bind_map<UserMapLike>(m, "UserMapLike");

// The rest depends on numpy:
try {
py::module_::import("numpy");
Expand Down
14 changes: 14 additions & 0 deletions tests/test_stl_binders.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,3 +353,17 @@ def test_recursive_map():
recursive_map[100][101] = m.RecursiveMap()
recursive_map[100][102] = m.RecursiveMap()
assert list(recursive_map[100].keys()) == [101, 102]


def test_user_vector_like():
vec = m.UserVectorLike()
vec.append(2)
assert vec[0] == 2
assert len(vec) == 1


def test_user_like_map():
map = m.UserMapLike()
map[33] = 44
assert map[33] == 44
assert len(map) == 1

0 comments on commit a67d786

Please sign in to comment.