Library of Assembled Shared Sources
pysequence.cpp
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2025 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#include "python_common.h"
46#include "pysequence.h"
47#include "pyobject_macros.h"
48#include "_lass_module.h"
49
50namespace lass
51{
52namespace python
53{
54namespace impl
55{
57 //typedef meta::type_list::Make<PyObject*>::Type TArguments;
58 //PY_CLASS_CONSTRUCTOR(Sequence, TArguments) // constructor with some arguments. *
59
60 PY_CLASS_METHOD( Sequence, append )
62 PY_CLASS_METHOD_NAME( Sequence, pop_back, "pop" )
64 PY_CLASS_METHOD( Sequence, reserve )
66 PY_CLASS_METHOD( Sequence, asList )
67 PY_CLASS_METHOD_NAME( Sequence, iter, methods::_iter_ );
68 PY_CLASS_METHOD_NAME( Sequence, repr, methods::_repr_ );
69 LASS_EXECUTE_BEFORE_MAIN_EX( Sequence_executeBeforeMain,
70 Sequence::_lassPyClassDef.setSlot(Py_sq_length, &Sequence::length);
71 Sequence::_lassPyClassDef.setSlot(Py_sq_concat, &Sequence::concat);
72 Sequence::_lassPyClassDef.setSlot(Py_sq_repeat, &Sequence::repeat);
73 Sequence::_lassPyClassDef.setSlot(Py_sq_item, &Sequence::item);
74 Sequence::_lassPyClassDef.setSlot(Py_sq_ass_item, &Sequence::assItem);
75 Sequence::_lassPyClassDef.setSlot(Py_sq_contains, &Sequence::contains);
76 Sequence::_lassPyClassDef.setSlot(Py_sq_inplace_concat, &Sequence::inplaceConcat);
77 Sequence::_lassPyClassDef.setSlot(Py_sq_inplace_repeat, &Sequence::inplaceRepeat);
78 Sequence::_lassPyClassDef.setSlot(Py_mp_length, &Sequence::length);
79 Sequence::_lassPyClassDef.setSlot(Py_mp_subscript, &Sequence::subscript);
80 Sequence::_lassPyClassDef.setSlot(Py_mp_ass_subscript, &Sequence::assSubscript);
81 )
82
83 Sequence::Sequence(TPimpl&& pimpl)
84 {
85 init(std::move(pimpl));
86 }
87
88 void Sequence::init(TPimpl&& pimpl)
89 {
90 LockGIL LASS_UNUSED(lock);
91 initLassModule();
92 impl::fixObjectType(this);
93 pimpl_ = std::move(pimpl);
94 }
95
96 const TSequencePtr Sequence::copy() const
97 {
98 LockGIL LASS_UNUSED(lock);
99 Sequence::TPimpl pimpl = pimpl_->copy();
100 return TSequencePtr(new Sequence(std::move(pimpl)));
101 }
102 void Sequence::clear()
103 {
104 LockGIL LASS_UNUSED(lock);
105 if (!pimpl_->clear())
106 {
107 impl::fetchAndThrowPythonException(LASS_PRETTY_FUNCTION);
108 }
109 }
110 void Sequence::reserve(Py_ssize_t n)
111 {
112 LockGIL LASS_UNUSED(lock);
113 if (!pimpl_->reserve(n))
114 {
115 impl::fetchAndThrowPythonException(LASS_PRETTY_FUNCTION);
116 }
117 }
118 void Sequence::append(const TPyObjPtr& obj)
119 {
120 LockGIL LASS_UNUSED(lock);
121 if (!pimpl_->append(obj))
122 {
123 impl::fetchAndThrowPythonException(LASS_PRETTY_FUNCTION);
124 }
125 }
126 const TPyObjPtr Sequence::pop(Py_ssize_t i)
127 {
128 LockGIL LASS_UNUSED(lock);
129 TPyObjPtr popped(pimpl_->item(i));
130 if (!pimpl_->pop(i))
131 {
132 impl::fetchAndThrowPythonException(LASS_PRETTY_FUNCTION);
133 }
134 return popped;
135 }
136 const TPyObjPtr Sequence::pop_back()
137 {
138 LockGIL LASS_UNUSED(lock);
139 return pop(pimpl_->length() - 1);
140 }
141
142 const std::type_info& Sequence::type() const
143 {
144 return pimpl_->type();
145 }
146 void* Sequence::raw(bool writable) const
147 {
148 return pimpl_->raw(writable);
149 }
150
151 std::string Sequence::repr() const
152 {
153 LockGIL LASS_UNUSED(lock);
154 return pimpl_->repr();
155 }
156
157 const TPyObjPtr Sequence::asList() const
158 {
159 LockGIL LASS_UNUSED(lock);
160 return pimpl_->asNative();
161 }
162 const TPyObjPtr Sequence::iter() const
163 {
164 LockGIL LASS_UNUSED(lock);
165 return fromNakedToSharedPtrCast<PyObject>(pimpl_->items());
166 }
167
168 Py_ssize_t Sequence::length(PyObject* self)
169 {
170 return static_cast<Sequence*>(self)->pimpl_->length();
171 }
172 PyObject* Sequence::concat(PyObject* self, PyObject* other)
173 {
174 TSequencePtr result = static_cast<Sequence*>(self)->copy();
175 return inplaceConcat(result.get(), other);
176 }
177 PyObject* Sequence::repeat(PyObject* self, Py_ssize_t n)
178 {
179 TSequencePtr result = static_cast<Sequence*>(self)->copy();
180 return inplaceRepeat(result.get(), n);
181 }
182 PyObject* Sequence::item(PyObject* self, Py_ssize_t i)
183 {
184 return static_cast<Sequence*>(self)->pimpl_->item(i);
185 }
186 int Sequence::assItem(PyObject* self, Py_ssize_t i, PyObject* obj)
187 {
188 return static_cast<Sequence*>(self)->pimpl_->assItem(i, obj);
189 }
190 int Sequence::contains(PyObject* self, PyObject* obj)
191 {
192 return static_cast<Sequence*>(self)->pimpl_->contains(obj);
193 }
194 PyObject* Sequence::inplaceConcat(PyObject* self, PyObject* other)
195 {
196 if (!static_cast<Sequence*>(self)->pimpl_->inplaceConcat(other))
197 {
198 return 0;
199 }
200 Py_INCREF(self);
201 return self;
202 }
203 PyObject* Sequence::inplaceRepeat(PyObject* self, Py_ssize_t n)
204 {
205 if (!static_cast<Sequence*>(self)->pimpl_->inplaceRepeat(n))
206 {
207 return 0;
208 }
209 Py_INCREF(self);
210 return self;
211 }
212 PyObject* Sequence::subscript(PyObject* self, PyObject* key)
213 {
214 PySequenceImplBase& pimpl = *static_cast<Sequence*>(self)->pimpl_;
215 if (PySlice_Check(key))
216 {
217 Py_ssize_t start, stop, step, slicelength;
218 if (PySlice_GetIndicesEx(key, pimpl.length(), &start, &stop, &step, &slicelength) != 0)
219 {
220 return 0;
221 }
222 return pimpl.slice(start, stop, step);
223 }
224 Py_ssize_t i;
225 if (pyGetSimpleObject(key, i) != 0)
226 {
227 return 0;
228 }
229 if (i < 0)
230 {
231 i += pimpl.length();
232 }
233 return pimpl.item(i);
234 }
235 int Sequence::assSubscript( PyObject* self, PyObject* key, PyObject* value)
236 {
237 PySequenceImplBase& pimpl = *static_cast<Sequence*>(self)->pimpl_;
238 if (PySlice_Check(key))
239 {
240 Py_ssize_t start, stop, step, slicelength;
241 if (PySlice_GetIndicesEx(key, pimpl.length(), &start, &stop, &step, &slicelength) != 0)
242 {
243 return -1;
244 }
245 return pimpl.assSlice(start, stop, step, value);
246 }
247 Py_ssize_t i;
248 if (pyGetSimpleObject(key, i) != 0)
249 {
250 return -1;
251 }
252 if (i < 0)
253 {
254 i += pimpl.length();
255 }
256 return pimpl.assItem(i, value);
257 }
258}
259
260}
261
262}
Object for interfacing sequence-like objects with Python.
Definition pysequence.h:333
#define PY_DECLARE_CLASS(i_cppClass)
Declare a Python class with automatic name and no documentation.
#define PY_CLASS_METHOD_NAME(i_cppClass, i_cppMethod, s_methodName)
Export a C++ method to Python with custom name (no documentation).
#define PY_CLASS_METHOD(i_cppClass, i_cppMethod)
Export a C++ method to Python using the C++ method name (no documentation).
void fetchAndThrowPythonException(std::string loc)
Fetch the current Python exception and throw it as a C++ PythonException.
PyObjectPtr< PyObject >::Type TPyObjPtr
PyObjectPtr to a PyObject.
lass::util::SharedPtr< T, PyObjectStorage, PyObjectCounter > fromNakedToSharedPtrCast(PyObject *object)
fromNakedToSharedPtrCast.
Comprehensive C++ to Python binding library.
Library for Assembled Shared Sources.
Definition config.h:53