@@ -49,17 +49,31 @@ constexpr forwarded_type<T, U> forward_like(U &&u) {
4949 return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
5050}
5151
52+ // Checks if a container has a STL style reserve method.
53+ // This will only return true for a `reserve()` with a `void` return.
54+ template <typename C>
55+ using has_reserve_method = std::is_same<decltype (std::declval<C>().reserve(0 )), void >;
56+
5257template <typename Type, typename Key>
5358struct set_caster {
5459 using type = Type;
5560 using key_conv = make_caster<Key>;
5661
62+ private:
63+ template <typename T = Type, enable_if_t <has_reserve_method<T>::value, int > = 0 >
64+ void reserve_maybe (const anyset &s, Type *) {
65+ value.reserve (s.size ());
66+ }
67+ void reserve_maybe (const anyset &, void *) {}
68+
69+ public:
5770 bool load (handle src, bool convert) {
5871 if (!isinstance<anyset>(src)) {
5972 return false ;
6073 }
6174 auto s = reinterpret_borrow<anyset>(src);
6275 value.clear ();
76+ reserve_maybe (s, &value);
6377 for (auto entry : s) {
6478 key_conv conv;
6579 if (!conv.load (entry, convert)) {
@@ -94,12 +108,21 @@ struct map_caster {
94108 using key_conv = make_caster<Key>;
95109 using value_conv = make_caster<Value>;
96110
111+ private:
112+ template <typename T = Type, enable_if_t <has_reserve_method<T>::value, int > = 0 >
113+ void reserve_maybe (const dict &d, Type *) {
114+ value.reserve (d.size ());
115+ }
116+ void reserve_maybe (const dict &, void *) {}
117+
118+ public:
97119 bool load (handle src, bool convert) {
98120 if (!isinstance<dict>(src)) {
99121 return false ;
100122 }
101123 auto d = reinterpret_borrow<dict>(src);
102124 value.clear ();
125+ reserve_maybe (d, &value);
103126 for (auto it : d) {
104127 key_conv kconv;
105128 value_conv vconv;
@@ -160,9 +183,7 @@ struct list_caster {
160183 }
161184
162185private:
163- template <
164- typename T = Type,
165- enable_if_t <std::is_same<decltype (std::declval<T>().reserve(0 )), void >::value, int > = 0 >
186+ template <typename T = Type, enable_if_t <has_reserve_method<T>::value, int > = 0 >
166187 void reserve_maybe (const sequence &s, Type *) {
167188 value.reserve (s.size ());
168189 }
0 commit comments