Library of Assembled Shared Sources
container.h
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#ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_CONTAINER_H
44#define LASS_GUARDIAN_OF_INCLUSION_UTIL_CONTAINER_H
45
46#include "python_common.h"
47#include "pyiteratorrange.h"
48#include "../util/string_cast.h"
49#include "../util/shared_ptr.h"
51#include "../meta/type_traits.h"
52
53#include <vector>
54#include <list>
55#include <deque>
56#include <map>
57#include <typeinfo>
58
59namespace lass
60{
61namespace python
62{
63namespace impl
64{
65
66template <typename Container>
67struct ContainerTraitsBase
68{
69 typedef Container container_type;
70 typedef typename Container::value_type value_type;
71 typedef typename Container::const_iterator const_iterator;
72 typedef typename Container::iterator iterator;
73 static Py_ssize_t size(const container_type& c)
74 {
75 const Py_ssize_t size = static_cast<Py_ssize_t>(c.size());
76 LASS_ASSERT(size >= 0);
77 return size;
78 }
79 static const const_iterator begin(const container_type& c)
80 {
81 return c.begin();
82 }
83 static const iterator begin(container_type& c)
84 {
85 return c.begin();
86 }
87 template <typename It>
88 static const It next(It it, Py_ssize_t i = 1)
89 {
90 std::advance(it, i);
91 return it;
92 }
93 static void insert(container_type& c, iterator i, value_type value)
94 {
95 c.insert(i, std::move(value));
96 }
97 template <typename InputIt>
98 static void insert(container_type& c, iterator i, InputIt first, InputIt last)
99 {
100 c.insert(i, first, last);
101 }
102 static void erase(container_type& c, iterator i)
103 {
104 c.erase(i);
105 }
106 static void erase(container_type& c, iterator first, iterator last)
107 {
108 c.erase(first, last);
109 }
110 static void clear(container_type& c)
111 {
112 c.clear();
113 }
114 static void reserve(container_type& /*c*/, Py_ssize_t /*n*/)
115 {
116 }
117 static const util::SharedPtr<container_type> copy(const container_type& c)
118 {
119 return util::SharedPtr<container_type>(new container_type(c));
120 }
121 static void inplace_repeat(container_type& c, Py_ssize_t n)
122 {
123 stde::inplace_repeat_c(c, n);
124 }
125};
126
127template <typename Container>
128struct ContainerTraits: ContainerTraitsBase<Container>
129{
130};
131
132template <typename T, typename A>
133struct ContainerTraits< std::vector<T, A> >: ContainerTraitsBase< std::vector<T, A> >
134{
135 typedef typename ContainerTraitsBase< std::vector<T, A> >::container_type container_type;
136 static void reserve( container_type& c, Py_ssize_t n )
137 {
138 LASS_ASSERT(n >= 0);
139 c.reserve(static_cast<size_t>(n));
140 }
141};
142
143
144class LASS_PYTHON_DLL ContainerImplBase
145{
146public:
147 virtual ~ContainerImplBase() {};
148 virtual bool clear() = 0;
149 virtual Py_ssize_t length() const = 0;
150 virtual PyObject* items() const = 0;
151 virtual const TPyObjPtr asNative() const = 0;
152 virtual const std::type_info& type() const = 0;
153 virtual void* raw(bool writable) = 0;
154
155 const std::string repr() const;
156};
157
158
159template <typename Container, typename Base>
160class ContainerImpl : public Base
161{
162public:
163 typedef Container TContainer;
164 typedef util::SharedPtr<Container> TContainerPtr;
165 typedef util::SharedPtr<const Container> TConstContainerPtr;
166 typedef ContainerTraits<Container> TContainerTraits;
167
168 bool clear() override
169 {
170 if (!checkWritable())
171 {
172 return false;
173 }
174 TContainerTraits::clear(*container_);
175 return true;
176 }
177 Py_ssize_t length() const override
178 {
179 return TContainerTraits::size(*container_);
180 }
181 PyObject* items() const override
182 {
183 return new PyIteratorRange(container_->begin(), container_->end());
184 }
185 const std::type_info& type() const override
186 {
187 return typeid(TContainerPtr);
188 }
189 void* raw(bool writable) override
190 {
191 if (writable && readOnly_)
192 {
193 return 0;
194 }
195 return &container_;
196 }
197protected:
198 ContainerImpl(const TContainerPtr& container, bool readOnly = false):
199 container_(container),
200 readOnly_(readOnly)
201 {
202 LASS_ASSERT(container_);
203 }
204 bool checkWritable() const
205 {
206 if (readOnly_)
207 {
208 LockGIL LASS_UNUSED(lock);
209 PyErr_SetString(PyExc_TypeError, "Container is read-only");
210 return false;
211 }
212 return true;
213 }
214 const TContainer& container() const
215 {
216 return *container_;
217 }
218 TContainer& container()
219 {
220 return *container_;
221 }
222 const typename TContainerTraits::const_iterator begin() const
223 {
224 return TContainerTraits::begin(*container_);
225 }
226 const typename TContainerTraits::iterator begin()
227 {
228 return TContainerTraits::begin(*container_);
229 }
230 template <typename It> static const It next(It it, Py_ssize_t i)
231 {
232 return TContainerTraits::next(it, i);
233 }
234private:
235 util::SharedPtr<Container> container_;
236 bool readOnly_;
237};
238
239
240template
241<
242 typename ShadowType,
243 typename ConcreteTraits
244>
245struct ShadowTraitsContainer
246{
247 typedef typename PyObjectPtr<ShadowType>::Type TPyClassPtr;
248 typedef ShadowType TCppClass;
249 typedef TPyClassPtr TCppClassPtr;
250 typedef typename PyObjectPtr<const ShadowType>::Type TConstCppClassPtr;
251
252 template <typename Container> static int getObject(PyObject* obj, util::SharedPtr<Container>& container)
253 {
254 typedef typename meta::TypeTraits<Container>::TNonConst TNonConstContainer;
255 util::SharedPtr<TNonConstContainer> temp;
256 if (ConcreteTraits::getObjectImpl(obj, temp, false) != 0)
257 {
258 return 1;
259 }
260 container = temp.template constCast<Container>();
261 return 0;
262 }
263 template <typename Container> static int getObject(PyObject* obj, Container& container)
264 {
265 util::SharedPtr<Container> temp;
266 if (ConcreteTraits::getObjectImpl(obj, temp, false) != 0)
267 {
268 return 1;
269 }
270 container = *temp;
271 return 0;
272 }
273 static int getObject(PyObject* obj, TPyClassPtr& shadow)
274 {
276 return 0;
277 }
278 static int getObject(PyObject* obj, TConstCppClassPtr& shadow)
279 {
281 return 0;
282 }
283
284 template <typename T> static TPyClassPtr buildObject(const T& value)
285 {
286 return TPyClassPtr(new ShadowType(value));
287 }
288 static TPyClassPtr buildObject(const TPyClassPtr& shadow)
289 {
290 return shadow;
291 }
292};
293
294}
295}
296}
297
298#endif
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
ConstTraits< T >::TNonConst TNonConst
strips const qualifier of refered type of T (but keeps reference if any).