From a8dc0d26707feed4c76025d9497c116ed4a917e4 Mon Sep 17 00:00:00 2001 From: Aaron Gokaslan Date: Wed, 21 Sep 2022 10:52:43 -0400 Subject: [PATCH 1/4] Call reserve method in set and map casters too --- include/pybind11/stl.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index 48031c2a60..e6ac0e86ed 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -60,6 +60,7 @@ struct set_caster { } auto s = reinterpret_borrow(src); value.clear(); + reserve_maybe(s, &value); for (auto entry : s) { key_conv conv; if (!conv.load(entry, convert)) { @@ -87,6 +88,15 @@ struct set_caster { } PYBIND11_TYPE_CASTER(type, const_name("Set[") + key_conv::name + const_name("]")); + +private: + template < + typename T = Type, + enable_if_t().reserve(0)), void>::value, int> = 0> + void reserve_maybe(const anyset &s, Type *) { + value.reserve(s.size()); + } + void reserve_maybe(const anyset &, void *) {} }; template @@ -100,6 +110,7 @@ struct map_caster { } auto d = reinterpret_borrow(src); value.clear(); + reserve_maybe(d, &value); for (auto it : d) { key_conv kconv; value_conv vconv; @@ -136,6 +147,15 @@ struct map_caster { PYBIND11_TYPE_CASTER(Type, const_name("Dict[") + key_conv::name + const_name(", ") + value_conv::name + const_name("]")); + +private: + template < + typename T = Type, + enable_if_t().reserve(0)), void>::value, int> = 0> + void reserve_maybe(const dict &d, Type *) { + value.reserve(d.size()); + } + void reserve_maybe(const dict &, void *) {} }; template From 81be3b7e3fd5be4d0eb57d2a9f3d407eaa91d0d3 Mon Sep 17 00:00:00 2001 From: Aaron Gokaslan Date: Thu, 22 Sep 2022 12:28:50 -0400 Subject: [PATCH 2/4] Refactor template logic into has_reserve_method --- include/pybind11/stl.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index e6ac0e86ed..94894203db 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -49,6 +49,11 @@ constexpr forwarded_type forward_like(U &&u) { return std::forward>(std::forward(u)); } +// Checks if a container has a STL style reserve method. +// The reserve method should also have a void return type. +template +using has_reserve_method = std::is_same().reserve(0)), void>; + template struct set_caster { using type = Type; @@ -90,9 +95,7 @@ struct set_caster { PYBIND11_TYPE_CASTER(type, const_name("Set[") + key_conv::name + const_name("]")); private: - template < - typename T = Type, - enable_if_t().reserve(0)), void>::value, int> = 0> + template ::value, int> = 0> void reserve_maybe(const anyset &s, Type *) { value.reserve(s.size()); } @@ -149,9 +152,7 @@ struct map_caster { + const_name("]")); private: - template < - typename T = Type, - enable_if_t().reserve(0)), void>::value, int> = 0> + template ::value, int> = 0> void reserve_maybe(const dict &d, Type *) { value.reserve(d.size()); } @@ -180,9 +181,7 @@ struct list_caster { } private: - template < - typename T = Type, - enable_if_t().reserve(0)), void>::value, int> = 0> + template ::value, int> = 0> void reserve_maybe(const sequence &s, Type *) { value.reserve(s.size()); } From 2a327eecd191c009b134b78b8d9aa7da3402c62f Mon Sep 17 00:00:00 2001 From: Aaron Gokaslan Date: Thu, 22 Sep 2022 12:38:42 -0400 Subject: [PATCH 3/4] Adjust comment for reviews --- include/pybind11/stl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index 94894203db..79d8f10aef 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -50,7 +50,7 @@ constexpr forwarded_type forward_like(U &&u) { } // Checks if a container has a STL style reserve method. -// The reserve method should also have a void return type. +// This will only return true for a `reserve()` with a `void` return. template using has_reserve_method = std::is_same().reserve(0)), void>; From 007de499633d1128f8867c79740432a539c2390d Mon Sep 17 00:00:00 2001 From: Aaron Gokaslan Date: Thu, 22 Sep 2022 12:44:48 -0400 Subject: [PATCH 4/4] Rearrange reserve_maybe to not be underneath macro --- include/pybind11/stl.h | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index 79d8f10aef..8f243502ef 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -59,6 +59,14 @@ struct set_caster { using type = Type; using key_conv = make_caster; +private: + template ::value, int> = 0> + void reserve_maybe(const anyset &s, Type *) { + value.reserve(s.size()); + } + void reserve_maybe(const anyset &, void *) {} + +public: bool load(handle src, bool convert) { if (!isinstance(src)) { return false; @@ -93,13 +101,6 @@ struct set_caster { } PYBIND11_TYPE_CASTER(type, const_name("Set[") + key_conv::name + const_name("]")); - -private: - template ::value, int> = 0> - void reserve_maybe(const anyset &s, Type *) { - value.reserve(s.size()); - } - void reserve_maybe(const anyset &, void *) {} }; template @@ -107,6 +108,14 @@ struct map_caster { using key_conv = make_caster; using value_conv = make_caster; +private: + template ::value, int> = 0> + void reserve_maybe(const dict &d, Type *) { + value.reserve(d.size()); + } + void reserve_maybe(const dict &, void *) {} + +public: bool load(handle src, bool convert) { if (!isinstance(src)) { return false; @@ -150,13 +159,6 @@ struct map_caster { PYBIND11_TYPE_CASTER(Type, const_name("Dict[") + key_conv::name + const_name(", ") + value_conv::name + const_name("]")); - -private: - template ::value, int> = 0> - void reserve_maybe(const dict &d, Type *) { - value.reserve(d.size()); - } - void reserve_maybe(const dict &, void *) {} }; template