@@ -49,17 +49,31 @@ constexpr forwarded_type<T, U> forward_like(U &&u) {
49
49
return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
50
50
}
51
51
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
+
52
57
template <typename Type, typename Key>
53
58
struct set_caster {
54
59
using type = Type;
55
60
using key_conv = make_caster<Key>;
56
61
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:
57
70
bool load (handle src, bool convert) {
58
71
if (!isinstance<anyset>(src)) {
59
72
return false ;
60
73
}
61
74
auto s = reinterpret_borrow<anyset>(src);
62
75
value.clear ();
76
+ reserve_maybe (s, &value);
63
77
for (auto entry : s) {
64
78
key_conv conv;
65
79
if (!conv.load (entry, convert)) {
@@ -94,12 +108,21 @@ struct map_caster {
94
108
using key_conv = make_caster<Key>;
95
109
using value_conv = make_caster<Value>;
96
110
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:
97
119
bool load (handle src, bool convert) {
98
120
if (!isinstance<dict>(src)) {
99
121
return false ;
100
122
}
101
123
auto d = reinterpret_borrow<dict>(src);
102
124
value.clear ();
125
+ reserve_maybe (d, &value);
103
126
for (auto it : d) {
104
127
key_conv kconv;
105
128
value_conv vconv;
@@ -160,9 +183,7 @@ struct list_caster {
160
183
}
161
184
162
185
private:
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 >
166
187
void reserve_maybe (const sequence &s, Type *) {
167
188
value.reserve (s.size ());
168
189
}
0 commit comments