Library of Assembled Shared Sources
argument_traits.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_PYTHON_ARGUMENT_TRAITS_H
44#define LASS_GUARDIAN_OF_INCLUSION_PYTHON_ARGUMENT_TRAITS_H
45
46#include "python_common.h"
47#include "pyobject_plus.h"
48#include "shadowee_traits.h"
50
51namespace lass
52{
53namespace python
54{
55namespace impl
56{
57
58// --- ArgumentTraitsBuiltin -----------------------------------------------------------------------
59
60/** @ingroup Python
61 * @internal
62 * For built-in types like int, float, bool, std::string ...
63 *
64 * In case of built-in types, a Python type has to be converted to a C++ type. Therefore a "copy"
65 * of the object is created. And thus, ArgumentTraitsBuiltin does not support the cases in which
66 * you would be able to alter the original object: non-const pointers and non-const references.
67 */
68template <typename T>
69struct ArgumentTraitsBuiltin
70{
71 typedef T TStorage;
72 static const T& arg(const TStorage& storage) { return storage; }
73};
74
75/** @ingroup Python
76 * @internal
77 * Non-const pointers to builtin types are not supported as you would be acting on a copy anyway ...
78 */
79template <typename T>
80struct ArgumentTraitsBuiltin<T*>
81{
82};
83
84/** @ingroup Python
85 * @internal
86 * For built-in types, by const pointer is @e almost equivalent to by copy.
87 */
88template <typename T>
89struct ArgumentTraitsBuiltin<const T*>
90{
91 typedef T TStorage;
92 static const T* arg(const TStorage& storage) { return &storage; }
93};
94
95/** @ingroup Python
96 * @internal
97 * Non-const references to builtin types are not supported as you would be acting on a copy anyway ...
98 */
99template <typename T>
100struct ArgumentTraitsBuiltin<T&>
101{
102};
103
104/** @ingroup Python
105 * @internal
106 * For built-in types, by const references is equivalent to by copy
107 */
108template <typename T>
109struct ArgumentTraitsBuiltin<const T&>: ArgumentTraitsBuiltin<T>
110{
111};
112
113// --- ArgumentTraitsPyObject ----------------------------------------------------------------------
114
115/** @ingroup Python
116 * @internal
117 * For types that derive from PyObject. These are fully supported.
118 */
119template <typename T>
120struct ArgumentTraitsPyObject
121{
122 typedef python::NoNone< typename PyObjectPtr<T>::Type > TStorage;
123 static const T& arg(const TStorage& storage) { return *storage.reference(); }
124};
125
126/** @ingroup Python
127 * @internal
128 */
129template <typename T>
130struct ArgumentTraitsPyObject<T*>
131{
132 typedef typename PyObjectPtr<T>::Type TStorage;
133 static T* arg(const TStorage& storage) { return storage.get(); }
134};
135
136/** @ingroup Python
137 * @internal
138 */
139template <typename T>
140struct ArgumentTraitsPyObject<T&>
141{
142 typedef python::NoNone< typename PyObjectPtr<T>::Type > TStorage;
143 static T& arg(const TStorage& storage) { return *storage.reference(); }
144};
145
146/** by PyObjectPtr.
147 * @ingroup Python
148 */
149template <typename T>
150struct ArgumentTraitsPyObject< util::SharedPtr<T, PyObjectStorage, PyObjectCounter> >
151{
152 typedef typename PyObjectPtr<T>::Type TStorage;
153 static const TStorage& arg(const TStorage& storage) { return storage; }
154};
155
156
157// --- ArgumentTraitsShadowee ------------------------------------------------------------------------
158
159/** @ingroup Python
160 * @internal
161 * For types that have a shadow pyobject. These are fully supported (T may be const)
162 */
163template <typename T>
164struct ArgumentTraitsShadowee
165{
166 typedef typename ShadoweeTraits<T>::TPointerTraits TPointerTraits;
168 static const T& arg(const TStorage& storage) { return *storage.reference(); }
169};
170
171/** @ingroup Python
172 * @internal
173 * For types that have a shadow pyobject. These are fully supported (T may be const)
174 */
175template <typename T>
176struct ArgumentTraitsShadowee<T&>
177{
178 typedef typename ShadoweeTraits<T>::TPointerTraits TPointerTraits;
180 static T& arg(const TStorage& storage) { return *storage.reference(); }
181};
182
183/** @ingroup Python
184 * @internal
185 * For types that have a shadow pyobject (T may be const).
186 */
187template <typename T>
188struct ArgumentTraitsShadowee<T*>
189{
190 typedef typename ShadoweeTraits<T>::TPointerTraits TPointerTraits;
191 typedef typename TPointerTraits::TPtr TStorage;
192 static T* arg(const TStorage& storage) { return TPointerTraits::get(storage); }
193};
194
195/** by SharedPtr (T may be const).
196 * @ingroup Python
197 */
198template <typename T, template <typename, typename> class S, typename C>
199struct ArgumentTraitsShadowee< util::SharedPtr<T, S, C> >
200{
201 typedef util::SharedPtr<T, S, C> TStorage;
202 static const util::SharedPtr<T, S, C>& arg(const TStorage& storage) { return storage; }
203};
204
205
206
207// --- ArgumentTraitsSelector ----------------------------------------------------------------------
208
209/** @ingroup Python
210 * @internal
211 */
212template <typename T, bool isPyObject, bool isShadowee> struct ArgumentTraitsSelector;
213
214/** @ingroup Python
215 * @internal
216 */
217template <typename T>
218struct ArgumentTraitsSelector<T, false, false>: ArgumentTraitsBuiltin<T>
219{
220};
221
222/** @ingroup Python
223 * @internal
224 */
225template <typename T>
226struct ArgumentTraitsSelector<T, true, false>: ArgumentTraitsPyObject<T>
227{
228};
229
230/** @ingroup Python
231 * @internal
232 */
233template <typename T>
234struct ArgumentTraitsSelector<T, false, true>: ArgumentTraitsShadowee<T>
235{
236};
237
238}
239
240// --- ArgumentTraits ------------------------------------------------------------------------------
241
242/** by copy.
243 * @ingroup Python
244 */
245template <typename T>
246struct ArgumentTraits: impl::ArgumentTraitsSelector<T, IsPyObject<T>::value, ShadoweeTraits<T>::value>
247{
248};
249
250/** by const copy.
251 * @ingroup Python
252 *
253 * Is same as by copy.
254 */
255template <typename T>
257{
258};
259
260/** by non-const pointer to non-const object.
261 * @ingroup Python
262 */
263template <typename T>
264struct ArgumentTraits<T*>: impl::ArgumentTraitsSelector<T*, IsPyObject<T>::value, ShadoweeTraits<T>::value>
265{
266};
267
268/** by non-const pointer to const object.
269 * @ingroup Python
270 */
271template <typename T>
272struct ArgumentTraits<const T*>: impl::ArgumentTraitsSelector<const T*, IsPyObject<T>::value, ShadoweeTraits<T>::value>
273{
274};
275
276/** by reference to non-const object.
277 * @ingroup Python
278 */
279template <typename T>
280struct ArgumentTraits<T&>: impl::ArgumentTraitsSelector<T&, IsPyObject<T>::value, ShadoweeTraits<T>::value>
281{
282};
283
284/** by reference to const object.
285 * @ingroup Python
286 */
287template <typename T>
288struct ArgumentTraits<const T&>: impl::ArgumentTraitsSelector<const T&, IsPyObject<T>::value, ShadoweeTraits<T>::value>
289{
290};
291
292/** by SharedPtr
293 * @ingroup Python
294 */
295template <typename T, template <typename, typename> class S, typename C>
296struct ArgumentTraits< util::SharedPtr<T, S, C> >:
297 impl::ArgumentTraitsSelector< util::SharedPtr<T, S, C> , IsPyObject<T>::value, ShadoweeTraits<T>::value>
298{
299};
300
301/** by SharedPtr
302 * @ingroup Python
303 *//*
304template <typename T, template <typename, typename> class S, typename C>
305struct ArgumentTraits< util::SharedPtr<const T, S, C> >:
306 impl::ArgumentTraitsSelector< util::SharedPtr<const T, S, C> , IsPyObject<T>::value, ShadoweeTraits<T>::value>
307{
308};*/
309
310// --- odds and ends ---
311
312template <>
313struct ArgumentTraits<const char*>
314{
315 typedef std::optional<std::string> TStorage;
316 static const char* arg(const TStorage& storage) { return storage ? storage->c_str() : nullptr; }
317};
318
319template <>
320struct ArgumentTraits<const wchar_t*>
321{
322 typedef std::optional<std::wstring> TStorage;
323 static const wchar_t* arg(const TStorage& storage) { return storage ? storage->c_str() : nullptr; }
324};
325
326#if LASS_HAVE_STD_U8STRING
327#if __cpp_lib_char8_t
328
329template <>
330struct ArgumentTraits<const char8_t*>
331{
332 typedef std::optional <std::u8string> TStorage;
333 static const char8_t* arg(const TStorage& storage) { return storage ? storage->c_str() : nullptr; }
334};
335
336#endif
337#endif
338
339template <>
340struct ArgumentTraits<const char16_t*>
341{
342 typedef std::optional <std::u16string> TStorage;
343 static const char16_t* arg(const TStorage& storage) { return storage ? storage->c_str() : nullptr; }
344};
345
346template <>
347struct ArgumentTraits<const char32_t*>
348{
349 typedef std::optional<std::u32string> TStorage;
350 static const char32_t* arg(const TStorage& storage) { return storage ? storage->c_str() : nullptr; }
351};
352
353template <typename T>
354struct ArgumentTraits< std::basic_string_view<T> >
355{
356 typedef std::basic_string<T> TStorage;
357 static const TStorage& arg(const TStorage& storage) { return storage; }
358};
359
360template <>
361struct ArgumentTraits<void*>
362{
363 typedef void* TStorage;
364 static void* arg(const TStorage& storage) { return storage; }
365};
366
367template <typename T1, typename T2>
368struct ArgumentTraits<std::pair<T1, T2>>
369{
370 typedef ArgumentTraits<T1> TArgTraits1;
371 typedef ArgumentTraits<T2> TArgTraits2;
372 typedef std::pair<typename TArgTraits1::TStorage, typename TArgTraits2::TStorage> TStorage;
373 static std::pair<T1, T2> arg(const TStorage& storage)
374 {
375 return std::make_pair(TArgTraits1::arg(storage.first), TArgTraits2::arg(storage.second));
376 }
377};
378
379}
380}
381
382#endif
T & reference()
Return reference to wrapped value.
Definition no_none.h:88
Comprehensive C++ to Python binding library.
general utility, debug facilities, ...
Library for Assembled Shared Sources.
Definition config.h:53