@@ -645,49 +645,50 @@ auto map_if_insertion_operator(Class_ &cl, std::string const &name)
645645 " Return the canonical string representation of this map." );
646646}
647647
648- template <typename KeyType>
649648struct keys_view {
650649 virtual size_t len () = 0;
651650 virtual iterator iter () = 0;
652- virtual bool contains (const KeyType &k) = 0;
653- virtual bool contains (const object &k) = 0;
651+ virtual bool contains (const handle &k) = 0;
654652 virtual ~keys_view () = default ;
655653};
656654
657- template <typename MappedType>
658655struct values_view {
659656 virtual size_t len () = 0;
660657 virtual iterator iter () = 0;
661658 virtual ~values_view () = default ;
662659};
663660
664- template <typename KeyType, typename MappedType>
665661struct items_view {
666662 virtual size_t len () = 0;
667663 virtual iterator iter () = 0;
668664 virtual ~items_view () = default ;
669665};
670666
671- template <typename Map, typename KeysView >
672- struct KeysViewImpl : public KeysView {
667+ template <typename Map>
668+ struct KeysViewImpl : public detail ::keys_view {
673669 explicit KeysViewImpl (Map &map) : map(map) {}
674670 size_t len () override { return map.size (); }
675671 iterator iter () override { return make_key_iterator (map.begin (), map.end ()); }
676- bool contains (const typename Map::key_type &k) override { return map.find (k) != map.end (); }
677- bool contains (const object &) override { return false ; }
672+ bool contains (const handle &k) override {
673+ try {
674+ return map.find (k.template cast <typename Map::key_type>()) != map.end ();
675+ } catch (const cast_error &) {
676+ return false ;
677+ }
678+ }
678679 Map ↦
679680};
680681
681- template <typename Map, typename ValuesView >
682- struct ValuesViewImpl : public ValuesView {
682+ template <typename Map>
683+ struct ValuesViewImpl : public detail ::values_view {
683684 explicit ValuesViewImpl (Map &map) : map(map) {}
684685 size_t len () override { return map.size (); }
685686 iterator iter () override { return make_value_iterator (map.begin (), map.end ()); }
686687 Map ↦
687688};
688689
689- template <typename Map, typename ItemsView >
690- struct ItemsViewImpl : public ItemsView {
690+ template <typename Map>
691+ struct ItemsViewImpl : public detail ::items_view {
691692 explicit ItemsViewImpl (Map &map) : map(map) {}
692693 size_t len () override { return map.size (); }
693694 iterator iter () override { return make_iterator (map.begin (), map.end ()); }
@@ -700,11 +701,9 @@ template <typename Map, typename holder_type = std::unique_ptr<Map>, typename...
700701class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {
701702 using KeyType = typename Map::key_type;
702703 using MappedType = typename Map::mapped_type;
703- using StrippedKeyType = detail::remove_cvref_t <KeyType>;
704- using StrippedMappedType = detail::remove_cvref_t <MappedType>;
705- using KeysView = detail::keys_view<StrippedKeyType>;
706- using ValuesView = detail::values_view<StrippedMappedType>;
707- using ItemsView = detail::items_view<StrippedKeyType, StrippedMappedType>;
704+ using KeysView = detail::keys_view;
705+ using ValuesView = detail::values_view;
706+ using ItemsView = detail::items_view;
708707 using Class_ = class_<Map, holder_type>;
709708
710709 // If either type is a non-module-local bound type then make the map binding non-local as well;
@@ -718,39 +717,20 @@ class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&
718717 }
719718
720719 Class_ cl (scope, name.c_str (), pybind11::module_local (local), std::forward<Args>(args)...);
721- static constexpr auto key_type_descr = detail::make_caster<KeyType>::name;
722- static constexpr auto mapped_type_descr = detail::make_caster<MappedType>::name;
723- std::string key_type_name (key_type_descr.text ), mapped_type_name (mapped_type_descr.text );
724720
725- // If key type isn't properly wrapped, fall back to C++ names
726- if (key_type_name == " %" ) {
727- key_type_name = detail::type_info_description (typeid (KeyType));
728- }
729- // Similarly for value type:
730- if (mapped_type_name == " %" ) {
731- mapped_type_name = detail::type_info_description (typeid (MappedType));
732- }
733-
734- // Wrap KeysView[KeyType] if it wasn't already wrapped
721+ // Wrap KeysView if it wasn't already wrapped
735722 if (!detail::get_type_info (typeid (KeysView))) {
736- class_<KeysView> keys_view (
737- scope, (" KeysView[" + key_type_name + " ]" ).c_str (), pybind11::module_local (local));
723+ class_<KeysView> keys_view (scope, " KeysView" , pybind11::module_local (local));
738724 keys_view.def (" __len__" , &KeysView::len);
739725 keys_view.def (" __iter__" ,
740726 &KeysView::iter,
741727 keep_alive<0 , 1 >() /* Essential: keep view alive while iterator exists */
742728 );
743- keys_view.def (" __contains__" ,
744- static_cast <bool (KeysView::*)(const KeyType &)>(&KeysView::contains));
745- // Fallback for when the object is not of the key type
746- keys_view.def (" __contains__" ,
747- static_cast <bool (KeysView::*)(const object &)>(&KeysView::contains));
729+ keys_view.def (" __contains__" , &KeysView::contains);
748730 }
749731 // Similarly for ValuesView:
750732 if (!detail::get_type_info (typeid (ValuesView))) {
751- class_<ValuesView> values_view (scope,
752- (" ValuesView[" + mapped_type_name + " ]" ).c_str (),
753- pybind11::module_local (local));
733+ class_<ValuesView> values_view (scope, " ValuesView" , pybind11::module_local (local));
754734 values_view.def (" __len__" , &ValuesView::len);
755735 values_view.def (" __iter__" ,
756736 &ValuesView::iter,
@@ -759,10 +739,7 @@ class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&
759739 }
760740 // Similarly for ItemsView:
761741 if (!detail::get_type_info (typeid (ItemsView))) {
762- class_<ItemsView> items_view (
763- scope,
764- (" ItemsView[" + key_type_name + " , " ).append (mapped_type_name + " ]" ).c_str (),
765- pybind11::module_local (local));
742+ class_<ItemsView> items_view (scope, " ItemsView" , pybind11::module_local (local));
766743 items_view.def (" __len__" , &ItemsView::len);
767744 items_view.def (" __iter__" ,
768745 &ItemsView::iter,
@@ -788,25 +765,19 @@ class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&
788765
789766 cl.def (
790767 " keys" ,
791- [](Map &m) {
792- return std::unique_ptr<KeysView>(new detail::KeysViewImpl<Map, KeysView>(m));
793- },
768+ [](Map &m) { return std::unique_ptr<KeysView>(new detail::KeysViewImpl<Map>(m)); },
794769 keep_alive<0 , 1 >() /* Essential: keep map alive while view exists */
795770 );
796771
797772 cl.def (
798773 " values" ,
799- [](Map &m) {
800- return std::unique_ptr<ValuesView>(new detail::ValuesViewImpl<Map, ValuesView>(m));
801- },
774+ [](Map &m) { return std::unique_ptr<ValuesView>(new detail::ValuesViewImpl<Map>(m)); },
802775 keep_alive<0 , 1 >() /* Essential: keep map alive while view exists */
803776 );
804777
805778 cl.def (
806779 " items" ,
807- [](Map &m) {
808- return std::unique_ptr<ItemsView>(new detail::ItemsViewImpl<Map, ItemsView>(m));
809- },
780+ [](Map &m) { return std::unique_ptr<ItemsView>(new detail::ItemsViewImpl<Map>(m)); },
810781 keep_alive<0 , 1 >() /* Essential: keep map alive while view exists */
811782 );
812783
0 commit comments