mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 21:25:13 +00:00
perf: call reserve method in set and map casters (#4194)
* Call reserve method in set and map casters too * Refactor template logic into has_reserve_method * Adjust comment for reviews * Rearrange reserve_maybe to not be underneath macro
This commit is contained in:
parent
f743bdf8e6
commit
5aa0fad5de
@ -49,17 +49,31 @@ constexpr forwarded_type<T, U> forward_like(U &&u) {
|
|||||||
return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
|
return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if a container has a STL style reserve method.
|
||||||
|
// This will only return true for a `reserve()` with a `void` return.
|
||||||
|
template <typename C>
|
||||||
|
using has_reserve_method = std::is_same<decltype(std::declval<C>().reserve(0)), void>;
|
||||||
|
|
||||||
template <typename Type, typename Key>
|
template <typename Type, typename Key>
|
||||||
struct set_caster {
|
struct set_caster {
|
||||||
using type = Type;
|
using type = Type;
|
||||||
using key_conv = make_caster<Key>;
|
using key_conv = make_caster<Key>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T = Type, enable_if_t<has_reserve_method<T>::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) {
|
bool load(handle src, bool convert) {
|
||||||
if (!isinstance<anyset>(src)) {
|
if (!isinstance<anyset>(src)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto s = reinterpret_borrow<anyset>(src);
|
auto s = reinterpret_borrow<anyset>(src);
|
||||||
value.clear();
|
value.clear();
|
||||||
|
reserve_maybe(s, &value);
|
||||||
for (auto entry : s) {
|
for (auto entry : s) {
|
||||||
key_conv conv;
|
key_conv conv;
|
||||||
if (!conv.load(entry, convert)) {
|
if (!conv.load(entry, convert)) {
|
||||||
@ -94,12 +108,21 @@ struct map_caster {
|
|||||||
using key_conv = make_caster<Key>;
|
using key_conv = make_caster<Key>;
|
||||||
using value_conv = make_caster<Value>;
|
using value_conv = make_caster<Value>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T = Type, enable_if_t<has_reserve_method<T>::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) {
|
bool load(handle src, bool convert) {
|
||||||
if (!isinstance<dict>(src)) {
|
if (!isinstance<dict>(src)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto d = reinterpret_borrow<dict>(src);
|
auto d = reinterpret_borrow<dict>(src);
|
||||||
value.clear();
|
value.clear();
|
||||||
|
reserve_maybe(d, &value);
|
||||||
for (auto it : d) {
|
for (auto it : d) {
|
||||||
key_conv kconv;
|
key_conv kconv;
|
||||||
value_conv vconv;
|
value_conv vconv;
|
||||||
@ -160,9 +183,7 @@ struct list_caster {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <
|
template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
|
||||||
typename T = Type,
|
|
||||||
enable_if_t<std::is_same<decltype(std::declval<T>().reserve(0)), void>::value, int> = 0>
|
|
||||||
void reserve_maybe(const sequence &s, Type *) {
|
void reserve_maybe(const sequence &s, Type *) {
|
||||||
value.reserve(s.size());
|
value.reserve(s.size());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user