Library of Assembled Shared Sources
pyshadow_object.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 * https://lass.cocamware.com/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) 2023-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/** @file
44 * @author Bram de Greve (bram@cocamware.com)
45 * @author Tom De Muer (tom@cocamware.com)
46 *
47 * Distributed under the terms of the GPL (GNU Public License)
48 *
49 * The LASS License:
50 *
51 * Copyright 2004-2008 Bram de Greve and Tom De Muer
52 *
53 * LASS is free software; you can redistribute it and/or modify
54 * it under the terms of the GNU General Public License as published by
55 * the Free Software Foundation; either version 2 of the License, or
56 * (at your option) any later version.
57 *
58 * This program is distributed in the hope that it will be useful,
59 * but WITHOUT ANY WARRANTY; without even the implied warranty of
60 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
61 * GNU General Public License for more details.
62 *
63 * You should have received a copy of the GNU General Public License
64 * along with this program; if not, write to the Free Software
65 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
66 *
67 * @note
68 * This header bundles the _EXPERIMENTAL_ code for quasi automatic
69 * wrapping of C++ object hierarchies into python shadow objects. This
70 * code is still heavily under development and not ready for production use.
71 */
72
73#ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_PYSHADOW_OBJECT_H
74#define LASS_GUARDIAN_OF_INCLUSION_UTIL_PYSHADOW_OBJECT_H
75
76#include "python_common.h"
77#include "pyobject_plus.h"
78#include "shadowee_traits.h"
79#include "../meta/is_derived.h"
80#include <type_traits>
81
82namespace lass
83{
84namespace python
85{
86
87using TShadoweeID = num::TuintPtr;
88
89namespace impl
90{
91
92/** @ingroup Python
93 * @internal
94 */
95enum ShadoweeConstness
96{
97 scConst,
98 scNonConst
99};
100
101/** @ingroup Python
102 * @internal
103 */
104class LASS_PYTHON_DLL ShadowBaseCommon: public PyObjectPlus
105{
106public:
107 static TPyObjPtr findShadowObject(TShadoweeID shadoweeID, ShadoweeConstness constness);
108
109protected:
110 ShadowBaseCommon();
111 ~ShadowBaseCommon() override;
112
113 void registerShadowee(TShadoweeID shadoweeID, ShadoweeConstness constness);
114 void unregisterShadowee(TShadoweeID shadoweeID, ShadoweeConstness constness);
115private:
116 typedef std::pair<TShadoweeID, ShadoweeConstness> TCacheKey;
117
118 struct CacheKeyHash
119 {
120 std::size_t operator()(const TCacheKey& key) const
121 {
122 std::size_t h1 = std::hash<TShadoweeID>()(key.first);
123 std::size_t h2 = std::hash<ShadoweeConstness>()(key.second);
124 return h1 ^ h2;
125 }
126 };
127
128 typedef std::unordered_map<TCacheKey, ShadowBaseCommon*, CacheKeyHash> TCache;
129 ShadowBaseCommon(const ShadowBaseCommon&);
130 ShadowBaseCommon& operator=(const ShadowBaseCommon&);
131
132 static TCache& cache();
133};
134
135/** @ingroup Python
136 * @internal
137 */
138template <typename T>
139struct IsShadowClass: public meta::IsDerived<T, ShadowBaseCommon>
140{
141};
142
143/** @ingroup Python
144 * @internal
145 */
146template <typename T>
147struct ShadowTraits
148{
149 enum { isShadow = IsShadowClass<T>::value };
150
151private:
152
153 template <typename U, bool shadow>
154 struct Impl
155 {
156 typedef typename U::TShadoweePtr TCppClassPtr;
157 typedef typename U::TConstShadoweePtr TConstCppClassPtr;
158 typedef typename U::TShadowPtr TPyClassPtr;
159 typedef typename U::TShadowee TCppClass;
160 static int getObject(U* obj, TCppClassPtr& value)
161 {
162 typedef typename U::TPointerTraits TPointerTraits;
163 const TCppClassPtr p = TPointerTraits::staticCast(obj->cppObject());
164 if (TPointerTraits::isEmpty(p))
165 {
166 PyErr_Format(PyExc_TypeError, "PyObject is a const %s", T::_lassPyClassDef.name());
167 return 1;
168 }
169 value = p;
170 return 0;
171 };
172 static int getObject(U* obj, TConstCppClassPtr& value)
173 {
174 typedef typename U::TConstPointerTraits TConstPointerTraits;
175 value = TConstPointerTraits::staticCast(obj->constCppObject());
176 if (TConstPointerTraits::isEmpty(value))
177 {
178 PyErr_Format(PyExc_TypeError, "Trying to dereference null-PyObject of type %s", T::_lassPyClassDef.name());
179 return 1;
180 }
181 return 0;
182 };
183 template <typename Ptr> static TPyClassPtr buildObject(const Ptr& value)
184 {
185 return U::make(value);
186 }
187 };
188
189 template <typename U>
190 struct Impl<U, false>
191 {
192 typedef typename PyObjectPtr<U>::Type TPyClassPtr;
193 typedef TPyClassPtr TCppClassPtr;
194 typedef typename PyObjectPtr<const U>::Type TConstCppClassPtr;
195 typedef U TCppClass;
196 static int getObject(U* obj, TPyClassPtr& value)
197 {
198 value = fromNakedToSharedPtrCast<U>(obj);
199 return 0;
200 };
201 static int getObject(U* obj, TConstCppClassPtr& value)
202 {
204 return 0;
205 };
206 static const TPyClassPtr& buildObject(const TPyClassPtr& value)
207 {
208 return value;
209 }
210 // we can't create them from const cppObjects, as we can't track it as such ...
211 };
212
213 typedef Impl<T, isShadow> TImpl;
214
215 static bool checkSubType(PyObject* obj)
216 {
217 LASS_ASSERT(obj);
218 if (!PyType_IsSubtype(obj->ob_type , T::_lassPyClassDef.type() ))
219 {
220 PyErr_Format(PyExc_TypeError, "%s not castable to %s", obj->ob_type->tp_name, T::_lassPyClassDef.name());
221 return false;
222 }
223 return true;
224 }
225
226public:
227
228 typedef typename TImpl::TCppClass TCppClass;
229 typedef typename TImpl::TCppClassPtr TCppClassPtr;
230 typedef typename TImpl::TConstCppClassPtr TConstCppClassPtr;
231 typedef typename TImpl::TPyClassPtr TPyClassPtr;
232 typedef int (*TImplicitConverter)(PyObject* obj, TCppClassPtr&);
233
234 template <typename Ptr> static int getObject(PyObject* obj, Ptr& value)
235 {
236 if (obj == Py_None)
237 {
238 value = Ptr();
239 return 0;
240 }
241 if (PyType_IsSubtype(obj->ob_type , T::_lassPyClassDef.type()))
242 {
243 return TImpl::getObject(static_cast<T*>(obj), value);
244 }
245 TCppClassPtr p;
246 if (tryImplicitConverters(obj, p) != 0)
247 {
248 return 1;
249 }
250 value = p;
251 return 0;
252 }
253 static int getObject(PyObject* obj, TCppClass& value)
254 {
255 if (obj == Py_None)
256 {
257 PyErr_Format(PyExc_TypeError, "None not castable to %s", T::_lassPyClassDef.name());
258 return 1;
259 }
260 TConstCppClassPtr p;
261 if (obj->ob_type == T::_lassPyClassDef.type())
262 {
263 if (TImpl::getObject(static_cast<T*>(obj), p) != 0)
264 {
265 return 1;
266 }
267 }
268 else
269 {
270 TCppClassPtr p2;
271 if (tryImplicitConverters(obj, p2) != 0)
272 {
273 return 1;
274 }
275 p = p2;
276 }
277 try
278 {
279 value = *p;
280 }
281 LASS_PYTHON_CATCH_AND_RETURN_EX(1)
282 return 0;
283 }
284 template <typename Ptr> static TPyClassPtr buildObject(const Ptr& value)
285 {
286 return TImpl::buildObject(value);
287 }
288 static TPyClassPtr buildObject(const TCppClass& value)
289 {
290 TCppClassPtr p(new TCppClass(value));
291 return buildObject(p);
292 }
293 template <typename Deleter>
294 static TPyClassPtr buildObject(std::unique_ptr<TCppClass, Deleter>&& value)
295 {
296 return buildObject(TCppClassPtr(std::move(value)));
297 }
298 static void addConverter(TImplicitConverter converter)
299 {
300 TImplicitConverterList* converters = implicitConverters();
301 converters->push_back(converter);
302 }
303
304private:
305 typedef std::vector<TImplicitConverter> TImplicitConverterList;
306 static TImplicitConverterList* implicitConverters_;
307
308 static int tryImplicitConverters(PyObject* obj, TCppClassPtr& p)
309 {
310 const TImplicitConverterList* converters = implicitConverters();
311 if (converters)
312 {
313 for (typename TImplicitConverterList::const_iterator i = converters->begin(); i != converters->end(); ++i)
314 {
315 if ((*i)(obj, p) == 0)
316 {
317 return 0;
318 }
319 PyErr_Clear();
320 }
321 }
322 PyErr_Format(PyExc_TypeError, "%s not convertable to %s", obj->ob_type->tp_name, T::_lassPyClassDef.name());
323 return 1;
324 }
325
326 static TImplicitConverterList* implicitConverters()
327 {
328 void*& slot = T::_lassPyClassDef.implicitConvertersSlot_;
329 if (!slot)
330 {
331 slot = new TImplicitConverterList;
332 }
333 return static_cast<TImplicitConverterList*>(slot);
334 }
335};
336
337//template <typename T> typename ShadowTraits<T>::TImplicitConverterList* ShadowTraits<T>::implicitConverters_ = 0;
338
339template <typename ShadowType, typename DerivedMakers>
340typename ShadowType::TShadowPtr makeShadow(
341 const typename ShadowType::TConstShadoweePtr& shadowee, const DerivedMakers* derivedMakers,
342 impl::ShadoweeConstness constness)
343{
344 typedef typename ShadowType::TShadowPtr TShadowPtr;
345 typedef typename ShadowType::TConstPointerTraits TConstPointerTraits;
346
347 LASS_ASSERT(!TConstPointerTraits::isEmpty(shadowee));
348 if (const auto p = impl::ShadowBaseCommon::findShadowObject(TConstPointerTraits::id(shadowee), constness))
349 {
350 LASS_ASSERT(PyObject_IsInstance(p.get(), reinterpret_cast<PyObject*>(ShadowType::_lassPyClassDef.type())));
351 return p.template staticCast<ShadowType>();
352 }
353 if (derivedMakers)
354 {
355 for (typename DerivedMakers::const_iterator i = derivedMakers->begin(); i != derivedMakers->end(); ++i)
356 {
357 if (const TShadowPtr p = (*i)(shadowee, constness))
358 {
359 return p;
360 }
361 }
362 }
363 return TShadowPtr(impl::fixObjectType(new ShadowType(shadowee, constness)));
364}
365
366template <typename Makers, typename Maker> void registerMaker(Makers*& makers, Maker maker)
367{
368 if (!makers)
369 {
370 makers = new Makers;
371 }
372 makers->push_back(maker);
373}
374
375template <typename DestPyType, typename SourceCppType>
376int defaultConvertor(PyObject* object, typename lass::python::impl::ShadowTraits<DestPyType>::TCppClassPtr& p)
377{
378 typedef typename lass::python::impl::ShadowTraits<DestPyType>::TCppClass TCppClass;
379 typedef typename lass::python::impl::ShadowTraits<DestPyType>::TCppClassPtr TPtr;
380 SourceCppType source;
381 if (pyGetSimpleObject(object, source) != 0)
382 {
383 return 1;
384 }
385 p = TPtr(new TCppClass(source));
386 return 0;
387}
388
389}
390
391
392template <typename T, template <typename, typename> class S = util::ObjectStorage, typename C = util::DefaultCounter>
393struct SharedPointerTraits
394{
395 typedef util::SharedPtr<T, S, C> TPtr;
396 template <typename U> struct Rebind
397 {
398 typedef SharedPointerTraits<U, S, C> Type;
399 };
400 static void acquire(const TPtr&) {} // TPtr already handles ownership, so nothing to acquire.
401 static void release(const TPtr&) {}
402 static bool isEmpty(const TPtr& p)
403 {
404 return p.isEmpty();
405 }
406 static T* get(const TPtr& p)
407 {
408 return p.get();
409 }
410 static TShadoweeID id(const TPtr& p)
411 {
412 return reinterpret_cast<TShadoweeID>(p.get());
413 }
414 template <typename U> static TPtr staticCast(const util::SharedPtr<U, S, C>& p)
415 {
416 return p.template staticCast<T>();
417 }
418 template <typename U> static TPtr dynamicCast(const util::SharedPtr<U, S, C>& p)
419 {
420 return p.template dynamicCast<T>();
421 }
422 template <typename U> static TPtr constCast(const util::SharedPtr<U, S, C>& p)
423 {
424 return p.template constCast<T>();
425 }
426};
427
428
429template <typename T>
430struct NakedPointerTraits
431{
432 typedef T* TPtr;
433 template <typename U> struct Rebind
434 {
435 typedef NakedPointerTraits<U> Type;
436 };
437 static void acquire(TPtr) {} // no ownership rules, so nothing to acquire.
438 static void release(TPtr) {}
439 static bool isEmpty(TPtr p)
440 {
441 return p == 0;
442 }
443 static T* get(TPtr p)
444 {
445 return p;
446 }
447 static TShadoweeID id(TPtr p)
448 {
449 return reinterpret_cast<TShadoweeID>(p);
450 }
451 template <typename U> static TPtr staticCast(U* p)
452 {
453 return static_cast<TPtr>(p);
454 }
455 template <typename U> static TPtr dynamicCast(U* p)
456 {
457 return dynamic_cast<TPtr>(p);
458 }
459 template <typename U> static TPtr constCast(U* p)
460 {
461 return const_cast<TPtr>(p);
462 }
463};
464
465
466template <typename T>
467struct StdSharedPointerTraits
468{
469 typedef std::shared_ptr<T> TPtr;
470 template <typename U> struct Rebind
471 {
472 typedef StdSharedPointerTraits<U> Type;
473 };
474 static void acquire(const TPtr&) {} // TPtr already handles ownership, so nothing to acquire.
475 static void release(const TPtr&) {}
476 static bool isEmpty(const TPtr& p)
477 {
478 return !p;
479 }
480 static T* get(const TPtr& p)
481 {
482 return p.get();
483 }
484 static TShadoweeID id(TPtr p)
485 {
486 return reinterpret_cast<TShadoweeID>(p.get());
487 }
488 template <typename U> static TPtr staticCast(const std::shared_ptr<U>& p)
489 {
490 return std::static_pointer_cast<T>(p);
491 }
492 template <typename U> static TPtr dynamicCast(const std::shared_ptr<U>& p)
493 {
494 return std::dynamic_pointer_cast<T>(p);
495 }
496 template <typename U> static TPtr constCast(const std::shared_ptr<U>& p)
497 {
498 return std::const_pointer_cast<T>(p);
499 }
500};
501
502
503/** @ingroup Python
504 */
505template
506<
507 typename ShadowType,
508 typename ShadoweeType,
509 typename ParentShadowType,
510 typename PointerTraits = SharedPointerTraits<ShadoweeType>
511>
512class ShadowClass: public ParentShadowType
513{
514public:
515 typedef ShadoweeType TShadowee;
516 typedef ShadowType TShadow;
517 typedef ParentShadowType TParentShadow;
518 typedef typename PointerTraits::template Rebind<ShadoweeType>::Type TPointerTraits;
519 typedef typename PointerTraits::template Rebind<const ShadoweeType>::Type TConstPointerTraits;
520 typedef typename TPointerTraits::TPtr TShadoweePtr;
521 typedef typename TConstPointerTraits::TPtr TConstShadoweePtr;
522 typedef typename PyObjectPtr<ShadowType>::Type TShadowPtr;
523
524 static TShadowPtr make(const TShadoweePtr& shadowee)
525 {
526 return impl::makeShadow<ShadowType>(shadowee, derivedMakers_, impl::scNonConst);
527 }
528 static TShadowPtr make(const TConstShadoweePtr& shadowee)
529 {
530 return impl::makeShadow<ShadowType>(shadowee, derivedMakers_, impl::scConst);
531 }
532 static void registerWithParent()
533 {
534 ParentShadowType::registerDerivedMaker(ShadowClass::makeParent);
535 }
536
537protected:
538 typedef TShadowPtr (*TDerivedMaker)(const TConstShadoweePtr&, impl::ShadoweeConstness);
539
540 ShadowClass(const TConstShadoweePtr& shadowee, impl::ShadoweeConstness constness):
541 ParentShadowType(shadowee, constness)
542 {
543 }
544 static void registerDerivedMaker(TDerivedMaker derivedMaker)
545 {
546 impl::registerMaker(derivedMakers_, derivedMaker);
547 }
548
549private:
550 typedef std::vector<TDerivedMaker> TDerivedMakers;
551
552 typedef typename TParentShadow::TConstShadoweePtr TParentConstShadoweePtr;
553 typedef typename TParentShadow::TShadowPtr TParentShadowPtr;
554
555 static TParentShadowPtr makeParent(const TParentConstShadoweePtr& shadowee, impl::ShadoweeConstness constness)
556 {
557 const TConstShadoweePtr p = TConstPointerTraits::dynamicCast(shadowee);
558 if (TConstPointerTraits::isEmpty(p))
559 {
560 return TParentShadowPtr();
561 }
562 return impl::makeShadow<ShadowType>(p, derivedMakers_, constness);
563 }
564
565 static TDerivedMakers* derivedMakers_;
566};
567
568template <typename S, typename T, typename P, typename PT>
569typename ShadowClass<S, T, P, PT>::TDerivedMakers* ShadowClass<S, T, P, PT>::derivedMakers_ = 0;
570
571
572
573template
574<
575 typename ShadowType,
576 typename ShadoweeType,
577 typename PointerTraits
578>
579class ShadowClass<ShadowType, ShadoweeType, PyObjectPlus, PointerTraits>: public impl::ShadowBaseCommon
580{
581public:
582 typedef ShadoweeType TShadowee;
583 typedef ShadowType TShadow;
584 typedef typename PointerTraits::template Rebind<ShadoweeType>::Type TPointerTraits;
585 typedef typename PointerTraits::template Rebind<const ShadoweeType>::Type TConstPointerTraits;
586 typedef typename TPointerTraits::TPtr TShadoweePtr;
587 typedef typename TConstPointerTraits::TPtr TConstShadoweePtr;
588 typedef typename PyObjectPtr<ShadowType>::Type TShadowPtr;
589
590 const TShadoweePtr cppObject() const
591 {
592 if (constness_ == impl::scConst)
593 {
594 return TShadoweePtr();
595 }
596 return TPointerTraits::constCast(shadowee_);
597 }
598 const TConstShadoweePtr& constCppObject() const
599 {
600 return shadowee_;
601 }
602 static TShadowPtr make(const TShadoweePtr& shadowee)
603 {
604 return impl::makeShadow<ShadowType>(shadowee, derivedMakers_, impl::scNonConst);
605 }
606 static TShadowPtr make(const TConstShadoweePtr& shadowee)
607 {
608 return impl::makeShadow<ShadowType>(shadowee, derivedMakers_, impl::scConst);
609 }
610 static void registerWithParent()
611 {
612 }
613protected:
614 typedef TShadowPtr (*TDerivedMaker)(const TConstShadoweePtr&, impl::ShadoweeConstness);
615 ShadowClass(const TConstShadoweePtr& shadowee, impl::ShadoweeConstness constness):
616 shadowee_(shadowee),
617 constness_(constness)
618 {
619 TConstPointerTraits::acquire(shadowee_);
620 impl::ShadowBaseCommon::registerShadowee(TConstPointerTraits::id(shadowee_), constness_);
621 }
622 ~ShadowClass()
623 {
624 impl::ShadowBaseCommon::unregisterShadowee(TConstPointerTraits::id(shadowee_), constness_);
625 TConstPointerTraits::release(shadowee_);
626 }
627 static void registerDerivedMaker(TDerivedMaker derivedMaker)
628 {
629 impl::registerMaker(derivedMakers_, derivedMaker);
630 }
631private:
632 typedef std::vector<TDerivedMaker> TDerivedMakers;
633
634 static TDerivedMakers* derivedMakers_;
635 TConstShadoweePtr shadowee_;
636 impl::ShadoweeConstness constness_;
637};
638
639template <typename S, typename T, typename PT>
640typename ShadowClass<S, T, PyObjectPlus, PT>::TDerivedMakers* ShadowClass<S, T, PyObjectPlus, PT>::derivedMakers_ = 0;
641
642
643
644/** @ingroup Python
645 * @brief Helper to get the pointer type holding the shadowee in a shadow object
646 *
647 * `ShadoweeType` is the C++ type being wrapped by a shadow object. This shadow object
648 * holds the wrapped shadowee in a pointer type. This pointer type is defined by the
649 * pointer traits passed to `PY_SHADOW_CLASS_EX` or `PY_SHADOW_CLASS_PTRTRAITS`.
650 * By default, this is `SharedPointerTraits<ShadoweeType>`.
651 *
652 * This helper will directly give you the pointer type used to store the shadowee in
653 * the shadow objects. Depending on the constness of the shadowee, you will either get
654 * a pointer to a non-const ShadoweeType or a pointer to a const ShadoweeType.
655 *
656 * If `ShadoweeType` is _not_ a shadowed type but derives from `PyObjectPlus`, then
657 * the pointer type `PyObjectPtr<ShadoweeType>::Type`
658 */
659template <typename ShadoweeType>
660using ShadoweePtr = std::conditional_t<std::is_const_v<ShadoweeType>,
661 typename impl::ShadowTraits<typename ShadoweeTraits<ShadoweeType>::TShadow>::TConstCppClassPtr,
662 typename impl::ShadowTraits<typename ShadoweeTraits<ShadoweeType>::TShadow>::TCppClassPtr
663>;
664
665}
666
667}
668
669/** @ingroup Python
670 */
671#define PY_SHADOW_CLASS_EX(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectParent, t_PointerTraits) \
672 class dllInterface i_PyObjectShadowClass : \
673 public ::lass::python::ShadowClass< i_PyObjectShadowClass, t_CppClass, t_PyObjectParent, t_PointerTraits > \
674 { \
675 PY_HEADER(t_PyObjectParent) \
676 static void _lassPyClassRegisterHook() { registerWithParent(); } \
677 public: \
678 i_PyObjectShadowClass(const TConstShadoweePtr& shadowee, ::lass::python::impl::ShadoweeConstness constness): \
679 ::lass::python::ShadowClass< i_PyObjectShadowClass, t_CppClass, t_PyObjectParent, t_PointerTraits >(shadowee, constness) \
680 { \
681 } \
682 }; \
683 /**/
684
685/** @ingroup Python
686 */
687#define PY_SHADOW_CLASS_PTRTRAITS(dllInterface, i_PyObjectShadowClass, t_CppClass, pointerTraits)\
688 PY_SHADOW_CLASS_EX(dllInterface, i_PyObjectShadowClass, t_CppClass, ::lass::python::PyObjectPlus, pointerTraits < t_CppClass > )
689
690/** @ingroup Python
691 */
692#define PY_SHADOW_CLASS(dllInterface, i_PyObjectShadowClass, t_CppClass)\
693 PY_SHADOW_CLASS_EX(dllInterface, i_PyObjectShadowClass, t_CppClass, ::lass::python::PyObjectPlus, ::lass::python::SharedPointerTraits< t_CppClass >)
694
695#define PY_SHADOW_CLASS_DERIVED(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectShadowParent)\
696 PY_SHADOW_CLASS_EX(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectShadowParent, t_PyObjectShadowParent::TPointerTraits::Rebind< t_CppClass >::Type )
697
698/** @ingroup Python
699 * @deprecated
700 */
701#define PY_SHADOW_CLASS_NOCONSTRUCTOR_EX(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectBase, t_PyObjectParent)\
702 PY_SHADOW_CLASS_EX(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectBase, t_PyObjectParent)
703
704/** @ingroup Python
705 * @deprecated
706 */
707#define PY_SHADOW_CLASS_NOCONSTRUCTOR(dllInterface, i_PyObjectShadowClass, t_CppClass)\
708 PY_SHADOW_CLASS(dllInterface, i_PyObjectShadowClass, t_CppClass)
709
710/** @ingroup Python
711 * @deprecated
712 */
713#define PY_WEAK_SHADOW_CLASS(dllInterface, i_PyObjectShadowClass, t_CppClass)\
714 PY_SHADOW_CLASS(dllInterface, i_PyObjectShadowClass, t_CppClass)
715
716/** @ingroup Python
717 * @deprecated
718 */
719#define PY_WEAK_SHADOW_CLASS_NOCONSTRUCTOR(dllInterface, i_PyObjectShadowClass, t_CppClass)\
720 PY_SHADOW_CLASS(dllInterface, i_PyObjectShadowClass, t_CppClass)
721
722/** @ingroup Python
723 * @deprecated
724 */
725#define PY_SHADOW_CLASS_ENABLE_AUTOMATIC_INVALIDATION(i_PyObjectShadowClass)
726
727/** @ingroup Python
728 * @deprecated
729 */
730#define PY_SHADOW_CLASS_DERIVED_NOCONSTRUCTOR(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectShadowParent)\
731 PY_SHADOW_CLASS_DERIVED(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectShadowParent)
732
733
734
735
736/** @ingroup Python
737 */
738#define PY_SHADOW_CASTERS(t_ShadowObject)\
739namespace lass \
740{ \
741namespace python \
742{ \
743 template <> struct ShadoweeTraits< t_ShadowObject::TShadowee >: ::lass::meta::True \
744 { \
745 typedef t_ShadowObject TShadow; \
746 /*typedef impl::ShadowTraits< t_ShadowObject > TShadowTraits;*/ \
747 typedef t_ShadowObject::TPointerTraits TPointerTraits; \
748 }; \
749} \
750} \
751/**/
752
753
754
755/** @ingroup Python
756 * @deprecated
757 */
758#define PY_SHADOW_DOWN_CASTERS(t_ShadowObject)\
759 PY_SHADOW_CASTERS(t_ShadowObject)
760
761/** @ingroup Python
762 * @deprecated
763 */
764#define PY_SHADOW_DOWN_CASTERS_NOCONSTRUCTOR(t_ShadowObject)\
765 PY_SHADOW_CASTERS(t_ShadowObject)
766
767
768
769
770#define PY_CLASS_CONVERTOR_EX( t_ShadowObject, v_conversionFunction, i_uniqueName )\
771 LASS_EXECUTE_BEFORE_MAIN_EX( LASS_CONCATENATE( lassPyClassConverter_, i_uniqueName ),\
772 lass::python::impl::ShadowTraits< t_ShadowObject >::addConverter( v_conversionFunction );\
773 )
774
775#define PY_CLASS_CONVERTOR( i_ShadowObject, t_sourceType )\
776 PY_CLASS_CONVERTOR_EX( i_ShadowObject, (::lass::python::impl::defaultConvertor< i_ShadowObject, t_sourceType >) , i_ShadowObject );
777
778
779
780#endif
781
782// EOF
PyObjectPtr< PyObject >::Type TPyObjPtr
PyObjectPtr to a PyObject.
std::conditional_t< std::is_const_v< ShadoweeType >, typename impl::ShadowTraits< typename ShadoweeTraits< ShadoweeType >::TShadow >::TConstCppClassPtr, typename impl::ShadowTraits< typename ShadoweeTraits< ShadoweeType >::TShadow >::TCppClassPtr > ShadoweePtr
Helper to get the pointer type holding the shadowee in a shadow object.
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