1 // Copyright David Abrahams 2002.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 #include <boost/python/list.hpp>
6 #include <boost/python/ssize_t.hpp>
7
8 namespace boost { namespace python { namespace detail {
9
10
call(object const & arg_)11 detail::new_non_null_reference list_base::call(object const& arg_)
12 {
13 return (detail::new_non_null_reference)
14 (expect_non_null)(
15 PyObject_CallFunction(
16 (PyObject*)&PyList_Type, const_cast<char*>("(O)"),
17 arg_.ptr()));
18 }
19
list_base()20 list_base::list_base()
21 : object(detail::new_reference(PyList_New(0)))
22 {}
23
list_base(object_cref sequence)24 list_base::list_base(object_cref sequence)
25 : object(list_base::call(sequence))
26 {}
27
append(object_cref x)28 void list_base::append(object_cref x)
29 {
30 if (PyList_CheckExact(this->ptr()))
31 {
32 if (PyList_Append(this->ptr(), x.ptr()) == -1)
33 throw_error_already_set();
34 }
35 else
36 {
37 this->attr("append")(x);
38 }
39 }
40
41 //long list_base::count(object_cref value) const;
42
extend(object_cref sequence)43 void list_base::extend(object_cref sequence)
44 {
45 this->attr("extend")(sequence);
46 }
47
index(object_cref value) const48 long list_base::index(object_cref value) const
49 {
50 object result_obj(this->attr("index")(value));
51 #if PY_VERSION_HEX >= 0x03000000
52 ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
53 #else
54 long result = PyInt_AsLong(result_obj.ptr());
55 #endif
56 if (result == -1)
57 throw_error_already_set();
58 return result;
59 }
60
insert(ssize_t index,object_cref item)61 void list_base::insert(ssize_t index, object_cref item)
62 {
63 if (PyList_CheckExact(this->ptr()))
64 {
65 if (PyList_Insert(this->ptr(), index, item.ptr()) == -1)
66 throw_error_already_set();
67 }
68 else
69 {
70 this->attr("insert")(index, item);
71 }
72 }
73
insert(object const & index,object_cref x)74 void list_base::insert(object const& index, object_cref x)
75 {
76 #if PY_VERSION_HEX >= 0x03000000
77 ssize_t index_ = PyLong_AsSsize_t(index.ptr());
78 #else
79 long index_ = PyInt_AsLong(index.ptr());
80 #endif
81 if (index_ == -1 && PyErr_Occurred())
82 throw_error_already_set();
83 this->insert(index_, x);
84 }
85
pop()86 object list_base::pop()
87 {
88 return this->attr("pop")();
89 }
90
pop(ssize_t index)91 object list_base::pop(ssize_t index)
92 {
93 return this->pop(object(index));
94 }
95
pop(object const & index)96 object list_base::pop(object const& index)
97 {
98 return this->attr("pop")(index);
99 }
100
remove(object_cref value)101 void list_base::remove(object_cref value)
102 {
103 this->attr("remove")(value);
104 }
105
reverse()106 void list_base::reverse()
107 {
108 if (PyList_CheckExact(this->ptr()))
109 {
110 if (PyList_Reverse(this->ptr()) == -1)
111 throw_error_already_set();
112 }
113 else
114 {
115 this->attr("reverse")();
116 }
117 }
118
sort()119 void list_base::sort()
120 {
121 if (PyList_CheckExact(this->ptr()))
122 {
123 if (PyList_Sort(this->ptr()) == -1)
124 throw_error_already_set();
125 }
126 else
127 {
128 this->attr("sort")();
129 }
130 }
131
132 #if PY_VERSION_HEX >= 0x03000000
sort(args_proxy const & args,kwds_proxy const & kwds)133 void list_base::sort(args_proxy const &args,
134 kwds_proxy const &kwds)
135 {
136 this->attr("sort")(args, kwds);
137 }
138 #else
sort(object_cref cmpfunc)139 void list_base::sort(object_cref cmpfunc)
140 {
141 this->attr("sort")(cmpfunc);
142 }
143 #endif
144
145 // For some reason, moving this to the end of the TU suppresses an ICE
146 // with vc6.
count(object_cref value) const147 ssize_t list_base::count(object_cref value) const
148 {
149 object result_obj(this->attr("count")(value));
150 #if PY_VERSION_HEX >= 0x03000000
151 ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
152 #else
153 long result = PyInt_AsLong(result_obj.ptr());
154 #endif
155 if (result == -1)
156 throw_error_already_set();
157 return result;
158 }
159
160 static struct register_list_pytype_ptr
161 {
register_list_pytype_ptrboost::python::detail::register_list_pytype_ptr162 register_list_pytype_ptr()
163 {
164 const_cast<converter::registration &>(
165 converter::registry::lookup(boost::python::type_id<boost::python::list>())
166 ).m_class_object = &PyList_Type;
167 }
168 }register_list_pytype_ptr_;
169
170 }}} // namespace boost::python
171