annotate DEPENDENCIES/generic/include/boost/python/suite/indexing/map_indexing_suite.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // (C) Copyright Joel de Guzman 2003.
Chris@16 2 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 3 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 4 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 #ifndef MAP_INDEXING_SUITE_JDG20038_HPP
Chris@16 7 # define MAP_INDEXING_SUITE_JDG20038_HPP
Chris@16 8
Chris@16 9 # include <boost/python/suite/indexing/indexing_suite.hpp>
Chris@16 10 # include <boost/python/iterator.hpp>
Chris@16 11 # include <boost/python/call_method.hpp>
Chris@16 12 # include <boost/python/tuple.hpp>
Chris@16 13
Chris@16 14 namespace boost { namespace python {
Chris@16 15
Chris@16 16 // Forward declaration
Chris@16 17 template <class Container, bool NoProxy, class DerivedPolicies>
Chris@16 18 class map_indexing_suite;
Chris@16 19
Chris@16 20 namespace detail
Chris@16 21 {
Chris@16 22 template <class Container, bool NoProxy>
Chris@16 23 class final_map_derived_policies
Chris@16 24 : public map_indexing_suite<Container,
Chris@16 25 NoProxy, final_map_derived_policies<Container, NoProxy> > {};
Chris@16 26 }
Chris@16 27
Chris@16 28 // The map_indexing_suite class is a predefined indexing_suite derived
Chris@16 29 // class for wrapping std::map (and std::map like) classes. It provides
Chris@16 30 // all the policies required by the indexing_suite (see indexing_suite).
Chris@16 31 // Example usage:
Chris@16 32 //
Chris@16 33 // class X {...};
Chris@16 34 //
Chris@16 35 // ...
Chris@16 36 //
Chris@16 37 // class_<std::map<std::string, X> >("XMap")
Chris@16 38 // .def(map_indexing_suite<std::map<std::string, X> >())
Chris@16 39 // ;
Chris@16 40 //
Chris@16 41 // By default indexed elements are returned by proxy. This can be
Chris@16 42 // disabled by supplying *true* in the NoProxy template parameter.
Chris@16 43 //
Chris@16 44 template <
Chris@16 45 class Container,
Chris@16 46 bool NoProxy = false,
Chris@16 47 class DerivedPolicies
Chris@16 48 = detail::final_map_derived_policies<Container, NoProxy> >
Chris@16 49 class map_indexing_suite
Chris@16 50 : public indexing_suite<
Chris@16 51 Container
Chris@16 52 , DerivedPolicies
Chris@16 53 , NoProxy
Chris@16 54 , true
Chris@16 55 , typename Container::value_type::second_type
Chris@16 56 , typename Container::key_type
Chris@16 57 , typename Container::key_type
Chris@16 58 >
Chris@16 59 {
Chris@16 60 public:
Chris@16 61
Chris@16 62 typedef typename Container::value_type value_type;
Chris@16 63 typedef typename Container::value_type::second_type data_type;
Chris@16 64 typedef typename Container::key_type key_type;
Chris@16 65 typedef typename Container::key_type index_type;
Chris@16 66 typedef typename Container::size_type size_type;
Chris@16 67 typedef typename Container::difference_type difference_type;
Chris@16 68
Chris@16 69 template <class Class>
Chris@16 70 static void
Chris@16 71 extension_def(Class& cl)
Chris@16 72 {
Chris@16 73 // Wrap the map's element (value_type)
Chris@16 74 std::string elem_name = "map_indexing_suite_";
Chris@16 75 object class_name(cl.attr("__name__"));
Chris@16 76 extract<std::string> class_name_extractor(class_name);
Chris@16 77 elem_name += class_name_extractor();
Chris@16 78 elem_name += "_entry";
Chris@16 79
Chris@16 80 typedef typename mpl::if_<
Chris@16 81 mpl::and_<is_class<data_type>, mpl::bool_<!NoProxy> >
Chris@16 82 , return_internal_reference<>
Chris@16 83 , default_call_policies
Chris@16 84 >::type get_data_return_policy;
Chris@16 85
Chris@16 86 class_<value_type>(elem_name.c_str())
Chris@16 87 .def("__repr__", &DerivedPolicies::print_elem)
Chris@16 88 .def("data", &DerivedPolicies::get_data, get_data_return_policy())
Chris@16 89 .def("key", &DerivedPolicies::get_key)
Chris@16 90 ;
Chris@16 91 }
Chris@16 92
Chris@16 93 static object
Chris@16 94 print_elem(typename Container::value_type const& e)
Chris@16 95 {
Chris@16 96 return "(%s, %s)" % python::make_tuple(e.first, e.second);
Chris@16 97 }
Chris@16 98
Chris@16 99 static
Chris@16 100 typename mpl::if_<
Chris@16 101 mpl::and_<is_class<data_type>, mpl::bool_<!NoProxy> >
Chris@16 102 , data_type&
Chris@16 103 , data_type
Chris@16 104 >::type
Chris@16 105 get_data(typename Container::value_type& e)
Chris@16 106 {
Chris@16 107 return e.second;
Chris@16 108 }
Chris@16 109
Chris@16 110 static typename Container::key_type
Chris@16 111 get_key(typename Container::value_type& e)
Chris@16 112 {
Chris@16 113 return e.first;
Chris@16 114 }
Chris@16 115
Chris@16 116 static data_type&
Chris@16 117 get_item(Container& container, index_type i_)
Chris@16 118 {
Chris@16 119 typename Container::iterator i = container.find(i_);
Chris@16 120 if (i == container.end())
Chris@16 121 {
Chris@16 122 PyErr_SetString(PyExc_KeyError, "Invalid key");
Chris@16 123 throw_error_already_set();
Chris@16 124 }
Chris@16 125 return i->second;
Chris@16 126 }
Chris@16 127
Chris@16 128 static void
Chris@16 129 set_item(Container& container, index_type i, data_type const& v)
Chris@16 130 {
Chris@16 131 container[i] = v;
Chris@16 132 }
Chris@16 133
Chris@16 134 static void
Chris@16 135 delete_item(Container& container, index_type i)
Chris@16 136 {
Chris@16 137 container.erase(i);
Chris@16 138 }
Chris@16 139
Chris@16 140 static size_t
Chris@16 141 size(Container& container)
Chris@16 142 {
Chris@16 143 return container.size();
Chris@16 144 }
Chris@16 145
Chris@16 146 static bool
Chris@16 147 contains(Container& container, key_type const& key)
Chris@16 148 {
Chris@16 149 return container.find(key) != container.end();
Chris@16 150 }
Chris@16 151
Chris@16 152 static bool
Chris@16 153 compare_index(Container& container, index_type a, index_type b)
Chris@16 154 {
Chris@16 155 return container.key_comp()(a, b);
Chris@16 156 }
Chris@16 157
Chris@16 158 static index_type
Chris@16 159 convert_index(Container& /*container*/, PyObject* i_)
Chris@16 160 {
Chris@16 161 extract<key_type const&> i(i_);
Chris@16 162 if (i.check())
Chris@16 163 {
Chris@16 164 return i();
Chris@16 165 }
Chris@16 166 else
Chris@16 167 {
Chris@16 168 extract<key_type> i(i_);
Chris@16 169 if (i.check())
Chris@16 170 return i();
Chris@16 171 }
Chris@16 172
Chris@16 173 PyErr_SetString(PyExc_TypeError, "Invalid index type");
Chris@16 174 throw_error_already_set();
Chris@16 175 return index_type();
Chris@16 176 }
Chris@16 177 };
Chris@16 178
Chris@16 179 }} // namespace boost::python
Chris@16 180
Chris@16 181 #endif // MAP_INDEXING_SUITE_JDG20038_HPP