8 #ifndef ICETRAY_PYTHON_STD_MAP_INDEXING_SUITE_HPP_INCLUDED 9 # define ICETRAY_PYTHON_STD_MAP_INDEXING_SUITE_HPP_INCLUDED 12 # include <boost/python/suite/indexing/indexing_suite.hpp> 13 # include <boost/python/iterator.hpp> 14 # include <boost/python/call_method.hpp> 15 # include <boost/python/tuple.hpp> 16 # include <boost/iterator/transform_iterator.hpp> 20 namespace boost {
namespace python {
23 template <
class Container,
bool NoProxy,
class DerivedPolicies>
28 template <
class Container,
bool NoProxy>
31 NoProxy, final_std_map_derived_policies<Container, NoProxy> > {};
56 :
public indexing_suite<
61 , typename Container::value_type::second_type
62 , typename Container::key_type
63 , typename Container::key_type
69 typedef typename Container::value_type::second_type
data_type;
80 if (i==0 || i==-2)
return object(x.first);
81 else if (i==1 || i==-1)
return object(x.second);
83 PyErr_SetString(PyExc_IndexError,
"Index out of range.");
84 throw_error_already_set();
94 object tuple = bp::make_tuple(x.first,x.second);
95 return incref(tuple.attr(
"__iter__")().ptr());
99 static int pair_len(value_type
const& x) {
return 2; }
102 static bp::list
keys(Container
const& x)
105 for(
typename Container::const_iterator it = x.begin(); it != x.end(); it++)
110 static bp::list
values(Container
const& x)
113 for(
typename Container::const_iterator it = x.begin(); it != x.end(); it++)
114 t.append(it->second);
118 static bp::list
items(Container
const& x)
121 for(
typename Container::const_iterator it = x.begin(); it != x.end(); it++)
122 t.append(bp::make_tuple(it->first, it->second));
129 static Container copy(Container
const& x)
132 for(const_iterator it = x.begin();it != x.end();it++) newmap.insert(*it);
137 static object dict_get(Container
const& x, index_type
const& k,
object const& default_val =
object())
139 const_iterator it = x.find(k);
140 if (it != x.end())
return object(it->second);
141 else return default_val;
147 static object dict_pop(Container & x, index_type
const& k)
149 const_iterator it = x.find(k);
152 result = object(it->second);
157 PyErr_SetString(PyExc_KeyError,
"Key not found.");
158 throw_error_already_set();
164 static object dict_pop_default(Container & x, index_type
const& k,
object const& default_val)
166 const_iterator it = x.find(k);
169 result = object(it->second);
173 else return default_val;
179 const_iterator it = x.begin();
182 result = boost::python::make_tuple(it->first,it->second);
187 PyErr_SetString(PyExc_KeyError,
"No more items to pop");
188 throw_error_already_set();
196 object newmap = object(
typename Container::storage_type());
197 int numkeys = extract<int>(keys.attr(
"__len__")());
198 for(
int i=0;i<numkeys;i++) {
199 newmap.attr(
"__setitem__")
200 (keys.attr(
"__getitem__")(i),value);
206 template <
typename PyClassT>
208 typedef typename PyClassT::metadata::holder
Holder;
215 void* memory = Holder::allocate(p, offsetof(instance_t, storage),
sizeof(Holder));
219 (
new (memory) Holder(p))->install(p);
222 Holder::deallocate(p, memory);
226 static void from_dict(PyObject *p, bp::dict
const& dict)
229 object newmap = object(bp::handle<>(borrowed(p)));
230 newmap.attr(
"update")(dict);
232 static void from_list(PyObject *p, bp::list
const& list)
235 object newmap = object(bp::handle<>(borrowed(p)));
236 newmap.attr(
"update")(bp::dict(list));
244 object keys = dictlike.attr(
"keys")();
245 int numkeys = extract<int>(keys.attr(
"__len__")());
246 for(
int i=0;i<numkeys;i++) {
247 key = keys.attr(
"__getitem__")(i);
248 x.attr(
"__setitem__")(key,dictlike.attr(
"__getitem__")(key));
279 return boost::python::make_tuple(x.first,x.second);
283 template <
typename Transform>
286 typedef boost::transform_iterator<Transform, const_iterator>
iterator;
288 static iterator
begin(
const Container& m)
290 return boost::make_transform_iterator(m.begin(), Transform());
292 static iterator
end(
const Container& m)
294 return boost::make_transform_iterator(m.end(), Transform());
299 return bp::range(&begin, &end);
303 template <
typename Transform>
307 return make_transform_impl<Transform>::range();
313 return "(%s, %s)" % python::make_tuple(e.first, e.second);
327 static typename Container::key_type
336 typename Container::iterator i = container.find(i_);
337 if (i == container.end())
339 PyErr_SetString(PyExc_KeyError,
"Invalid key");
340 throw_error_already_set();
346 set_item(Container& container, index_type i, data_type
const& v)
360 return container.size();
364 contains(Container& container, key_type
const& key)
366 return container.find(key) != container.end();
372 return container.key_comp()(a, b);
378 extract<key_type const&> i(i_);
385 extract<key_type> i(i_);
390 PyErr_SetString(PyExc_TypeError,
"Invalid index type");
391 throw_error_already_set();
395 template <
class Class>
400 std::string elem_name =
"std_map_indexing_suite_";
402 object class_name(cl.attr(
"__name__"));
403 extract<std::string> class_name_extractor(class_name);
404 cl_name = class_name_extractor();
405 elem_name += cl_name;
406 elem_name +=
"_entry";
408 typedef typename mpl::if_<
410 , return_internal_reference<>
411 , default_call_policies
412 >::type get_data_return_policy;
414 class_<value_type>(elem_name.c_str())
415 .def(
"__repr__", &DerivedPolicies::print_elem)
416 .def(
"data", &DerivedPolicies::get_data, get_data_return_policy(),
417 "K.data() -> the value associated with this pair.\n")
418 .def(
"key", &DerivedPolicies::get_key,
419 "K.key() -> the key associated with this pair.\n")
423 .def(
"first",&DerivedPolicies::get_key,
424 "K.first() -> the first item in this pair.\n")
425 .def(
"second",&DerivedPolicies::get_data, get_data_return_policy(),
426 "K.second() -> the second item in this pair.\n")
432 .def(
"__init__", init_factory<Class>::from_list,
433 "Initialize with keys and values from a Python dictionary: {'key':'value'}\n")
434 .def(
"__init__", init_factory<Class>::from_dict,
435 "Initialize with keys and values as tuples in a Python list: [('key','value')]\n")
438 .def(
"keys", &
keys,
"D.keys() -> list of D's keys\n")
439 .def(
"has_key", &
contains,
"D.has_key(k) -> True if D has a key k, else False\n")
440 .def(
"values", &
values,
"D.values() -> list of D's values\n")
441 .def(
"items", &
items,
"D.items() -> list of D's (key, value) pairs, as 2-tuples\n")
442 .def(
"clear", &Container::clear,
"D.clear() -> None. Remove all items from D.\n")
444 .def(
"get",
dict_get, dict_get_overloads(args(
"default_val"),
445 "D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.\n"))
448 "D.pop(k[,d]) -> v, remove specified key and return the corresponding value\nIf key is not found, d is returned if given, otherwise KeyError is raised\n")
450 "D.popitem() -> (k, v), remove and return some (key, value) pair as a\n2-tuple; but raise KeyError if D is empty\n")
452 (cl_name+
".fromkeys(S,v) -> New "+cl_name+
" with keys from S and values equal to v.\n").c_str())
453 .staticmethod(
"fromkeys")
455 "D.update(E) -> None. Update D from E: for k in E: D[k] = E[k]\n")
457 make_transform<iteritems>(),
458 "D.iteritems() -> an iterator over the (key, value) items of D\n")
460 make_transform<iterkeys>(),
461 "D.iterkeys() -> an iterator over the keys of D\n")
463 make_transform<itervalues>(),
464 "D.itervalues() -> an iterator over the values of D\n")
473 #endif // ICETRAY_PYTHON_STD_MAP_INDEXING_SUITE_HPP_INCLUDED static void from_dict(PyObject *p, bp::dict const &dict)
Definition: std_map_indexing_suite.hpp:226
static void set_item(Container &container, index_type i, data_type const &v)
Definition: std_map_indexing_suite.hpp:346
Definition: std_map_indexing_suite.hpp:207
static PyObject * pair_iter(value_type const &x)
Definition: std_map_indexing_suite.hpp:93
Definition: std_map_indexing_suite.hpp:20
static object dict_pop_default(Container &x, index_type const &k, object const &default_val)
Definition: std_map_indexing_suite.hpp:164
static object print_elem(typename Container::value_type const &e)
Definition: std_map_indexing_suite.hpp:311
static bool compare_index(Container &container, index_type a, index_type b)
Definition: std_map_indexing_suite.hpp:370
bp::objects::instance< Holder > instance_t
Definition: std_map_indexing_suite.hpp:209
Definition: std_map_indexing_suite.hpp:24
static bp::object make_transform()
Definition: std_map_indexing_suite.hpp:305
static bool contains(Container &container, key_type const &key)
Definition: std_map_indexing_suite.hpp:364
static object dict_fromkeys(object const &keys, object const &value)
Definition: std_map_indexing_suite.hpp:194
Container::value_type::second_type data_type
Definition: std_map_indexing_suite.hpp:69
static object dict_pop_item(Container &x)
Definition: std_map_indexing_suite.hpp:177
static Container::key_type get_key(typename Container::value_type &e)
Definition: std_map_indexing_suite.hpp:328
static void extension_def(Class &cl)
Definition: std_map_indexing_suite.hpp:397
static object pair_getitem(value_type const &x, int i)
Definition: std_map_indexing_suite.hpp:79
static object dict_pop(Container &x, index_type const &k)
Definition: std_map_indexing_suite.hpp:147
static mpl::if_< is_class< data_type >, data_type &, data_type >::type get_data(typename Container::value_type &e)
Definition: std_map_indexing_suite.hpp:322
Container::const_iterator const_iterator
Definition: std_map_indexing_suite.hpp:74
static void delete_item(Container &container, index_type i)
Definition: std_map_indexing_suite.hpp:352
result_type operator()(value_type const &x) const
Definition: std_map_indexing_suite.hpp:258
Container::difference_type difference_type
Definition: std_map_indexing_suite.hpp:73
Container::size_type size_type
Definition: std_map_indexing_suite.hpp:72
static object dict_get(Container const &x, index_type const &k, object const &default_val=object())
Definition: std_map_indexing_suite.hpp:137
result_type operator()(value_type const &x) const
Definition: std_map_indexing_suite.hpp:268
Definition: std_map_indexing_suite.hpp:264
tuple result_type
Definition: std_map_indexing_suite.hpp:275
key_type result_type
Definition: std_map_indexing_suite.hpp:256
Definition: std_map_indexing_suite.hpp:29
static void dict_update(object &x, object const &dictlike)
Definition: std_map_indexing_suite.hpp:241
static bp::list items(Container const &x)
Definition: std_map_indexing_suite.hpp:118
static index_type convert_index(Container &container, PyObject *i_)
Definition: std_map_indexing_suite.hpp:376
data_type result_type
Definition: std_map_indexing_suite.hpp:266
static void make_holder(PyObject *p)
Definition: std_map_indexing_suite.hpp:213
static size_t size(Container &container)
Definition: std_map_indexing_suite.hpp:358
PyClassT::metadata::holder Holder
Definition: std_map_indexing_suite.hpp:208
BOOST_PYTHON_FUNCTION_OVERLOADS(dict_get_overloads, dict_get, 2, 3)
static int pair_len(value_type const &x)
Definition: std_map_indexing_suite.hpp:99
static bp::list values(Container const &x)
Definition: std_map_indexing_suite.hpp:110
static void from_list(PyObject *p, bp::list const &list)
Definition: std_map_indexing_suite.hpp:232
result_type operator()(value_type const &x) const
Definition: std_map_indexing_suite.hpp:277
static data_type & get_item(Container &container, index_type i_)
Definition: std_map_indexing_suite.hpp:334
Definition: std_map_indexing_suite.hpp:274
Definition: std_map_indexing_suite.hpp:20
Container::key_type index_type
Definition: std_map_indexing_suite.hpp:71
Container::value_type value_type
Definition: std_map_indexing_suite.hpp:68
static bp::list keys(Container const &x)
Definition: std_map_indexing_suite.hpp:102
Container::key_type key_type
Definition: std_map_indexing_suite.hpp:70
Definition: std_map_indexing_suite.hpp:254