@@ -645,49 +645,50 @@ auto map_if_insertion_operator(Class_ &cl, std::string const &name)
645
645
" Return the canonical string representation of this map." );
646
646
}
647
647
648
- template <typename KeyType>
649
648
struct keys_view {
650
649
virtual size_t len () = 0;
651
650
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;
654
652
virtual ~keys_view () = default ;
655
653
};
656
654
657
- template <typename MappedType>
658
655
struct values_view {
659
656
virtual size_t len () = 0;
660
657
virtual iterator iter () = 0;
661
658
virtual ~values_view () = default ;
662
659
};
663
660
664
- template <typename KeyType, typename MappedType>
665
661
struct items_view {
666
662
virtual size_t len () = 0;
667
663
virtual iterator iter () = 0;
668
664
virtual ~items_view () = default ;
669
665
};
670
666
671
- template <typename Map, typename KeysView >
672
- struct KeysViewImpl : public KeysView {
667
+ template <typename Map>
668
+ struct KeysViewImpl : public detail ::keys_view {
673
669
explicit KeysViewImpl (Map &map) : map(map) {}
674
670
size_t len () override { return map.size (); }
675
671
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
+ }
678
679
Map ↦
679
680
};
680
681
681
- template <typename Map, typename ValuesView >
682
- struct ValuesViewImpl : public ValuesView {
682
+ template <typename Map>
683
+ struct ValuesViewImpl : public detail ::values_view {
683
684
explicit ValuesViewImpl (Map &map) : map(map) {}
684
685
size_t len () override { return map.size (); }
685
686
iterator iter () override { return make_value_iterator (map.begin (), map.end ()); }
686
687
Map ↦
687
688
};
688
689
689
- template <typename Map, typename ItemsView >
690
- struct ItemsViewImpl : public ItemsView {
690
+ template <typename Map>
691
+ struct ItemsViewImpl : public detail ::items_view {
691
692
explicit ItemsViewImpl (Map &map) : map(map) {}
692
693
size_t len () override { return map.size (); }
693
694
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...
700
701
class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {
701
702
using KeyType = typename Map::key_type;
702
703
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;
708
707
using Class_ = class_<Map, holder_type>;
709
708
710
709
// 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 &&
718
717
}
719
718
720
719
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 );
724
720
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
735
722
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));
738
724
keys_view.def (" __len__" , &KeysView::len);
739
725
keys_view.def (" __iter__" ,
740
726
&KeysView::iter,
741
727
keep_alive<0 , 1 >() /* Essential: keep view alive while iterator exists */
742
728
);
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);
748
730
}
749
731
// Similarly for ValuesView:
750
732
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));
754
734
values_view.def (" __len__" , &ValuesView::len);
755
735
values_view.def (" __iter__" ,
756
736
&ValuesView::iter,
@@ -759,10 +739,7 @@ class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&
759
739
}
760
740
// Similarly for ItemsView:
761
741
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));
766
743
items_view.def (" __len__" , &ItemsView::len);
767
744
items_view.def (" __iter__" ,
768
745
&ItemsView::iter,
@@ -788,25 +765,19 @@ class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&
788
765
789
766
cl.def (
790
767
" 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)); },
794
769
keep_alive<0 , 1 >() /* Essential: keep map alive while view exists */
795
770
);
796
771
797
772
cl.def (
798
773
" 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)); },
802
775
keep_alive<0 , 1 >() /* Essential: keep map alive while view exists */
803
776
);
804
777
805
778
cl.def (
806
779
" 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)); },
810
781
keep_alive<0 , 1 >() /* Essential: keep map alive while view exists */
811
782
);
812
783
0 commit comments