diff options
Diffstat (limited to '')
-rw-r--r-- | src/boost/libs/python/src/dict.cpp | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/src/boost/libs/python/src/dict.cpp b/src/boost/libs/python/src/dict.cpp new file mode 100644 index 00000000..77d840d4 --- /dev/null +++ b/src/boost/libs/python/src/dict.cpp @@ -0,0 +1,184 @@ +// Copyright David Abrahams 2004. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#include <boost/python/dict.hpp> +#include <boost/python/extract.hpp> + +namespace boost { namespace python { namespace detail { +namespace +{ + // When returning list objects from methods, it may turn out that the + // derived class is returning something else, perhaps something not + // even derived from list. Since it is generally harmless for a + // Boost.Python wrapper object to hold an object of a different + // type, and because calling list() with an object may in fact + // perform a conversion, the least-bad alternative is to assume that + // we have a Python list object and stuff it into the list result. + list assume_list(object const& o) + { + return list(detail::borrowed_reference(o.ptr())); + } + + // No PyDict_CheckExact; roll our own. + inline bool check_exact(dict_base const* p) + { + return p->ptr()->ob_type == &PyDict_Type; + } +} + +detail::new_reference dict_base::call(object const& arg_) +{ + return (detail::new_reference)PyObject_CallFunction( + (PyObject*)&PyDict_Type, const_cast<char*>("(O)"), + arg_.ptr()); +} + +dict_base::dict_base() + : object(detail::new_reference(PyDict_New())) +{} + +dict_base::dict_base(object_cref data) + : object(call(data)) +{} + +void dict_base::clear() +{ + if (check_exact(this)) + PyDict_Clear(this->ptr()); + else + this->attr("clear")(); +} + +dict dict_base::copy() +{ + if (check_exact(this)) + { + return dict(detail::new_reference( + PyDict_Copy(this->ptr()))); + } + else + { + return dict(detail::borrowed_reference( + this->attr("copy")().ptr() + )); + } +} + +object dict_base::get(object_cref k) const +{ + if (check_exact(this)) + { + PyObject* result = PyDict_GetItem(this->ptr(),k.ptr()); + return object(detail::borrowed_reference(result ? result : Py_None)); + } + else + { + return this->attr("get")(k); + } +} + +object dict_base::get(object_cref k, object_cref d) const +{ + return this->attr("get")(k,d); +} + +bool dict_base::has_key(object_cref k) const +{ + return extract<bool>(this->contains(k)); +} + +list dict_base::items() const +{ + if (check_exact(this)) + { + return list(detail::new_reference( + PyDict_Items(this->ptr()))); + } + else + { + return assume_list(this->attr("items")()); + } +} + +object dict_base::iteritems() const +{ + return this->attr("iteritems")(); +} + +object dict_base::iterkeys() const +{ + return this->attr("iterkeys")(); +} + +object dict_base::itervalues() const +{ + return this->attr("itervalues")(); +} + +list dict_base::keys() const +{ + if (check_exact(this)) + { + return list(detail::new_reference( + PyDict_Keys(this->ptr()))); + } + else + { + return assume_list(this->attr("keys")()); + } +} + +tuple dict_base::popitem() +{ + return tuple(detail::borrowed_reference( + this->attr("popitem")().ptr() + )); +} + +object dict_base::setdefault(object_cref k) +{ + return this->attr("setdefault")(k); +} + +object dict_base::setdefault(object_cref k, object_cref d) +{ + return this->attr("setdefault")(k,d); +} + +void dict_base::update(object_cref other) +{ + if (check_exact(this)) + { + if (PyDict_Update(this->ptr(),other.ptr()) == -1) + throw_error_already_set(); + } + else + { + this->attr("update")(other); + } +} + +list dict_base::values() const +{ + if (check_exact(this)) + { + return list(detail::new_reference( + PyDict_Values(this->ptr()))); + } + else + { + return assume_list(this->attr("values")()); + } +} + +static struct register_dict_pytype_ptr +{ + register_dict_pytype_ptr() + { + const_cast<converter::registration &>( + converter::registry::lookup(boost::python::type_id<boost::python::dict>()) + ).m_class_object = &PyDict_Type; + } +}register_dict_pytype_ptr_; + +}}} // namespace boost::python |