mirror of
https://github.com/boostorg/python.git
synced 2026-01-24 18:12:43 +00:00
list implementation
[SVN r14261]
This commit is contained in:
1
Jamfile
1
Jamfile
@@ -13,6 +13,7 @@ if $(UNIX) && ( $(OS) = AIX )
|
||||
|
||||
dll bpl
|
||||
:
|
||||
src/list.cpp
|
||||
src/aix_init_module.cpp
|
||||
src/converter/from_python.cpp
|
||||
src/converter/registry.cpp
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
# include <boost/python/to_python_indirect.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/detail/convertible.hpp>
|
||||
# include <boost/python/detail/string_literal.hpp>
|
||||
# include <boost/python/base_type_traits.hpp>
|
||||
// Bring in specializations
|
||||
# include <boost/python/converter/builtin_converters.hpp>
|
||||
@@ -73,6 +74,11 @@ namespace detail
|
||||
template <class T>
|
||||
struct select_arg_to_python
|
||||
{
|
||||
// Special handling for char const[N]; interpret them as char
|
||||
// const* for the sake of conversion
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, is_string = python::detail::is_string_literal<T const>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, manager = is_object_manager<T>::value);
|
||||
|
||||
@@ -89,22 +95,27 @@ namespace detail
|
||||
typedef typename unwrap_pointer<T>::type unwrapped_ptr;
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
manager
|
||||
, object_manager_arg_to_python<T>
|
||||
is_string
|
||||
, arg_to_python<char const*>
|
||||
, typename mpl::select_type<
|
||||
ptr
|
||||
, pointer_deep_arg_to_python<T>
|
||||
manager
|
||||
, object_manager_arg_to_python<T>
|
||||
, typename mpl::select_type<
|
||||
ptr_wrapper
|
||||
, pointer_shallow_arg_to_python<unwrapped_ptr>
|
||||
ptr
|
||||
, pointer_deep_arg_to_python<T>
|
||||
, typename mpl::select_type<
|
||||
ref_wrapper
|
||||
, reference_arg_to_python<unwrapped_referent>
|
||||
, value_arg_to_python<T>
|
||||
ptr_wrapper
|
||||
, pointer_shallow_arg_to_python<unwrapped_ptr>
|
||||
, typename mpl::select_type<
|
||||
ref_wrapper
|
||||
, reference_arg_to_python<unwrapped_referent>
|
||||
, value_arg_to_python<T>
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
99
include/boost/python/converter/pytype_arg_from_python.hpp
Normal file
99
include/boost/python/converter/pytype_arg_from_python.hpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP
|
||||
# define PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
//
|
||||
// arg_from_python converters for Python type wrappers, to be used as
|
||||
// base classes for specializations.
|
||||
//
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <PyTypeObject* python_type>
|
||||
struct pytype_arg_from_python
|
||||
{
|
||||
pytype_arg_from_python(PyObject*);
|
||||
bool convertible() const;
|
||||
private:
|
||||
PyObject* m_src;
|
||||
};
|
||||
|
||||
// rvalue converter base
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
struct pytype_wrapper_value_arg_from_python
|
||||
: pytype_arg_from_python<python_type>
|
||||
{
|
||||
typedef Wrapper result_type;
|
||||
|
||||
pytype_wrapper_value_arg_from_python(PyObject*);
|
||||
Wrapper operator()(PyObject*) const;
|
||||
};
|
||||
|
||||
// Special case for Wrapper& - must store an lvalue internally. This
|
||||
// OK because the entire state of the object is actually in the Python
|
||||
// object.
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
struct pytype_wrapper_ref_arg_from_python
|
||||
: pytype_arg_from_python<python_type>
|
||||
{
|
||||
typedef Wrapper& result_type;
|
||||
|
||||
pytype_wrapper_ref_arg_from_python(PyObject*);
|
||||
Wrapper& operator()(PyObject*) const;
|
||||
private:
|
||||
mutable Wrapper m_result;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
|
||||
template <PyTypeObject* python_type>
|
||||
inline pytype_arg_from_python<python_type>::pytype_arg_from_python(PyObject* x)
|
||||
: m_src(x)
|
||||
{
|
||||
}
|
||||
|
||||
template <PyTypeObject* python_type>
|
||||
inline bool pytype_arg_from_python<python_type>::convertible() const
|
||||
{
|
||||
return PyObject_IsInstance(m_src, (PyObject*)python_type);
|
||||
}
|
||||
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
pytype_wrapper_value_arg_from_python<Wrapper,python_type>::pytype_wrapper_value_arg_from_python(
|
||||
PyObject* p)
|
||||
: pytype_arg_from_python<python_type>(p)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
Wrapper pytype_wrapper_value_arg_from_python<Wrapper,python_type>::operator()(
|
||||
PyObject* x) const
|
||||
{
|
||||
return Wrapper(python::detail::borrowed_reference(x));
|
||||
}
|
||||
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
pytype_wrapper_ref_arg_from_python<Wrapper,python_type>::pytype_wrapper_ref_arg_from_python(
|
||||
PyObject* p)
|
||||
: pytype_arg_from_python<python_type>(p)
|
||||
, m_result(python::detail::borrowed_reference(p))
|
||||
{
|
||||
}
|
||||
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
Wrapper& pytype_wrapper_ref_arg_from_python<Wrapper,python_type>::operator()(
|
||||
PyObject* x) const
|
||||
{
|
||||
return m_result;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP
|
||||
29
include/boost/python/detail/raw_pyobject.hpp
Normal file
29
include/boost/python/detail/raw_pyobject.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef RAW_PYOBJECT_DWA2002628_HPP
|
||||
# define RAW_PYOBJECT_DWA2002628_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
//
|
||||
// Define some types which we can use to get around the vagaries of
|
||||
// PyObject*. We will use these to initialize object instances, and
|
||||
// keep them in namespace detail to make sure they stay out of the
|
||||
// hands of users. That is much simpler than trying to grant
|
||||
// friendship to all the appropriate parties.
|
||||
//
|
||||
|
||||
// New references are checked for null
|
||||
struct new_reference_t;
|
||||
typedef new_reference_t* new_reference;
|
||||
|
||||
// Borrowed references are assumed to be non-null
|
||||
struct borrowed_reference_t;
|
||||
typedef borrowed_reference_t* borrowed_reference;
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // RAW_PYOBJECT_DWA2002628_HPP
|
||||
77
include/boost/python/detail/string_literal.hpp
Normal file
77
include/boost/python/detail/string_literal.hpp
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef STRING_LITERAL_DWA2002629_HPP
|
||||
# define STRING_LITERAL_DWA2002629_HPP
|
||||
|
||||
# include <cstddef>
|
||||
# include <boost/type.hpp>
|
||||
# include <boost/type_traits/array_traits.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct is_string_literal
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
# if !defined(__MWERKS__) || __MWERKS__ > 0x2407
|
||||
template <std::size_t n>
|
||||
struct is_string_literal<char const[n]>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
# else
|
||||
// CWPro7 has trouble with the array type deduction above
|
||||
template <class T, std::size_t n>
|
||||
struct is_string_literal<T[n]>
|
||||
: is_same<T, char const>
|
||||
{
|
||||
};
|
||||
# endif
|
||||
# else
|
||||
template <bool is_array = true>
|
||||
struct string_literal_helper
|
||||
{
|
||||
typedef char (&yes_string_literal)[1];
|
||||
typedef char (&no_string_literal)[2];
|
||||
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef apply<T> self;
|
||||
static T x;
|
||||
static yes_string_literal check(char const*);
|
||||
static no_string_literal check(char*);
|
||||
static no_string_literal check(void const volatile*);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = sizeof(self::check(x)) == sizeof(yes_string_literal));
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct string_literal_helper<false>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_string_literal
|
||||
: string_literal_helper<is_array<T>::value>::apply<T>
|
||||
{
|
||||
};
|
||||
# endif
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // STRING_LITERAL_DWA2002629_HPP
|
||||
179
include/boost/python/list.hpp
Normal file
179
include/boost/python/list.hpp
Normal file
@@ -0,0 +1,179 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef LIST_DWA2002627_HPP
|
||||
# define LIST_DWA2002627_HPP
|
||||
|
||||
# include <boost/python/object.hpp>
|
||||
# include <boost/python/converter/pytype_arg_from_python.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class list : public object
|
||||
{
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200
|
||||
typedef object const& object_cref;
|
||||
# else
|
||||
typedef object object_cref;
|
||||
# endif
|
||||
public:
|
||||
BOOST_PYTHON_DECL list(); // new list
|
||||
explicit BOOST_PYTHON_DECL list(object_cref sequence); // new list initialized from sequence's items
|
||||
|
||||
template <class T>
|
||||
explicit list(T const& sequence)
|
||||
: object(list::call(object(sequence)))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void append(object_cref); // append object to end
|
||||
|
||||
template <class T>
|
||||
void append(T const& x)
|
||||
{
|
||||
this->append(object(x));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL long count(object_cref value) const; // return number of occurrences of value
|
||||
|
||||
template <class T>
|
||||
long count(T const& value) const
|
||||
{
|
||||
return this->count(object(value));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void extend(object_cref sequence); // extend list by appending sequence elements
|
||||
|
||||
template <class T>
|
||||
void extend(T const& x)
|
||||
{
|
||||
this->extend(object(x));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL long index(object_cref value) const; // return index of first occurrence of value
|
||||
|
||||
template <class T>
|
||||
long index(T const& x) const
|
||||
{
|
||||
return this->index(object(x));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void insert(int index, object_cref); // insert object before index
|
||||
BOOST_PYTHON_DECL void insert(object const& index, object_cref);
|
||||
|
||||
template <class T>
|
||||
void insert(int index, T const& x) // insert object before index
|
||||
{
|
||||
this->insert(index, object(x));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void insert(object const& index, T const& x) // insert object before index
|
||||
{
|
||||
this->insert(index, object(x));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object pop(); // remove and return item at index (default last)
|
||||
BOOST_PYTHON_DECL object pop(long index);
|
||||
BOOST_PYTHON_DECL object pop(object const& index);
|
||||
|
||||
BOOST_PYTHON_DECL void remove(object_cref value); // remove first occurrence of value
|
||||
|
||||
template <class T>
|
||||
void remove(T const& value)
|
||||
{
|
||||
this->remove(object(value));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void reverse(); // reverse *IN PLACE*
|
||||
|
||||
BOOST_PYTHON_DECL void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1
|
||||
BOOST_PYTHON_DECL void sort(object_cref cmpfunc);
|
||||
|
||||
template <class T>
|
||||
void sort(T const& value)
|
||||
{
|
||||
this->sort(object(value));
|
||||
}
|
||||
|
||||
public: // implementation detail -- for internal use only
|
||||
explicit list(detail::borrowed_reference);
|
||||
explicit list(detail::new_reference);
|
||||
|
||||
private:
|
||||
static BOOST_PYTHON_DECL detail::new_reference call(object const&);
|
||||
};
|
||||
|
||||
//
|
||||
// Converter Specializations
|
||||
//
|
||||
template <class T> struct arg_from_python;
|
||||
|
||||
template <>
|
||||
struct arg_from_python<list>
|
||||
: converter::pytype_wrapper_value_arg_from_python<list, &PyList_Type>
|
||||
{
|
||||
typedef converter::pytype_wrapper_value_arg_from_python<list, &PyList_Type> base;
|
||||
typedef list result_type;
|
||||
|
||||
arg_from_python(PyObject* p) : base(p) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct arg_from_python<list const&>
|
||||
: arg_from_python<list>
|
||||
{
|
||||
arg_from_python(PyObject* p)
|
||||
: arg_from_python<list>(p) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct arg_from_python<list&>
|
||||
: converter::pytype_wrapper_ref_arg_from_python<list, &PyList_Type>
|
||||
{
|
||||
typedef converter::pytype_wrapper_ref_arg_from_python<list, &PyList_Type> base;
|
||||
typedef list result_type;
|
||||
|
||||
arg_from_python(PyObject* p)
|
||||
: base(p) {}
|
||||
};
|
||||
|
||||
namespace converter
|
||||
{
|
||||
template <class T> struct is_object_manager;
|
||||
|
||||
template <>
|
||||
struct is_object_manager<list>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T> struct return_from_python;
|
||||
template <>
|
||||
struct return_from_python<list>
|
||||
{
|
||||
typedef list result_type;
|
||||
|
||||
result_type operator()(PyObject* x) const
|
||||
{
|
||||
return list(python::detail::new_reference(x));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// list implementation
|
||||
//
|
||||
inline list::list(detail::borrowed_reference p)
|
||||
: object(p)
|
||||
{}
|
||||
|
||||
inline list::list(detail::new_reference p)
|
||||
: object(p)
|
||||
{}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // LIST_DWA2002627_HPP
|
||||
@@ -76,7 +76,7 @@ inline module& module::setattr(const char* name, handle<> const& x)
|
||||
|
||||
inline module& module::add(PyTypeObject* x)
|
||||
{
|
||||
this->base::add(x);
|
||||
this->base::add(handle<>(borrowed(x)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,14 +30,14 @@ struct attribute_policies : const_attribute_policies
|
||||
template <class U>
|
||||
inline object_attribute object_operators<U>::attr(char const* name)
|
||||
{
|
||||
object_cref x = *static_cast<U*>(this);
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_attribute(x, name);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
inline const_object_attribute object_operators<U>::attr(char const* name) const
|
||||
{
|
||||
object_cref x = *static_cast<U const*>(this);
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_attribute(x, name);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
# include <boost/python/call.hpp>
|
||||
# include <boost/preprocessor/max.hpp>
|
||||
# include <boost/python/slice_nil.hpp>
|
||||
# include <boost/python/detail/raw_pyobject.hpp>
|
||||
# include <boost/python/refcount.hpp>
|
||||
# include <boost/type.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
@@ -68,35 +70,8 @@ namespace api
|
||||
};
|
||||
# endif
|
||||
|
||||
//
|
||||
// object_handle -- get the handle to construct the object with,
|
||||
// based on whether T is a proxy or not
|
||||
//
|
||||
template <bool = false>
|
||||
struct object_handle
|
||||
{
|
||||
template <class T>
|
||||
static handle<> get(T const& x)
|
||||
{
|
||||
return handle<>(
|
||||
python::borrowed(
|
||||
python::allow_null( // null check is already done
|
||||
converter::arg_to_python<T>(x).get())
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct object_handle<true>
|
||||
{
|
||||
template <class Policies>
|
||||
static handle<> get(proxy<Policies> const& x)
|
||||
{
|
||||
return x.operator object().ptr();
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_proxy> struct object_initializer;
|
||||
|
||||
// A way to turn a conrete type T into a type dependent on U. This
|
||||
// keeps conforming compilers from complaining about returning an
|
||||
// incomplete T from a template member function (which must be
|
||||
@@ -108,24 +83,24 @@ namespace api
|
||||
};
|
||||
|
||||
class object;
|
||||
typedef handle<> const& (object::*bool_type)() const;
|
||||
typedef PyObject* (object::*bool_type)() const;
|
||||
|
||||
template <class U>
|
||||
class object_operators
|
||||
{
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200
|
||||
typedef object const& self_cref;
|
||||
typedef object const& object_cref;
|
||||
# else
|
||||
typedef object self_cref;
|
||||
typedef object object_cref;
|
||||
# endif
|
||||
|
||||
// there appears to be a codegen bug here. We prevent the early
|
||||
// destruction of a temporary in CWPro8 by binding a named
|
||||
// object instead.
|
||||
// there is a confirmed CWPro8 codegen bug here. We prevent the
|
||||
// early destruction of a temporary by binding a named object
|
||||
// instead.
|
||||
# if __MWERKS__ != 0x3000
|
||||
typedef object const& object_cref;
|
||||
typedef object const& object_cref2;
|
||||
# else
|
||||
typedef object const object_cref;
|
||||
typedef object const object_cref2;
|
||||
# endif
|
||||
|
||||
public:
|
||||
@@ -163,8 +138,8 @@ namespace api
|
||||
|
||||
// item access
|
||||
//
|
||||
const_object_item operator[](self_cref) const;
|
||||
object_item operator[](self_cref);
|
||||
const_object_item operator[](object_cref) const;
|
||||
object_item operator[](object_cref);
|
||||
|
||||
template <class T>
|
||||
const_object_item
|
||||
@@ -190,14 +165,14 @@ namespace api
|
||||
|
||||
// slicing
|
||||
//
|
||||
const_object_slice slice(self_cref, self_cref) const;
|
||||
object_slice slice(self_cref, self_cref);
|
||||
const_object_slice slice(object_cref, object_cref) const;
|
||||
object_slice slice(object_cref, object_cref);
|
||||
|
||||
const_object_slice slice(slice_nil, self_cref) const;
|
||||
object_slice slice(slice_nil, self_cref);
|
||||
const_object_slice slice(slice_nil, object_cref) const;
|
||||
object_slice slice(slice_nil, object_cref);
|
||||
|
||||
const_object_slice slice(self_cref, slice_nil) const;
|
||||
object_slice slice(self_cref, slice_nil);
|
||||
const_object_slice slice(object_cref, slice_nil) const;
|
||||
object_slice slice(object_cref, slice_nil);
|
||||
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
template <class T, class V>
|
||||
@@ -227,53 +202,69 @@ namespace api
|
||||
, slice_bound<V>::type(end));
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
# if BOOST_MSVC == 1200
|
||||
// For whatever reason, VC6 generates incorrect code unless we
|
||||
// define this
|
||||
object_operators& operator=(object_operators const&) { return *this; }
|
||||
# endif
|
||||
};
|
||||
|
||||
class object : public object_operators<object>
|
||||
{
|
||||
public:
|
||||
# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
// copy constructor without NULL checking, for efficiency
|
||||
// copy constructor without NULL checking, for efficiency. This
|
||||
// confuses VC6/7 so object_initializer also handles this case.
|
||||
object(object const&);
|
||||
# endif
|
||||
|
||||
// explicit conversion from any C++ object to Python
|
||||
template <class T>
|
||||
explicit object(T const& x)
|
||||
: m_ptr(object_handle<is_proxy<T>::value>::get(x))
|
||||
: m_ptr(object_initializer<is_proxy<T>::value>::get(
|
||||
x, detail::convertible<object const*>::check(&x)))
|
||||
{
|
||||
}
|
||||
|
||||
// capture this case explicitly to handle string
|
||||
// literals. Otherwise, they get deduced as char[N]const& above
|
||||
// and conversion fails at runtime.
|
||||
explicit object(char const* x)
|
||||
: m_ptr(object_handle<>::get(x))
|
||||
{
|
||||
}
|
||||
|
||||
// Throw error_already_set() if the handle is null.
|
||||
explicit object(handle<> const&);
|
||||
|
||||
// Underlying object access
|
||||
handle<> const& ptr() const;
|
||||
// Underlying object access -- returns a borrowed reference
|
||||
PyObject* ptr() const;
|
||||
|
||||
public: // implementation detail -- for internal use only
|
||||
object(null_ok<detail::borrowed<PyObject> >*);
|
||||
object(detail::borrowed<null_ok<PyObject> >*);
|
||||
object(detail::borrowed<PyObject>*);
|
||||
class new_pyobject_reference;
|
||||
object(new_pyobject_reference*);
|
||||
explicit object(detail::borrowed_reference);
|
||||
explicit object(detail::new_reference);
|
||||
|
||||
private:
|
||||
handle<> m_ptr;
|
||||
PyObject* m_ptr;
|
||||
};
|
||||
|
||||
//
|
||||
// object_initializer -- get the handle to construct the object with,
|
||||
// based on whether T is a proxy or derived from object
|
||||
//
|
||||
template <bool is_proxy = false>
|
||||
struct object_initializer
|
||||
{
|
||||
static PyObject*
|
||||
get(object const& x, detail::yes_convertible)
|
||||
{
|
||||
return python::incref(x.ptr());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static PyObject*
|
||||
get(T const& x, detail::no_convertible)
|
||||
{
|
||||
return python::incref(converter::arg_to_python<T>(x).get());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct object_initializer<true>
|
||||
{
|
||||
template <class Policies>
|
||||
static PyObject*
|
||||
get(proxy<Policies> const& x, detail::no_convertible)
|
||||
{
|
||||
return python::incref(x.operator object().ptr());
|
||||
}
|
||||
};
|
||||
}
|
||||
using api::object;
|
||||
@@ -336,39 +327,32 @@ namespace converter
|
||||
//
|
||||
|
||||
inline object::object(handle<> const& x)
|
||||
: m_ptr(python::borrowed(x.get()))
|
||||
: m_ptr(incref(expect_non_null(x.get())))
|
||||
{}
|
||||
|
||||
# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
// copy constructor without NULL checking, for efficiency
|
||||
inline object::object(object const& rhs)
|
||||
: m_ptr(python::allow_null(python::borrowed(rhs.m_ptr.get())))
|
||||
: m_ptr(incref(rhs.m_ptr))
|
||||
{}
|
||||
# endif
|
||||
|
||||
inline object::object(null_ok<detail::borrowed<PyObject> >* p)
|
||||
: m_ptr(p)
|
||||
inline object::object(detail::borrowed_reference p)
|
||||
: m_ptr(incref((PyObject*)p))
|
||||
{}
|
||||
|
||||
inline object::object(detail::borrowed<null_ok<PyObject> >* p)
|
||||
: m_ptr(p)
|
||||
|
||||
inline object::object(detail::new_reference p)
|
||||
: m_ptr(expect_non_null((PyObject*)p))
|
||||
{}
|
||||
|
||||
inline object::object(detail::borrowed<PyObject>* p)
|
||||
: m_ptr(p)
|
||||
{}
|
||||
|
||||
inline object::object(object::new_pyobject_reference* p)
|
||||
: m_ptr((PyObject*)p)
|
||||
{}
|
||||
|
||||
inline handle<> const& object::ptr() const
|
||||
inline PyObject* object::ptr() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
//
|
||||
// Converter speciaization implementations
|
||||
// Converter specialization implementations
|
||||
//
|
||||
inline arg_from_python<object>::arg_from_python(PyObject*)
|
||||
{}
|
||||
@@ -380,7 +364,7 @@ inline bool arg_from_python<object>::convertible() const
|
||||
|
||||
inline object arg_from_python<object>::operator()(PyObject* x) const
|
||||
{
|
||||
return object(python::borrowed(python::allow_null(x)));
|
||||
return object(detail::borrowed_reference(x));
|
||||
}
|
||||
|
||||
inline arg_from_python<object const&>::arg_from_python(PyObject*)
|
||||
@@ -388,7 +372,7 @@ inline arg_from_python<object const&>::arg_from_python(PyObject*)
|
||||
{}
|
||||
|
||||
inline arg_from_python<object&>::arg_from_python(PyObject* x)
|
||||
: m_result(python::allow_null(python::borrowed(x)))
|
||||
: m_result(detail::borrowed_reference(x))
|
||||
{}
|
||||
|
||||
inline bool arg_from_python<object&>::convertible() const
|
||||
@@ -406,12 +390,12 @@ namespace converter
|
||||
inline object
|
||||
return_from_python<object>::operator()(PyObject* x) const
|
||||
{
|
||||
return object((object::new_pyobject_reference*)x);
|
||||
return object(python::detail::new_reference(x));
|
||||
}
|
||||
|
||||
inline PyObject* get_managed_object(object const& x)
|
||||
{
|
||||
return x.ptr().get();
|
||||
return x.ptr();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,17 +29,17 @@ struct item_policies : const_item_policies
|
||||
//
|
||||
template <class U>
|
||||
inline object_item
|
||||
object_operators<U>::operator[](self_cref key)
|
||||
object_operators<U>::operator[](object_cref key)
|
||||
{
|
||||
object_cref x = *static_cast<U*>(this);
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_item(x, key);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
inline const_object_item
|
||||
object_operators<U>::operator[](self_cref key) const
|
||||
object_operators<U>::operator[](object_cref key) const
|
||||
{
|
||||
object_cref x = *static_cast<U const*>(this);
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_item(x, key);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ template <class U>
|
||||
object object_operators<U>::operator()() const
|
||||
{
|
||||
object const& f = *static_cast<U const*>(this);
|
||||
return call<object>(f.ptr().get());
|
||||
return call<object>(f.ptr());
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ inline
|
||||
object_operators<U>::operator bool_type() const
|
||||
{
|
||||
object const& x = *static_cast<U const*>(this);
|
||||
return PyObject_IsTrue(x.ptr().get()) ? &object::ptr : 0;
|
||||
return PyObject_IsTrue(x.ptr()) ? &object::ptr : 0;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -31,7 +31,7 @@ inline bool
|
||||
object_operators<U>::operator!() const
|
||||
{
|
||||
object const& x = *static_cast<U const*>(this);
|
||||
return !PyObject_IsTrue(x.ptr().get());
|
||||
return !PyObject_IsTrue(x.ptr());
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_COMPARE_OP(op, opid) \
|
||||
@@ -39,7 +39,7 @@ template <class L, class R> \
|
||||
bool operator op(L const& l, R const& r) \
|
||||
{ \
|
||||
return PyObject_RichCompareBool( \
|
||||
object(l).ptr().get(), object(r).ptr().get(), opid); \
|
||||
object(l).ptr(), object(r).ptr(), opid); \
|
||||
}
|
||||
BOOST_PYTHON_COMPARE_OP(>, Py_GT)
|
||||
BOOST_PYTHON_COMPARE_OP(>=, Py_GE)
|
||||
|
||||
@@ -30,50 +30,50 @@ struct slice_policies : const_slice_policies
|
||||
//
|
||||
template <class U>
|
||||
object_slice
|
||||
object_operators<U>::slice(self_cref start, self_cref finish)
|
||||
object_operators<U>::slice(object_cref start, object_cref finish)
|
||||
{
|
||||
object_cref x = *static_cast<U*>(this);
|
||||
return object_slice(x, std::make_pair(start.ptr(), finish.ptr()));
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
const_object_slice
|
||||
object_operators<U>::slice(self_cref start, self_cref finish) const
|
||||
object_operators<U>::slice(object_cref start, object_cref finish) const
|
||||
{
|
||||
object_cref x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, std::make_pair(start.ptr(), finish.ptr()));
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
object_slice
|
||||
object_operators<U>::slice(slice_nil, self_cref finish)
|
||||
object_operators<U>::slice(slice_nil, object_cref finish)
|
||||
{
|
||||
object_cref x = *static_cast<U*>(this);
|
||||
return object_slice(x, std::make_pair(handle<>(), finish.ptr()));
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
const_object_slice
|
||||
object_operators<U>::slice(slice_nil, self_cref finish) const
|
||||
object_operators<U>::slice(slice_nil, object_cref finish) const
|
||||
{
|
||||
object_cref x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, std::make_pair(handle<>(), finish.ptr()));
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr())));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
object_slice
|
||||
object_operators<U>::slice(self_cref start, slice_nil)
|
||||
object_operators<U>::slice(object_cref start, slice_nil)
|
||||
{
|
||||
object_cref x = *static_cast<U*>(this);
|
||||
return object_slice(x, std::make_pair(start.ptr(), handle<>()));
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
const_object_slice
|
||||
object_operators<U>::slice(self_cref start, slice_nil) const
|
||||
object_operators<U>::slice(object_cref start, slice_nil) const
|
||||
{
|
||||
object_cref x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, std::make_pair(start.ptr(), handle<>()));
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
}
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
template <class U>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
# ifdef BOOST_PYTHON_V2
|
||||
# include <boost/python/objects2.hpp>
|
||||
# include <boost/python/list.hpp>
|
||||
# else
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class list;
|
||||
|
||||
class BOOST_PYTHON_DECL objects_base
|
||||
{
|
||||
public:
|
||||
@@ -97,67 +99,6 @@ class tuple : public tuple_base
|
||||
}
|
||||
};
|
||||
|
||||
class list;
|
||||
|
||||
struct BOOST_PYTHON_DECL list_proxy;
|
||||
struct BOOST_PYTHON_DECL list_slice_proxy;
|
||||
|
||||
class BOOST_PYTHON_DECL list_base : public objects_base
|
||||
{
|
||||
protected:
|
||||
typedef list_proxy proxy;
|
||||
typedef list_slice_proxy slice_proxy;
|
||||
public:
|
||||
explicit list_base(handle<> p);
|
||||
explicit list_base(std::size_t sz = 0);
|
||||
static PyTypeObject* type_obj();
|
||||
static bool accepts(handle<> p);
|
||||
std::size_t size() const;
|
||||
handle<> operator[](std::size_t pos) const;
|
||||
proxy operator[](std::size_t pos);
|
||||
handle<> get_item(std::size_t pos) const;
|
||||
|
||||
void set_item(std::size_t pos, const handle<>& );
|
||||
|
||||
// void set_item(std::size_t pos, const object& );
|
||||
|
||||
void insert(std::size_t index, const handle<>& item);
|
||||
|
||||
void push_back(const handle<>& item);
|
||||
|
||||
void append(const handle<>& item);
|
||||
|
||||
list slice(int low, int high) const;
|
||||
slice_proxy slice(int low, int high);
|
||||
void sort();
|
||||
void reverse();
|
||||
tuple as_tuple() const;
|
||||
};
|
||||
|
||||
class list : public list_base
|
||||
{
|
||||
public:
|
||||
explicit list(handle<> p) : list_base(p) {}
|
||||
explicit list(std::size_t sz = 0) : list_base(sz) {}
|
||||
template <class T>
|
||||
void set_item(std::size_t pos, const T& x)
|
||||
{ this->set_item(pos, make_ref(x)); }
|
||||
template <class T>
|
||||
void insert(std::size_t index, const T& x)
|
||||
{ this->insert(index, make_ref(x)); }
|
||||
template <class T>
|
||||
void push_back(const T& item)
|
||||
{ this->push_back(make_ref(item)); }
|
||||
template <class T>
|
||||
void append(const T& item)
|
||||
{ this->append(make_ref(item)); }
|
||||
|
||||
void set_item(std::size_t pos, const handle<>& x) { list_base::set_item(pos, x); }
|
||||
void insert(std::size_t index, const handle<>& item) { list_base::insert(index, item); }
|
||||
void push_back(const handle<>& item) { list_base::push_back(item); }
|
||||
void append(const handle<>& item) { list_base::append(item); }
|
||||
};
|
||||
|
||||
class BOOST_PYTHON_DECL string
|
||||
: public objects_base, public boost::multipliable2<string, unsigned int>
|
||||
{
|
||||
@@ -306,43 +247,6 @@ class dictionary : public dictionary_base
|
||||
{ dictionary_base::erase(key); }
|
||||
};
|
||||
|
||||
struct BOOST_PYTHON_DECL list_proxy
|
||||
{
|
||||
template <class T>
|
||||
const handle<>& operator=(const T& rhs)
|
||||
{ return (*this) = make_ref(rhs); }
|
||||
const handle<>& operator=(const handle<>& rhs);
|
||||
|
||||
operator handle<>() const;
|
||||
|
||||
private:
|
||||
friend class list_base;
|
||||
list_proxy(const handle<>& list, std::size_t index);
|
||||
|
||||
// This is needed to work around the very strange MSVC error report that the
|
||||
// return type of the built-in operator= differs from that of the ones
|
||||
// defined above. Couldn't hurt to make these un-assignable anyway, though.
|
||||
const handle<>& operator=(const list_proxy&); // Not actually implemented
|
||||
private:
|
||||
list m_list;
|
||||
std::size_t m_index;
|
||||
};
|
||||
|
||||
struct BOOST_PYTHON_DECL list_slice_proxy
|
||||
{
|
||||
const list& operator=(const list& rhs);
|
||||
operator handle<>() const;
|
||||
operator list() const;
|
||||
std::size_t size() const;
|
||||
handle<> operator[](std::size_t pos) const;
|
||||
private:
|
||||
friend class list_base;
|
||||
list_slice_proxy(const handle<>& list, int low, int high);
|
||||
private:
|
||||
handle<> m_list;
|
||||
int m_low, m_high;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // OBJECTS_DWA20020611_H
|
||||
|
||||
@@ -73,10 +73,10 @@ inline proxy<Policies> const& proxy<Policies>::operator=(typename proxy::copy_ct
|
||||
|
||||
# define BOOST_PYTHON_PROXY_INPLACE(op) \
|
||||
template <class Policies, class R> \
|
||||
proxy<Policies> const& operator op(proxy<Policies> const& lhs, R const& other) \
|
||||
proxy<Policies> const& operator op(proxy<Policies> const& lhs, R const& rhs) \
|
||||
{ \
|
||||
object old(lhs); \
|
||||
return lhs = (old op other); \
|
||||
return lhs = (old op rhs); \
|
||||
}
|
||||
BOOST_PYTHON_PROXY_INPLACE(+=)
|
||||
BOOST_PYTHON_PROXY_INPLACE(-=)
|
||||
|
||||
105
src/list.cpp
Normal file
105
src/list.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/list.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
BOOST_PYTHON_DECL detail::new_reference list::call(object const& arg)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyList_Type, "(O)",
|
||||
arg.ptr());
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL list::list()
|
||||
: object(detail::new_reference(PyList_New(0)))
|
||||
{}
|
||||
|
||||
BOOST_PYTHON_DECL list::list(object_cref sequence)
|
||||
: object(list::call(sequence))
|
||||
{}
|
||||
|
||||
BOOST_PYTHON_DECL void list::append(object_cref x)
|
||||
{
|
||||
if (PyList_Append(this->ptr(), x.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL long list::count(object_cref value) const
|
||||
{
|
||||
object result_obj(this->attr("count")(value));
|
||||
long result = PyInt_AsLong(result_obj.ptr());
|
||||
if (result == -1)
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void list::extend(object_cref sequence)
|
||||
{
|
||||
this->attr("extend")(sequence);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL long list::index(object_cref value) const
|
||||
{
|
||||
object result_obj(this->attr("index")(value));
|
||||
long result = PyInt_AsLong(result_obj.ptr());
|
||||
if (result == -1)
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void list::insert(int index, object_cref item)
|
||||
{
|
||||
if (PyList_Insert(this->ptr(), index, item.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void list::insert(object const& index, object_cref x)
|
||||
{
|
||||
long index_ = PyInt_AsLong(index.ptr());
|
||||
if (index_ == -1 && PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
this->insert(index_, x);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object list::pop()
|
||||
{
|
||||
return this->attr("pop")();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object list::pop(long index)
|
||||
{
|
||||
return this->pop(object(index));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object list::pop(object const& index)
|
||||
{
|
||||
return this->attr("pop")(index);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void list::remove(object_cref value)
|
||||
{
|
||||
this->attr("remove")(value);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void list::reverse()
|
||||
{
|
||||
if (PyList_Reverse(this->ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void list::sort()
|
||||
{
|
||||
if (PyList_Sort(this->ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void list::sort(object_cref cmpfunc)
|
||||
{
|
||||
this->attr("sort")(cmpfunc);
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
@@ -5,7 +5,7 @@
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
#include <boost/python/object/class.hpp>
|
||||
#include <boost/python/objects.hpp>
|
||||
#include <boost/python/objects2.hpp>
|
||||
#include <boost/python/detail/map_entry.hpp>
|
||||
#include <boost/detail/binary_search.hpp>
|
||||
#include <boost/python/self.hpp>
|
||||
@@ -210,7 +210,7 @@ namespace objects
|
||||
type_handle query(class_id id) const;
|
||||
void set(class_id, type_handle class_object);
|
||||
private:
|
||||
typedef detail::map_entry<class_id,type_handle> entry;
|
||||
typedef python::detail::map_entry<class_id,type_handle> entry;
|
||||
std::vector<entry> m_impl;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <boost/python/object/function.hpp>
|
||||
#include <numeric>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/objects.hpp>
|
||||
#include <boost/python/objects2.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/object_operators.hpp>
|
||||
#include <boost/python/detail/raw_pyobject.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace api {
|
||||
|
||||
@@ -12,8 +13,9 @@ namespace boost { namespace python { namespace api {
|
||||
BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \
|
||||
{ \
|
||||
return object( \
|
||||
(object::new_pyobject_reference*) \
|
||||
PyNumber_##name(l.ptr().get(), r.ptr().get())); \
|
||||
detail::new_reference( \
|
||||
PyNumber_##name(l.ptr(), r.ptr())) \
|
||||
); \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_BINARY_OPERATOR(+, Add)
|
||||
@@ -32,8 +34,8 @@ BOOST_PYTHON_BINARY_OPERATOR(|, Or)
|
||||
BOOST_PYTHON_DECL object& operator op##=(object& l, object const& r) \
|
||||
{ \
|
||||
return l = object( \
|
||||
(object::new_pyobject_reference*) \
|
||||
PyNumber_InPlace##name(l.ptr().get(), r.ptr().get())); \
|
||||
(detail::new_reference) \
|
||||
PyNumber_InPlace##name(l.ptr(), r.ptr())); \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(+, Add)
|
||||
|
||||
@@ -12,33 +12,33 @@ namespace boost { namespace python { namespace api {
|
||||
|
||||
BOOST_PYTHON_DECL object getattr(object const& target, object const& key)
|
||||
{
|
||||
return object((object::new_pyobject_reference*)PyObject_GetAttr(target.ptr().get(), key.ptr().get()));
|
||||
return object(detail::new_reference(PyObject_GetAttr(target.ptr(), key.ptr())));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value)
|
||||
{
|
||||
if (PyObject_SetAttr(target.ptr().get(), key.ptr().get(), value.ptr().get()) == -1)
|
||||
if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void delattr(object const& target, object const& key)
|
||||
{
|
||||
if (PyObject_DelAttr(target.ptr().get(), key.ptr().get()) == -1)
|
||||
if (PyObject_DelAttr(target.ptr(), key.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object getattr(object const& target, char const* key)
|
||||
{
|
||||
return object(
|
||||
(object::new_pyobject_reference*)
|
||||
PyObject_GetAttrString(target.ptr().get(), const_cast<char*>(key))
|
||||
);
|
||||
detail::new_reference(
|
||||
PyObject_GetAttrString(target.ptr(), const_cast<char*>(key))
|
||||
));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value)
|
||||
{
|
||||
if (PyObject_SetAttrString(
|
||||
target.ptr().get(), const_cast<char*>(key), value.ptr().get()) == -1
|
||||
target.ptr(), const_cast<char*>(key), value.ptr()) == -1
|
||||
)
|
||||
{
|
||||
throw_error_already_set();
|
||||
@@ -48,7 +48,7 @@ BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object con
|
||||
BOOST_PYTHON_DECL void delattr(object const& target, char const* key)
|
||||
{
|
||||
if (PyObject_DelAttrString(
|
||||
target.ptr().get(), const_cast<char*>(key)) == -1
|
||||
target.ptr(), const_cast<char*>(key)) == -1
|
||||
)
|
||||
{
|
||||
throw_error_already_set();
|
||||
@@ -57,18 +57,19 @@ BOOST_PYTHON_DECL void delattr(object const& target, char const* key)
|
||||
|
||||
BOOST_PYTHON_DECL object getitem(object const& target, object const& key)
|
||||
{
|
||||
return object((object::new_pyobject_reference*)PyObject_GetItem(target.ptr().get(), key.ptr().get()));
|
||||
return object(detail::new_reference(
|
||||
PyObject_GetItem(target.ptr(), key.ptr())));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value)
|
||||
{
|
||||
if (PyObject_SetItem(target.ptr().get(), key.ptr().get(), value.ptr().get()) == -1)
|
||||
if (PyObject_SetItem(target.ptr(), key.ptr(), value.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void delitem(object const& target, object const& key)
|
||||
{
|
||||
if (PyObject_DelItem(target.ptr().get(), key.ptr().get()) == -1)
|
||||
if (PyObject_DelItem(target.ptr(), key.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
@@ -141,14 +142,14 @@ namespace // slicing code copied directly out of the Python implementation
|
||||
BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end)
|
||||
{
|
||||
return object(
|
||||
(object::new_pyobject_reference*)
|
||||
apply_slice(target.ptr().get(), begin.get(), end.get()));
|
||||
detail::new_reference(
|
||||
apply_slice(target.ptr(), begin.get(), end.get())));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value)
|
||||
{
|
||||
if (assign_slice(
|
||||
target.ptr().get(), begin.get(), end.get(), value.ptr().get()) == -1
|
||||
target.ptr(), begin.get(), end.get(), value.ptr()) == -1
|
||||
)
|
||||
{
|
||||
throw_error_already_set();
|
||||
@@ -158,7 +159,7 @@ BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, han
|
||||
BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end)
|
||||
{
|
||||
if (assign_slice(
|
||||
target.ptr().get(), begin.get(), end.get(), 0) == -1
|
||||
target.ptr(), begin.get(), end.get(), 0) == -1
|
||||
)
|
||||
{
|
||||
throw_error_already_set();
|
||||
|
||||
147
src/objects2.cpp
147
src/objects2.cpp
@@ -276,151 +276,4 @@ tuple operator+(const tuple& x, const tuple& y)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
list_base::list_base(handle<> p)
|
||||
: objects_base(p)
|
||||
{
|
||||
assert(accepts(p));
|
||||
if (!accepts(p))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
list_base::list_base(std::size_t sz)
|
||||
: objects_base(handle<>(PyList_New(sz)))
|
||||
{
|
||||
}
|
||||
|
||||
PyTypeObject* list_base::type_obj()
|
||||
{
|
||||
return &PyList_Type;
|
||||
}
|
||||
|
||||
bool list_base::accepts(handle<> p)
|
||||
{
|
||||
return PyList_Check(p.get());
|
||||
}
|
||||
|
||||
std::size_t list_base::size() const
|
||||
{
|
||||
return PyList_Size(get());
|
||||
}
|
||||
|
||||
handle<> list_base::operator[](std::size_t pos) const
|
||||
{
|
||||
return handle<>(borrowed(PyList_GetItem(get(), pos)));
|
||||
}
|
||||
|
||||
list_proxy list_base::operator[](std::size_t pos)
|
||||
{
|
||||
return proxy(reference(), pos);
|
||||
}
|
||||
|
||||
void list_base::insert(std::size_t index, const handle<>& item)
|
||||
{
|
||||
if (PyList_Insert(get(), index, item.get()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
void list_base::push_back(const handle<>& item)
|
||||
{
|
||||
if (PyList_Append(get(), item.get()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
void list_base::append(const handle<>& item)
|
||||
{
|
||||
this->push_back(item);
|
||||
}
|
||||
|
||||
list list_base::slice(int low, int high) const
|
||||
{
|
||||
return list(handle<>(PyList_GetSlice(get(), low, high)));
|
||||
}
|
||||
|
||||
list_slice_proxy list_base::slice(int low, int high)
|
||||
{
|
||||
return list_slice_proxy(reference(), low, high);
|
||||
}
|
||||
|
||||
void list_base::sort()
|
||||
{
|
||||
if (PyList_Sort(get()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
void list_base::reverse()
|
||||
{
|
||||
if (PyList_Reverse(get()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
tuple list_base::as_tuple() const
|
||||
{
|
||||
return tuple(handle<>(PyList_AsTuple(get())));
|
||||
}
|
||||
|
||||
const handle<>& list_proxy::operator=(const handle<>& rhs)
|
||||
{
|
||||
m_list.set_item(m_index, rhs);
|
||||
return rhs;
|
||||
}
|
||||
|
||||
list_proxy::operator handle<>() const
|
||||
{
|
||||
return handle<>(borrowed(PyList_GetItem(m_list.get(), m_index)));
|
||||
}
|
||||
|
||||
handle<> list_base::get_item(std::size_t pos) const
|
||||
{
|
||||
return handle<>(borrowed(PyList_GetItem(this->get(), pos)));
|
||||
}
|
||||
|
||||
void list_base::set_item(std::size_t pos, const handle<>& rhs)
|
||||
{
|
||||
int result = PyList_SetItem(this->get(), pos, rhs.get());
|
||||
if (result == -1)
|
||||
throw_error_already_set();
|
||||
Py_INCREF(rhs.get());
|
||||
}
|
||||
|
||||
list_proxy::list_proxy(const handle<>& list, std::size_t index)
|
||||
: m_list(list), m_index(index)
|
||||
{
|
||||
}
|
||||
|
||||
const list& list_slice_proxy::operator=(const list& rhs)
|
||||
{
|
||||
if (PyList_SetSlice(m_list.get(), m_low, m_high, rhs.get()) == -1)
|
||||
throw_error_already_set();
|
||||
return rhs;
|
||||
}
|
||||
|
||||
list_slice_proxy::operator handle<>() const
|
||||
{
|
||||
return handle<>(PyList_GetSlice(m_list.get(), m_low, m_high));
|
||||
}
|
||||
|
||||
list_slice_proxy::operator list() const
|
||||
{
|
||||
return list(this->operator handle<>());
|
||||
}
|
||||
|
||||
std::size_t list_slice_proxy::size() const
|
||||
{
|
||||
return this->operator list().size();
|
||||
}
|
||||
|
||||
handle<> list_slice_proxy::operator[](std::size_t pos) const
|
||||
{
|
||||
return this->operator list()[pos].operator handle<>();
|
||||
}
|
||||
|
||||
list_slice_proxy::list_slice_proxy(const handle<>& list, int low, int high)
|
||||
: m_list(list), m_low(low), m_high(high)
|
||||
{
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
@@ -62,6 +62,7 @@ bpl-test test_pointer_adoption ;
|
||||
bpl-test operators ;
|
||||
bpl-test callbacks ;
|
||||
bpl-test object ;
|
||||
bpl-test list ;
|
||||
bpl-test virtual_functions ;
|
||||
bpl-test back_reference ;
|
||||
bpl-test implicit ;
|
||||
@@ -88,6 +89,7 @@ run bases.cpp ;
|
||||
run if_else.cpp ;
|
||||
run pointee.cpp ;
|
||||
run result.cpp ;
|
||||
compile string_literal.cpp ;
|
||||
compile borrowed.cpp : $(PYTHON_PROPERTIES) ;
|
||||
compile object_manager.cpp : $(PYTHON_PROPERTIES) ;
|
||||
|
||||
|
||||
131
test/list.cpp
Normal file
131
test/list.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/list.hpp>
|
||||
#include <boost/python/make_function.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
object new_list()
|
||||
{
|
||||
return list();
|
||||
}
|
||||
|
||||
list listify(object x)
|
||||
{
|
||||
return list(x);
|
||||
}
|
||||
|
||||
object listify_string(char const* s)
|
||||
{
|
||||
return list(s);
|
||||
}
|
||||
|
||||
std::string x_rep(test_class<> const& x)
|
||||
{
|
||||
return "X(" + boost::lexical_cast<std::string>(x.value()) + ")";
|
||||
}
|
||||
|
||||
object apply_object_list(object f, list x)
|
||||
{
|
||||
return f(x);
|
||||
}
|
||||
|
||||
void append_object(list& x, object y)
|
||||
{
|
||||
x.append(y);
|
||||
}
|
||||
|
||||
void append_list(list& x, list const& y)
|
||||
{
|
||||
x.append(y);
|
||||
}
|
||||
|
||||
typedef test_class<> X;
|
||||
|
||||
int notcmp(object const& x, object const& y)
|
||||
{
|
||||
return y < x ? -1 : y > x ? 1 : 0;
|
||||
}
|
||||
|
||||
void exercise(list x, object y, object print)
|
||||
{
|
||||
x.append(y);
|
||||
x.append(5);
|
||||
x.append(X(3));
|
||||
|
||||
print("after append:");
|
||||
print(x);
|
||||
|
||||
print("number of", y, "instances:", x.count(y));
|
||||
|
||||
print("number of 5s:", x.count(5));
|
||||
|
||||
x.extend("xyz");
|
||||
print("after extend:");
|
||||
print(x);
|
||||
print("index of", y, "is:", x.index(y));
|
||||
print("index of 'l' is:", x.index("l"));
|
||||
|
||||
x.insert(4, 666);
|
||||
print("after inserting 666:");
|
||||
print(x);
|
||||
print("inserting with object as index:");
|
||||
x.insert(x[x.index(5)], "---");
|
||||
print(x);
|
||||
|
||||
print("popping...");
|
||||
x.pop();
|
||||
print(x);
|
||||
x.pop(x[x.index(5)]);
|
||||
print(x);
|
||||
x.pop(x.index(5));
|
||||
print(x);
|
||||
|
||||
print("removing", y);
|
||||
x.remove(y);
|
||||
print(x);
|
||||
print("removing", 666);
|
||||
x.remove(666);
|
||||
print(x);
|
||||
|
||||
print("reversing...");
|
||||
x.reverse();
|
||||
print(x);
|
||||
|
||||
print("sorted:");
|
||||
x.pop(2); // make sorting predictable
|
||||
x.sort();
|
||||
print(x);
|
||||
|
||||
print("reverse sorted:");
|
||||
x.sort(handle<>(make_function(notcmp)));
|
||||
print(x);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(list_ext)
|
||||
{
|
||||
module("list_ext")
|
||||
.def("new_list", new_list)
|
||||
.def("listify", listify)
|
||||
.def("listify_string", listify_string)
|
||||
.def("apply_object_list", apply_object_list)
|
||||
|
||||
.def("append_object", append_object)
|
||||
.def("append_list", append_list)
|
||||
|
||||
.def("exercise", exercise)
|
||||
|
||||
.add(class_<X>("X")
|
||||
.def_init(args<int>())
|
||||
.def( "__repr__", x_rep))
|
||||
;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user