diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index d788992df1..91b22274eb 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -1347,7 +1347,7 @@ template struct type_caster(static_cast(str_caster).c_str()); } + operator CharT*() { return none ? nullptr : &static_cast(str_caster)[0]; } operator CharT&() { if (none) throw value_error("Cannot convert None to a character"); diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index 6c2bebda87..1c3b8e0662 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -73,8 +73,11 @@ template struct set_caster { return false; auto s = reinterpret_borrow(src); value.clear(); + subcasters.clear(); + subcasters.reserve(s.size()); for (auto entry : s) { - key_conv conv; + subcasters.emplace_back(); + auto &conv = subcasters.back(); if (!conv.load(entry, convert)) return false; value.insert(cast_op(std::move(conv))); @@ -96,6 +99,9 @@ template struct set_caster { } PYBIND11_TYPE_CASTER(type, _("Set[") + key_conv::name + _("]")); + +private: + std::vector subcasters; }; template struct map_caster { @@ -107,9 +113,13 @@ template struct map_caster { return false; auto d = reinterpret_borrow(src); value.clear(); + subcasters.clear(); + subcasters.reserve(d.size()); for (auto it : d) { - key_conv kconv; - value_conv vconv; + subcasters.emplace_back(); + auto &conv_pair = subcasters.back(); + auto &kconv = conv_pair.first; + auto &vconv = conv_pair.second; if (!kconv.load(it.first.ptr(), convert) || !vconv.load(it.second.ptr(), convert)) return false; @@ -138,6 +148,9 @@ template struct map_caster { } PYBIND11_TYPE_CASTER(Type, _("Dict[") + key_conv::name + _(", ") + value_conv::name + _("]")); + +private: + std::vector> subcasters; }; template struct list_caster { @@ -149,8 +162,11 @@ template struct list_caster { auto s = reinterpret_borrow(src); value.clear(); reserve_maybe(s, &value); + subcasters.clear(); + subcasters.reserve(s.size()); for (auto it : s) { - value_conv conv; + subcasters.emplace_back(); + auto &conv = subcasters.back(); if (!conv.load(it, convert)) return false; value.push_back(cast_op(std::move(conv))); @@ -181,6 +197,9 @@ template struct list_caster { } PYBIND11_TYPE_CASTER(Type, _("List[") + value_conv::name + _("]")); + +private: + std::vector subcasters; }; template struct type_caster> @@ -214,9 +233,12 @@ template s auto l = reinterpret_borrow(src); if (!require_size(l.size())) return false; + subcasters.clear(); + subcasters.reserve(l.size()); size_t ctr = 0; for (auto it : l) { - value_conv conv; + subcasters.emplace_back(); + auto &conv = subcasters.back(); if (!conv.load(it, convert)) return false; value[ctr++] = cast_op(std::move(conv)); @@ -238,6 +260,9 @@ template s } PYBIND11_TYPE_CASTER(ArrayType, _("List[") + value_conv::name + _(_(""), _("[") + _() + _("]")) + _("]")); + +private: + std::vector subcasters; }; template struct type_caster> @@ -278,7 +303,6 @@ template struct optional_caster { } else if (src.is_none()) { return true; // default-constructed value is already empty } - value_conv inner_caster; if (!inner_caster.load(src, convert)) return false; @@ -287,6 +311,9 @@ template struct optional_caster { } PYBIND11_TYPE_CASTER(T, _("Optional[") + value_conv::name + _("]")); + +private: + value_conv inner_caster; }; #if PYBIND11_HAS_OPTIONAL @@ -342,6 +369,7 @@ struct variant_caster> { auto caster = make_caster(); if (caster.load(src, convert)) { value = cast_op(caster); + subcaster = std::move(caster); return true; } return load_alternative(src, convert, type_list{}); @@ -367,6 +395,9 @@ struct variant_caster> { using Type = V; PYBIND11_TYPE_CASTER(Type, _("Union[") + detail::concat(make_caster::name...) + _("]")); + +private: + V...> subcaster; }; #if PYBIND11_HAS_VARIANT