Chris@16: // (C) Copyright Joel de Guzman 2003. Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef MAP_INDEXING_SUITE_JDG20038_HPP Chris@16: # define MAP_INDEXING_SUITE_JDG20038_HPP Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: namespace boost { namespace python { Chris@16: Chris@16: // Forward declaration Chris@16: template Chris@16: class map_indexing_suite; Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: class final_map_derived_policies Chris@16: : public map_indexing_suite > {}; Chris@16: } Chris@16: Chris@16: // The map_indexing_suite class is a predefined indexing_suite derived Chris@16: // class for wrapping std::map (and std::map like) classes. It provides Chris@16: // all the policies required by the indexing_suite (see indexing_suite). Chris@16: // Example usage: Chris@16: // Chris@16: // class X {...}; Chris@16: // Chris@16: // ... Chris@16: // Chris@16: // class_ >("XMap") Chris@16: // .def(map_indexing_suite >()) Chris@16: // ; Chris@16: // Chris@16: // By default indexed elements are returned by proxy. This can be Chris@16: // disabled by supplying *true* in the NoProxy template parameter. Chris@16: // Chris@16: template < Chris@16: class Container, Chris@16: bool NoProxy = false, Chris@16: class DerivedPolicies Chris@16: = detail::final_map_derived_policies > Chris@16: class map_indexing_suite Chris@16: : public indexing_suite< Chris@16: Container Chris@16: , DerivedPolicies Chris@16: , NoProxy Chris@16: , true Chris@16: , typename Container::value_type::second_type Chris@16: , typename Container::key_type Chris@16: , typename Container::key_type Chris@16: > Chris@16: { Chris@16: public: Chris@16: Chris@16: typedef typename Container::value_type value_type; Chris@16: typedef typename Container::value_type::second_type data_type; Chris@16: typedef typename Container::key_type key_type; Chris@16: typedef typename Container::key_type index_type; Chris@16: typedef typename Container::size_type size_type; Chris@16: typedef typename Container::difference_type difference_type; Chris@16: Chris@16: template Chris@16: static void Chris@16: extension_def(Class& cl) Chris@16: { Chris@16: // Wrap the map's element (value_type) Chris@16: std::string elem_name = "map_indexing_suite_"; Chris@16: object class_name(cl.attr("__name__")); Chris@16: extract class_name_extractor(class_name); Chris@16: elem_name += class_name_extractor(); Chris@16: elem_name += "_entry"; Chris@16: Chris@16: typedef typename mpl::if_< Chris@16: mpl::and_, mpl::bool_ > Chris@16: , return_internal_reference<> Chris@16: , default_call_policies Chris@16: >::type get_data_return_policy; Chris@16: Chris@16: class_(elem_name.c_str()) Chris@16: .def("__repr__", &DerivedPolicies::print_elem) Chris@16: .def("data", &DerivedPolicies::get_data, get_data_return_policy()) Chris@16: .def("key", &DerivedPolicies::get_key) Chris@16: ; Chris@16: } Chris@16: Chris@16: static object Chris@16: print_elem(typename Container::value_type const& e) Chris@16: { Chris@16: return "(%s, %s)" % python::make_tuple(e.first, e.second); Chris@16: } Chris@16: Chris@16: static Chris@16: typename mpl::if_< Chris@16: mpl::and_, mpl::bool_ > Chris@16: , data_type& Chris@16: , data_type Chris@16: >::type Chris@16: get_data(typename Container::value_type& e) Chris@16: { Chris@16: return e.second; Chris@16: } Chris@16: Chris@16: static typename Container::key_type Chris@16: get_key(typename Container::value_type& e) Chris@16: { Chris@16: return e.first; Chris@16: } Chris@16: Chris@16: static data_type& Chris@16: get_item(Container& container, index_type i_) Chris@16: { Chris@16: typename Container::iterator i = container.find(i_); Chris@16: if (i == container.end()) Chris@16: { Chris@16: PyErr_SetString(PyExc_KeyError, "Invalid key"); Chris@16: throw_error_already_set(); Chris@16: } Chris@16: return i->second; Chris@16: } Chris@16: Chris@16: static void Chris@16: set_item(Container& container, index_type i, data_type const& v) Chris@16: { Chris@16: container[i] = v; Chris@16: } Chris@16: Chris@16: static void Chris@16: delete_item(Container& container, index_type i) Chris@16: { Chris@16: container.erase(i); Chris@16: } Chris@16: Chris@16: static size_t Chris@16: size(Container& container) Chris@16: { Chris@16: return container.size(); Chris@16: } Chris@16: Chris@16: static bool Chris@16: contains(Container& container, key_type const& key) Chris@16: { Chris@16: return container.find(key) != container.end(); Chris@16: } Chris@16: Chris@16: static bool Chris@16: compare_index(Container& container, index_type a, index_type b) Chris@16: { Chris@16: return container.key_comp()(a, b); Chris@16: } Chris@16: Chris@16: static index_type Chris@16: convert_index(Container& /*container*/, PyObject* i_) Chris@16: { Chris@16: extract i(i_); Chris@16: if (i.check()) Chris@16: { Chris@16: return i(); Chris@16: } Chris@16: else Chris@16: { Chris@16: extract i(i_); Chris@16: if (i.check()) Chris@16: return i(); Chris@16: } Chris@16: Chris@16: PyErr_SetString(PyExc_TypeError, "Invalid index type"); Chris@16: throw_error_already_set(); Chris@16: return index_type(); Chris@16: } Chris@16: }; Chris@16: Chris@16: }} // namespace boost::python Chris@16: Chris@16: #endif // MAP_INDEXING_SUITE_JDG20038_HPP