library of assembled shared sources

http://lass.cocamware.com

pyshadow_object.h

Go to the documentation of this file.
00001 /** @file
00002  *  @author Bram de Greve (bramz@users.sourceforge.net)
00003  *  @author Tom De Muer (tomdemuer@users.sourceforge.net)
00004  *
00005  *  Distributed under the terms of the GPL (GNU Public License)
00006  *
00007  *  The LASS License:
00008  *
00009  *  Copyright 2004-2008 Bram de Greve and Tom De Muer
00010  *
00011  *  LASS is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License
00022  *  along with this program; if not, write to the Free Software
00023  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024  *
00025  *  @note
00026  *      This header bundles the _EXPERIMENTAL_ code for quasi automatic
00027  *      wrapping of C++ object hierarchies into python shadow objects.  This
00028  *      code is still heavily under development and not ready for production use.
00029  */
00030 
00031 #ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_PYSHADOW_OBJECT_H
00032 #define LASS_GUARDIAN_OF_INCLUSION_UTIL_PYSHADOW_OBJECT_H
00033 
00034 #include "pyobject_plus.h"
00035 #include "../meta/is_derived.h"
00036 #include <set>
00037 
00038 namespace lass
00039 {
00040 namespace python
00041 {
00042 
00043 namespace impl
00044 {
00045 
00046 class LASS_DLL PyShadowBaseCommon: public PyObjectPlus
00047 {
00048 protected:
00049     PyShadowBaseCommon();
00050     PyShadowBaseCommon(const PyShadowBaseCommon& iOther);
00051     ~PyShadowBaseCommon();
00052     PyShadowBaseCommon& operator=(const PyShadowBaseCommon& iOther);    
00053 };
00054 
00055 template <class CppBase>
00056 class PyShadowBaseTracked : public PyShadowBaseCommon
00057 {
00058 public:
00059     PyShadowBaseTracked(CppBase* iObject=0, bool iTrack=false) : cppObject_(iObject)
00060     {
00061         if (iTrack)
00062             PyShadowBaseTracked<CppBase>::trackShadow(this);
00063     }
00064     virtual ~PyShadowBaseTracked()
00065     {
00066         PyShadowBaseTracked<CppBase>::forgetShadow(this);
00067     }
00068     class AutomaticObjectInvalidator
00069     {
00070     public:
00071         AutomaticObjectInvalidator() {}
00072         virtual ~AutomaticObjectInvalidator()
00073         {
00074             PyShadowBaseTracked<CppBase>::invalidateBase(static_cast<CppBase*>(this));
00075         }
00076     };
00077     static std::set<PyShadowBaseTracked<CppBase>*>* shadows_;
00078     static bool invalidateBase(CppBase* iBase)
00079     {
00080         if (!shadows_)
00081             return true;
00082         typename std::set<PyShadowBaseTracked<CppBase>*>::iterator it = shadows_->begin();
00083         for (;it!=shadows_->end();++it)
00084         {
00085             if ((*it)->cppObject_==iBase)
00086             {
00087                 (*it)->cppObject_ = NULL;       // invalidate
00088                 Py_INCREF(Py_None);
00089                 *(static_cast<PyObject*>(*it)) = *Py_None;
00090             }
00091         }
00092         return true;
00093     }
00094     static bool trackShadow(PyShadowBaseTracked<CppBase>* iShadow)
00095     {
00096         if (!shadows_)
00097             shadows_ = new std::set<PyShadowBaseTracked<CppBase>*>;
00098         if (shadows_)
00099             shadows_->insert(iShadow);
00100         return true;
00101     }
00102     static bool forgetShadow(PyShadowBaseTracked<CppBase>* iShadow)
00103     {
00104         if (shadows_)
00105             shadows_->erase(iShadow);
00106         return true;
00107     }
00108 protected:
00109     CppBase* cppObject_;
00110 };
00111 
00112 template <class CppBase> std::set<PyShadowBaseTracked<CppBase>*>* PyShadowBaseTracked<CppBase>::shadows_;
00113 
00114 
00115 template <class CppBase, bool weak = false>
00116 class PyShadowBase: public PyShadowBaseTracked<CppBase>
00117 {
00118 public:
00119     virtual ~PyShadowBase()
00120     {
00121         if (!weak && this->ownership_ == oOwner) 
00122         {
00123             delete this->cppObject_; 
00124             this->cppObject_ = 0;
00125         }
00126     }
00127     CppBase* cppObject() const
00128     {
00129         return this->cppObject_;
00130     }
00131     const CppBase* constCppObject() const
00132     {
00133         return this->cppObject_;
00134     }
00135     static bool doTracking;
00136 
00137 protected:
00138     enum Ownership
00139     {
00140         oOwner,
00141         oBorrowed
00142     };
00143     PyShadowBase(CppBase* iCppObject, Ownership iOwnership):
00144         PyShadowBaseTracked<CppBase>(iCppObject,doTracking),
00145         ownership_(iOwnership)
00146     {
00147         this->cppObject_ = iCppObject;
00148     }
00149 private:
00150     Ownership ownership_;
00151 };
00152 template <class CppBase, bool weak> bool PyShadowBase<CppBase,weak>::doTracking = false;
00153 }
00154 
00155 template <typename CppBase>
00156 struct ShadowObjectInvalidator
00157 {
00158     typedef typename impl::PyShadowBaseTracked<CppBase>::AutomaticObjectInvalidator Type;
00159 };
00160 
00161 template<typename CppBase>
00162 void invalidateShadowingObject(CppBase* iPointerReferenceToInvalidate)
00163 {
00164     impl::PyShadowBaseTracked<CppBase>::invalidateBase(iPointerReferenceToInvalidate);
00165 }
00166 
00167 namespace impl
00168 {
00169 
00170 /** a weak shadow class NEVER EVER owns the object, USE AT YOUR OWN RISK!  
00171 *   Consult your local Lass::Python guru to gain insight when the use of this
00172 *   class is appropriate.  A rule of thumb is that any properly designed 
00173 *   C++ interface should never be exposed using weak shadow objects.
00174 *   For your own safety, use weak shadow objects always in conjunction with the
00175 *   automatic object invalidator.  This at least assures that when you access 
00176 *   a weak shadow object from within Python that you don't get a dereference of 
00177 *   a dangling pointer.  You will notice that in Python a "C++ deleted" weak
00178 *   shadow object is transformed into None.
00179  */
00180 template <class CppBase>
00181 struct PyShadowBaseWeak
00182 {
00183     typedef PyShadowBase<CppBase,true> Type;
00184 };
00185 
00186 template <typename T>
00187 struct IsShadowClass: public meta::IsDerived<T, PyShadowBaseCommon> 
00188 {
00189 };
00190 
00191 
00192 
00193 template <typename T>
00194 struct ShadowTraits
00195 {
00196 private:
00197 
00198     template <typename U, bool shadow>
00199     struct Impl
00200     {
00201         typedef typename U::TCppClass TCppClass;
00202         static TCppClass* cppObject(U* iPyObject)
00203         {
00204             return static_cast<TCppClass*>(iPyObject->cppObject());
00205         };
00206         // this does nothing special in the general case, for specific use we
00207         // can override this function to only allow const calls on const shadowed objects
00208         static const TCppClass* constCppObject(U* iPyObject)
00209         {
00210             return static_cast<const TCppClass*>(iPyObject->constCppObject());
00211         };
00212         static U* pyObject(TCppClass* iCppObject)
00213         {
00214             std::auto_ptr<TCppClass> cppObject(iCppObject);
00215             return new U(cppObject);
00216         }
00217     };
00218 
00219     template <typename U>
00220     struct Impl<U, false>
00221     {
00222         typedef U TCppClass;
00223         static U* cppObject(U* iPyObject)
00224         {
00225             return iPyObject;
00226         };
00227         static const U* constCppObject(U* iPyObject)
00228         {
00229             return const_cast<U*>(iPyObject);
00230         };
00231         static U* pyObject(U* iCppObject)
00232         {
00233             return iCppObject;
00234         }
00235     };
00236 
00237 public:
00238 
00239     enum { isShadow = IsShadowClass<T>::value };
00240     typedef typename Impl<T, isShadow>::TCppClass TCppClass;
00241 
00242     typedef int (*TPyGetSimpleObjectByCopy)( PyObject* iObject, TCppClass& oByCopy );
00243     typedef int (*TPyGetSimpleObjectByBorrow)( PyObject* iObject, TCppClass*& oByBorrow );
00244 
00245     static std::vector<TPyGetSimpleObjectByCopy> byCopyGetters;
00246     static std::vector<TPyGetSimpleObjectByBorrow> byBorrowGetters;
00247 
00248     static TCppClass* cppObject(PyObject* iPyObject)
00249     {
00250         if (!PyType_IsSubtype(iPyObject->ob_type , &T::_lassPyType ))
00251         {
00252             PyErr_Format(PyExc_TypeError,"PyObject not castable to %s", T::_lassPyType.tp_name);
00253             return 0;
00254         }
00255         return Impl<T, isShadow>::cppObject(static_cast<T*>(iPyObject));
00256     };
00257     static const TCppClass* constCppObject(PyObject* iPyObject)
00258     {
00259         if (!PyType_IsSubtype(iPyObject->ob_type , &T::_lassPyType ))
00260         {
00261             PyErr_Format(PyExc_TypeError,"PyObject not castable to %s", T::_lassPyType.tp_name);
00262             return 0;
00263         }
00264         return Impl<T, isShadow>::constCppObject(static_cast<T*>(iPyObject));
00265     };
00266     static T* pyObject(TCppClass* iCppObject)
00267     {
00268         return Impl<T, isShadow>::pyObject(iCppObject);
00269     }
00270 };
00271 
00272 template<typename T> std::vector<typename ShadowTraits<T>::TPyGetSimpleObjectByCopy> ShadowTraits<T>::byCopyGetters;
00273 template<typename T> std::vector<typename ShadowTraits<T>::TPyGetSimpleObjectByBorrow> ShadowTraits<T>::byBorrowGetters;
00274 
00275 }
00276 
00277 }
00278 
00279 }
00280 
00281 #define PY_SHADOW_CLASS_EX(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectBase, t_PyObjectParent)\
00282     class dllInterface i_PyObjectShadowClass: public t_PyObjectBase\
00283     {\
00284         PY_HEADER(t_PyObjectParent)\
00285     public:\
00286         typedef t_CppClass TCppClass;\
00287         typedef t_PyObjectParent TPyParentClass;\
00288         i_PyObjectShadowClass(const TCppClass& iByCopy):\
00289             t_PyObjectBase(new TCppClass(iByCopy), oOwner) {}\
00290         i_PyObjectShadowClass(TCppClass* iByBorrowedPointer):\
00291             t_PyObjectBase(iByBorrowedPointer, oBorrowed) {}\
00292         i_PyObjectShadowClass(std::auto_ptr<TCppClass> iBySinkedPointer):\
00293             t_PyObjectBase(iBySinkedPointer.get(), oOwner) { iBySinkedPointer.release(); }\
00294     \
00295         typedef PyObject* (*TConstructorChainMethod)(TCppClass*);\
00296         static std::vector<TConstructorChainMethod>& constructors()\
00297         {\
00298             static std::vector<TConstructorChainMethod> constructors;\
00299             return constructors;\
00300         }\
00301         static PyObject* pyBuildSimpleObject_fromPtr(TCppClass* iPtr)\
00302         {\
00303             for (size_t i=0;i<constructors().size();++i)\
00304             {\
00305                 PyObject* tempObj = constructors()[i](iPtr);\
00306                 if ( (tempObj!=0) && (tempObj!=Py_None))\
00307                     return tempObj;\
00308             }\
00309             return ::lass::python::impl::fixObjectType(new i_PyObjectShadowClass( iPtr ));\
00310         }\
00311     protected:\
00312         i_PyObjectShadowClass(TCppClass* iValue, Ownership iOwnership):\
00313             t_PyObjectBase(iValue, iOwnership) {}\
00314     };\
00315 
00316 #define PY_SHADOW_CLASS_NOCONSTRUCTOR_EX(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectBase, t_PyObjectParent)\
00317     class dllInterface i_PyObjectShadowClass: public t_PyObjectBase\
00318     {\
00319         PY_HEADER(t_PyObjectParent)\
00320     public:\
00321         typedef t_CppClass TCppClass;\
00322         typedef t_PyObjectParent TPyParentClass;\
00323         i_PyObjectShadowClass(TCppClass* iByBorrowedPointer):\
00324             t_PyObjectBase(iByBorrowedPointer, oBorrowed) {}\
00325         i_PyObjectShadowClass(std::auto_ptr<TCppClass> iBySinkedPointer):\
00326             t_PyObjectBase(iBySinkedPointer.get(), oOwner) { iBySinkedPointer.release(); }\
00327     \
00328         typedef PyObject* (*TConstructorChainMethod)(TCppClass*);\
00329         static std::vector<TConstructorChainMethod>& constructors()\
00330         {\
00331             static std::vector<TConstructorChainMethod> constructors;\
00332             return constructors;\
00333         }\
00334         static PyObject* pyBuildSimpleObject_fromPtr(TCppClass* iPtr)\
00335         {\
00336             for (size_t i=0;i<constructors().size();++i)\
00337             {\
00338                 PyObject* tempObj = constructors()[i](iPtr);\
00339                 if ( (tempObj!=0) && (tempObj!=Py_None))\
00340                     return tempObj;\
00341             }\
00342             return ::lass::python::impl::fixObjectType(new i_PyObjectShadowClass( iPtr ));\
00343         }\
00344     protected:\
00345         i_PyObjectShadowClass(TCppClass* iValue, Ownership iOwnership):\
00346             t_PyObjectBase(iValue, iOwnership) {}\
00347     };\
00348 
00349 
00350 #define PY_SHADOW_CLASS(dllInterface, i_PyObjectShadowClass, t_CppClass)\
00351     PY_SHADOW_CLASS_EX(\
00352         dllInterface, i_PyObjectShadowClass, t_CppClass, lass::python::impl::PyShadowBase< t_CppClass >,\
00353         lass::python::PyObjectPlus)
00354 
00355 #define PY_SHADOW_CLASS_NOCONSTRUCTOR(dllInterface, i_PyObjectShadowClass, t_CppClass)\
00356     PY_SHADOW_CLASS_NOCONSTRUCTOR_EX(\
00357         dllInterface, i_PyObjectShadowClass, t_CppClass, lass::python::impl::PyShadowBase< t_CppClass >,\
00358         lass::python::PyObjectPlus)
00359 
00360 
00361 /** a weak shadow class NEVER EVER owns the object, USE AT YOUR OWN RISK!  
00362 *   Consult your local Lass::Python guru to gain insight when the use of this
00363 *   class is appropriate.  A rule of thumb is that any properly designed 
00364 *   C++ interface should never be exposed using weak shadow objects.
00365  */
00366 #define PY_WEAK_SHADOW_CLASS(dllInterface, i_PyObjectShadowClass, t_CppClass)\
00367     PY_SHADOW_CLASS_EX(\
00368     dllInterface, i_PyObjectShadowClass, t_CppClass, lass::python::impl::PyShadowBaseWeak< t_CppClass >::Type ,\
00369         lass::python::PyObjectPlus)
00370 
00371 #define PY_WEAK_SHADOW_CLASS_NOCONSTRUCTOR(dllInterface, i_PyObjectShadowClass, t_CppClass)\
00372     PY_SHADOW_CLASS_NOCONSTRUCTOR_EX(\
00373     dllInterface, i_PyObjectShadowClass, t_CppClass, lass::python::impl::PyShadowBaseWeak< t_CppClass >::Type ,\
00374         lass::python::PyObjectPlus)
00375 
00376 
00377 /** a macro to enable automatic invalidation for a given shadow class */
00378 #define PY_SHADOW_CLASS_ENABLE_AUTOMATIC_INVALIDATION(i_PyObjectShadowClass)\
00379     i_PyObjectShadowClass::doTracking = true;
00380 
00381 #define PY_SHADOW_CLASS_DERIVED(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectShadowParent)\
00382     PY_SHADOW_CLASS_EX(\
00383         dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectShadowParent, t_PyObjectShadowParent)
00384 
00385 #define PY_SHADOW_CLASS_DERIVED_NOCONSTRUCTOR(dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectShadowParent)\
00386     PY_SHADOW_CLASS_NOCONSTRUCTOR_EX(\
00387         dllInterface, i_PyObjectShadowClass, t_CppClass, t_PyObjectShadowParent, t_PyObjectShadowParent)
00388 
00389 
00390 /** a macro that enables shadow classes to have conversion (coercion) operations defined on construction 
00391 *   Say you have following situation:
00392 *       class A 
00393 *       { 
00394 *           A(int a) {} 
00395 *       };
00396 *       class B
00397 *       {
00398 *           B(const A& iA) {}
00399 *       };
00400 *   You may whish to create an object B with int as constructor argument, without having proper custom pyGetSimpleObject
00401 *   this will not work unless you use the PY_CLASS_CONVERTOR macro to let the conversion routines know which possibilities 
00402 *   may be tried before giving up and throwing a not-casteable exception.
00403 */
00404 #pragma LASS_TODO("Check if the convertor macro's don't leak any memory")
00405 
00406 #define PY_CLASS_CONSTRUCTOR_BYCOPY_IMPL( t_ShadowObject )\
00407 inline int pyGetSimpleObject(PyObject* iValue, lass::util::SharedPtr<t_ShadowObject, lass::python::PyObjectStorage, lass::python::PyObjectCounter>& oV)\
00408 {\
00409     const bool isNone = (iValue == Py_None );\
00410     if (isNone)\
00411         oV = lass::util::SharedPtr< t_ShadowObject, lass::python::PyObjectStorage, lass::python::PyObjectCounter>();\
00412     else\
00413     {\
00414         if (!PyType_IsSubtype(iValue->ob_type , & t_ShadowObject::_lassPyType ))\
00415         {\
00416             for (size_t i=0;i<lass::python::impl::ShadowTraits< t_ShadowObject >::byCopyGetters.size();++i)\
00417             {\
00418                 lass::python::impl::ShadowTraits< t_ShadowObject >::TCppClass* newCopy = new lass::python::impl::ShadowTraits< t_ShadowObject >::TCppClass();\
00419                 if (!lass::python::impl::ShadowTraits< t_ShadowObject >::byCopyGetters[i](iValue, *newCopy))\
00420                 {\
00421                     typedef lass::util::SharedPtr<t_ShadowObject, lass::python::PyObjectStorage, lass::python::PyObjectCounter> TSharedPtr;\
00422                     TSharedPtr newOv(new t_ShadowObject (newCopy));\
00423                     oV.swap(newOv);\
00424                     PyErr_Clear();\
00425                     return 0;\
00426                 }\
00427             }\
00428             PyErr_Format(PyExc_TypeError,"not castable to %s", t_ShadowObject::_lassPyType.tp_name);\
00429             return 1;\
00430         }\
00431         oV = lass::python::fromNakedToSharedPtrCast< t_ShadowObject >(iValue);\
00432     }\
00433     return 0;\
00434 }
00435 
00436 
00437 #define PY_SHADOW_CASTERS(t_ShadowObject)\
00438 namespace lass\
00439 {\
00440 namespace python\
00441 {\
00442 namespace impl\
00443 {\
00444 template <> struct ArgumentTraits< t_ShadowObject::TCppClass >\
00445 {\
00446     typedef t_ShadowObject::TCppClass TCppClass;\
00447     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00448     static const TCppClass& arg(const TStorage& iArg)\
00449     {\
00450         return *static_cast<TCppClass*>(iArg->cppObject());\
00451     }\
00452 };\
00453 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass >\
00454 {\
00455     typedef t_ShadowObject::TCppClass TCppClass;\
00456     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00457     static const TCppClass& arg(const TStorage& iArg)\
00458     {\
00459         return *static_cast<TCppClass*>(iArg->cppObject());\
00460     }\
00461 };\
00462 template <> struct ArgumentTraits< t_ShadowObject::TCppClass& >\
00463 {\
00464     typedef t_ShadowObject::TCppClass TCppClass;\
00465     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00466     static TCppClass& arg(const TStorage& iArg)\
00467     {\
00468         return *static_cast<TCppClass*>(iArg->cppObject());\
00469     }\
00470 };\
00471 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass& >\
00472 {\
00473     typedef t_ShadowObject::TCppClass TCppClass;\
00474     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00475     static const TCppClass& arg(const TStorage& iArg)\
00476     {\
00477         return *static_cast<TCppClass*>(iArg->cppObject());\
00478     }\
00479 };\
00480 template <> struct ArgumentTraits< t_ShadowObject::TCppClass* >\
00481 {\
00482     typedef t_ShadowObject::TCppClass TCppClass;\
00483     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00484     static TCppClass* arg(const TStorage& iArg)\
00485     {\
00486         return static_cast<TCppClass*>(iArg->cppObject());\
00487     }\
00488 };\
00489 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass* >\
00490 {\
00491     typedef t_ShadowObject::TCppClass TCppClass;\
00492     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00493     static const TCppClass* arg(const TStorage& iArg)\
00494     {\
00495         return static_cast<TCppClass*>(iArg->cppObject());\
00496     }\
00497 };\
00498 template <> struct ArgumentTraits< t_ShadowObject::TCppClass* const >\
00499 {\
00500     typedef t_ShadowObject::TCppClass TCppClass;\
00501     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00502     static TCppClass* const arg(const TStorage& iArg)\
00503     {\
00504         return static_cast<TCppClass*>(iArg->cppObject());\
00505     }\
00506 };\
00507 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass* const >\
00508 {\
00509     typedef t_ShadowObject::TCppClass TCppClass;\
00510     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00511     static const TCppClass* const arg(const TStorage& iArg)\
00512     {\
00513         return static_cast<TCppClass*>(iArg->cppObject());\
00514     }\
00515 };\
00516 }\
00517 inline PyObject* pyBuildSimpleObject_deprecated( const t_ShadowObject::TCppClass& iByCopy )\
00518 {\
00519     return ::lass::python::impl::fixObjectType(new t_ShadowObject( iByCopy ));\
00520 }\
00521 inline PyObject* pyBuildSimpleObject_deprecated( t_ShadowObject::TCppClass* iByBorrowedPointer )\
00522 {\
00523     return ::lass::python::impl::fixObjectType(new t_ShadowObject( iByBorrowedPointer ));\
00524 }\
00525 inline PyObject* pyBuildSimpleObject_deprecated( t_ShadowObject::TCppClass& iByBorrowedPointer )\
00526 {\
00527     return pyBuildSimpleObject_deprecated(&iByBorrowedPointer);\
00528 }\
00529 inline PyObject* pyBuildSimpleObject_deprecated( std::auto_ptr< t_ShadowObject::TCppClass > iBySinkedPointer )\
00530 {\
00531     return ::lass::python::impl::fixObjectType(new t_ShadowObject( iBySinkedPointer ));\
00532 }\
00533 inline int pyGetSimpleObject_deprecated( PyObject* iObject, t_ShadowObject::TCppClass& oByCopy )\
00534 {\
00535     if (t_ShadowObject::TCppClass* cppObject = \
00536         impl::ShadowTraits< t_ShadowObject >::cppObject(iObject))\
00537     {\
00538         oByCopy = *cppObject;\
00539         return 0;\
00540     }\
00541     return 1;\
00542 }\
00543 inline int pyGetSimpleObject_deprecated( PyObject* iObject, t_ShadowObject::TCppClass*& oByBorrowedPointer )\
00544 {\
00545     if (t_ShadowObject::TCppClass* cppObject = \
00546         impl::ShadowTraits< t_ShadowObject >::cppObject(iObject))\
00547     {\
00548         oByBorrowedPointer = cppObject;\
00549         return 0;\
00550     }\
00551     return 1;\
00552 }\
00553 template <> \
00554 struct PyExportTraits< t_ShadowObject::TCppClass > \
00555 {\
00556     static PyObject* build(const t_ShadowObject::TCppClass& iByCopy) { return pyBuildSimpleObject_deprecated(iByCopy); }\
00557     static int get(PyObject* iV, t_ShadowObject::TCppClass& oV) { return pyGetSimpleObject_deprecated(iV,oV); }\
00558 };\
00559 template <> \
00560 struct PyExportTraits< std::auto_ptr< t_ShadowObject::TCppClass > > \
00561 {\
00562     static PyObject* build(std::auto_ptr< t_ShadowObject::TCppClass > iBySinkedPointer) { return pyBuildSimpleObject_deprecated(iBySinkedPointer); }\
00563     static int get(PyObject* iV, t_ShadowObject::TCppClass& oV) { return pyGetSimpleObject_deprecated(iV,oV); }\
00564 };\
00565 }\
00566 }
00567 
00568 
00569 #define PY_SHADOW_DOWN_CASTERS(t_ShadowObject)\
00570 namespace lass\
00571 {\
00572 namespace python\
00573 {\
00574 namespace impl\
00575 {\
00576 template <> struct ArgumentTraits< t_ShadowObject::TCppClass >\
00577 {\
00578     typedef t_ShadowObject::TCppClass TCppClass;\
00579     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00580     static const TCppClass& arg(const TStorage& iArg)\
00581     {\
00582         if (!iArg) LASS_THROW("Null pointer reference");\
00583         return *static_cast<TCppClass*>(iArg->cppObject());\
00584     }\
00585 };\
00586 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass >\
00587 {\
00588     typedef t_ShadowObject::TCppClass TCppClass;\
00589     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00590     static const TCppClass& arg(const TStorage& iArg)\
00591     {\
00592         if (!iArg) LASS_THROW("Null pointer reference");\
00593         return *static_cast<TCppClass*>(iArg->cppObject());\
00594     }\
00595 };\
00596 template <> struct ArgumentTraits< t_ShadowObject::TCppClass& >\
00597 {\
00598     typedef t_ShadowObject::TCppClass TCppClass;\
00599     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00600     static TCppClass& arg(const TStorage& iArg)\
00601     {\
00602         if (!iArg) LASS_THROW("Null pointer reference");\
00603         return *static_cast<TCppClass*>(iArg->cppObject());\
00604     }\
00605 };\
00606 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass& >\
00607 {\
00608     typedef t_ShadowObject::TCppClass TCppClass;\
00609     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00610     static const TCppClass& arg(const TStorage& iArg)\
00611     {\
00612         if (!iArg) LASS_THROW("Null pointer reference");\
00613         return *static_cast<TCppClass*>(iArg->cppObject());\
00614     }\
00615 };\
00616 template <> struct ArgumentTraits< t_ShadowObject::TCppClass* >\
00617 {\
00618     typedef t_ShadowObject::TCppClass TCppClass;\
00619     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00620     static TCppClass* arg(const TStorage& iArg)\
00621     {\
00622         if (!iArg) return 0;\
00623         return static_cast<TCppClass*>(iArg->cppObject());\
00624     }\
00625 };\
00626 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass* >\
00627 {\
00628     typedef t_ShadowObject::TCppClass TCppClass;\
00629     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00630     static const TCppClass* arg(const TStorage& iArg)\
00631     {\
00632         if (!iArg) return 0;\
00633         return static_cast<TCppClass*>(iArg->cppObject());\
00634     }\
00635 };\
00636 template <> struct ArgumentTraits< t_ShadowObject::TCppClass* const >\
00637 {\
00638     typedef t_ShadowObject::TCppClass TCppClass;\
00639     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00640     static TCppClass* const arg(const TStorage& iArg)\
00641     {\
00642         if (!iArg) return 0;\
00643         return static_cast<TCppClass*>(iArg->cppObject());\
00644     }\
00645 };\
00646 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass* const >\
00647 {\
00648     typedef t_ShadowObject::TCppClass TCppClass;\
00649     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00650     static const TCppClass* const arg(const TStorage& iArg)\
00651     {\
00652         if (!iArg) return 0;\
00653         return static_cast<TCppClass*>(iArg->cppObject());\
00654     }\
00655 };\
00656 }\
00657 inline PyObject* pyBuildSimpleObject_deprecated( const t_ShadowObject::TCppClass& iByCopy )\
00658 {\
00659     return ::lass::python::impl::fixObjectType(new t_ShadowObject( iByCopy ));\
00660 }\
00661 inline PyObject* pyBuildSimpleObject_deprecated( t_ShadowObject::TCppClass* iByBorrowedPointer )\
00662 {\
00663     return t_ShadowObject::pyBuildSimpleObject_fromPtr( iByBorrowedPointer );\
00664 }\
00665 inline PyObject* pyBuildSimpleObject_deprecated( t_ShadowObject::TCppClass& iByBorrowedPointer )\
00666 {\
00667     return pyBuildSimpleObject_deprecated(&iByBorrowedPointer);\
00668 }\
00669 inline PyObject* pyBuildSimpleObject_deprecated( std::auto_ptr< t_ShadowObject::TCppClass > iBySinkedPointer )\
00670 {\
00671     return ::lass::python::impl::fixObjectType(new t_ShadowObject( iBySinkedPointer ));\
00672 }\
00673 inline int pyGetSimpleObject_deprecated( PyObject* iObject, t_ShadowObject::TCppClass& oByCopy )\
00674 {\
00675     if (t_ShadowObject::TCppClass* cppObject = \
00676         impl::ShadowTraits< t_ShadowObject >::cppObject(iObject))\
00677     {\
00678         oByCopy = *cppObject;\
00679         return 0;\
00680     }\
00681     for (size_t i=0;i<impl::ShadowTraits< t_ShadowObject >::byCopyGetters.size();++i)\
00682     {\
00683         if (!impl::ShadowTraits< t_ShadowObject >::byCopyGetters[i](iObject, oByCopy))\
00684             return 0;\
00685     }\
00686     return 1;\
00687 }\
00688 inline int pyGetSimpleObject_deprecated( PyObject* iObject, t_ShadowObject::TCppClass*& oByBorrowedPointer )\
00689 {\
00690     if (t_ShadowObject::TCppClass* cppObject = \
00691         impl::ShadowTraits< t_ShadowObject >::cppObject(iObject))\
00692     {\
00693         oByBorrowedPointer = cppObject;\
00694         return 0;\
00695     }\
00696     for (size_t i=0;i<impl::ShadowTraits< t_ShadowObject >::byBorrowGetters.size();++i)\
00697     {\
00698         if (!impl::ShadowTraits< t_ShadowObject >::byBorrowGetters[i](iObject, oByBorrowedPointer))\
00699             return 0;\
00700     }\
00701     return 1;\
00702 }\
00703 template <> \
00704 struct PyExportTraits< t_ShadowObject::TCppClass > \
00705 {\
00706     static PyObject* build(const t_ShadowObject::TCppClass& iByCopy) { return pyBuildSimpleObject_deprecated(iByCopy); }\
00707     static int get(PyObject* iV, t_ShadowObject::TCppClass& oV) { return pyGetSimpleObject_deprecated(iV,oV); }\
00708 };\
00709 template <> \
00710 struct PyExportTraits< const t_ShadowObject::TCppClass > \
00711 {\
00712     static PyObject* build(const t_ShadowObject::TCppClass& iByCopy) { return pyBuildSimpleObject_deprecated(iByCopy); }\
00713     static int get(PyObject* iV, t_ShadowObject::TCppClass& oV) { return pyGetSimpleObject_deprecated(iV,oV); }\
00714 };\
00715 template <> \
00716 struct PyExportTraits< t_ShadowObject::TCppClass & > \
00717 {\
00718     static PyObject* build(t_ShadowObject::TCppClass& iByCopy) { return pyBuildSimpleObject_deprecated(iByCopy); }\
00719     static int get(PyObject* iV, t_ShadowObject::TCppClass& oV) { return pyGetSimpleObject_deprecated(iV,oV); }\
00720 };\
00721 template <> \
00722 struct PyExportTraits< const t_ShadowObject::TCppClass& > \
00723 {\
00724     static PyObject* build(const t_ShadowObject::TCppClass& iByCopy) { return pyBuildSimpleObject_deprecated(iByCopy); }\
00725     static int get(PyObject* iV, t_ShadowObject::TCppClass& oV) { return pyGetSimpleObject_deprecated(iV,oV); }\
00726 };\
00727 template <> \
00728 struct PyExportTraits< std::auto_ptr< t_ShadowObject::TCppClass > > \
00729 {\
00730     static PyObject* build(std::auto_ptr< t_ShadowObject::TCppClass > iBySinkedPointer) { return pyBuildSimpleObject_deprecated(iBySinkedPointer); }\
00731     static int get(PyObject* iV, t_ShadowObject::TCppClass& oV) { return pyGetSimpleObject_deprecated(iV,oV); }\
00732 };\
00733 template <> \
00734 struct PyExportTraits< t_ShadowObject::TCppClass* > \
00735 {\
00736     static PyObject* build(t_ShadowObject::TCppClass* iByCopy) { return pyBuildSimpleObject_deprecated(iByCopy); }\
00737     static int get(PyObject* iV, t_ShadowObject::TCppClass& oV) { return pyGetSimpleObject_deprecated(iV,oV); }\
00738 };\
00739 template <> \
00740 struct PyExportTraits< const t_ShadowObject::TCppClass* > \
00741 {\
00742     static PyObject* build(const t_ShadowObject::TCppClass* iByCopy) { return pyBuildSimpleObject_deprecated(*iByCopy); }\
00743     static int get(PyObject* iV, t_ShadowObject::TCppClass& oV) { return pyGetSimpleObject_deprecated(iV,oV); }\
00744 };\
00745 PY_CLASS_CONSTRUCTOR_BYCOPY_IMPL( t_ShadowObject) \
00746 inline PyObject* LASS_CONCATENATE_3(pyBuildSimpleObject,t_ShadowObject,FromParent) ( \
00747     lass::meta::Select< \
00748         lass::meta::IsSame<t_ShadowObject::TPyParentClass, lass::python::PyObjectPlus>, \
00749             t_ShadowObject::TCppClass , \
00750             t_ShadowObject::TPyParentClass::TCppClass>::Type \
00751     * iByBorrowedPointer)\
00752 {\
00753     if (dynamic_cast<t_ShadowObject::TCppClass*>(iByBorrowedPointer))\
00754     {\
00755         t_ShadowObject::TCppClass* downCastedObject = dynamic_cast<t_ShadowObject::TCppClass*>(iByBorrowedPointer);\
00756         return lass::python::pyBuildSimpleObject_deprecated(downCastedObject);\
00757     }\
00758     return 0;\
00759 }\
00760 template <typename THasRealPyParent,typename TDummy>\
00761 struct ParentClassInjectorSelector_##t_ShadowObject\
00762 {\
00763     static void doStuff() {}\
00764 };\
00765 template <typename TDummy> \
00766 struct ParentClassInjectorSelector_##t_ShadowObject <lass::meta::False::Type, TDummy>\
00767 {\
00768     static void doStuff()\
00769     {\
00770         TDummy::constructors().push_back(& LASS_CONCATENATE_3(pyBuildSimpleObject,t_ShadowObject,FromParent));  \
00771     }\
00772 };\
00773 typedef ParentClassInjectorSelector_##t_ShadowObject < lass::meta::IsSame<t_ShadowObject::TPyParentClass, lass::python::PyObjectPlus>::Type, t_ShadowObject::TPyParentClass > SelectorFor_##t_ShadowObject;\
00774 LASS_EXECUTE_BEFORE_MAIN_EX( t_ShadowObject, SelectorFor_##t_ShadowObject::doStuff(); )\
00775 }\
00776 }
00777 
00778 #define PY_SHADOW_DOWN_CASTERS_NOCONSTRUCTOR(t_ShadowObject)\
00779 namespace lass\
00780 {\
00781 namespace python\
00782 {\
00783 namespace impl\
00784 {\
00785 template <> struct ArgumentTraits< t_ShadowObject::TCppClass >\
00786 {\
00787     typedef t_ShadowObject::TCppClass TCppClass;\
00788     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00789     static const TCppClass& arg(const TStorage& iArg)\
00790     {\
00791         if (!iArg) LASS_THROW("Null pointer reference");\
00792         return *static_cast<TCppClass*>(iArg->cppObject());\
00793     }\
00794 };\
00795 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass >\
00796 {\
00797     typedef t_ShadowObject::TCppClass TCppClass;\
00798     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00799     static const TCppClass& arg(const TStorage& iArg)\
00800     {\
00801         if (!iArg) LASS_THROW("Null pointer reference");\
00802         return *static_cast<TCppClass*>(iArg->cppObject());\
00803     }\
00804 };\
00805 template <> struct ArgumentTraits< t_ShadowObject::TCppClass& >\
00806 {\
00807     typedef t_ShadowObject::TCppClass TCppClass;\
00808     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00809     static TCppClass& arg(const TStorage& iArg)\
00810     {\
00811         if (!iArg) LASS_THROW("Null pointer reference");\
00812         return *static_cast<TCppClass*>(iArg->cppObject());\
00813     }\
00814 };\
00815 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass& >\
00816 {\
00817     typedef t_ShadowObject::TCppClass TCppClass;\
00818     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00819     static const TCppClass& arg(const TStorage& iArg)\
00820     {\
00821         if (!iArg) LASS_THROW("Null pointer reference");\
00822         return *static_cast<TCppClass*>(iArg->cppObject());\
00823     }\
00824 };\
00825 template <> struct ArgumentTraits< t_ShadowObject::TCppClass* >\
00826 {\
00827     typedef t_ShadowObject::TCppClass TCppClass;\
00828     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00829     static TCppClass* arg(const TStorage& iArg)\
00830     {\
00831         if (!iArg) return 0;\
00832         return static_cast<TCppClass*>(iArg->cppObject());\
00833     }\
00834 };\
00835 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass* >\
00836 {\
00837     typedef t_ShadowObject::TCppClass TCppClass;\
00838     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00839     static const TCppClass* arg(const TStorage& iArg)\
00840     {\
00841         if (!iArg) return 0;\
00842         return static_cast<TCppClass*>(iArg->cppObject());\
00843     }\
00844 };\
00845 template <> struct ArgumentTraits< t_ShadowObject::TCppClass* const >\
00846 {\
00847     typedef t_ShadowObject::TCppClass TCppClass;\
00848     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00849     static TCppClass* const arg(const TStorage& iArg)\
00850     {\
00851         if (!iArg) return 0;\
00852         return static_cast<TCppClass*>(iArg->cppObject());\
00853     }\
00854 };\
00855 template <> struct ArgumentTraits< const t_ShadowObject::TCppClass* const >\
00856 {\
00857     typedef t_ShadowObject::TCppClass TCppClass;\
00858     typedef PyObjectPtr<t_ShadowObject>::Type TStorage;\
00859     static const TCppClass* const arg(const TStorage& iArg)\
00860     {\
00861         if (!iArg) return 0;\
00862         return static_cast<TCppClass*>(iArg->cppObject());\
00863     }\
00864 };\
00865 }\
00866 inline PyObject* pyBuildSimpleObject_deprecated( const t_ShadowObject::TCppClass& iByBorrowedPointer )\
00867 {\
00868     return t_ShadowObject::pyBuildSimpleObject_fromPtr( const_cast<t_ShadowObject::TCppClass*>(&iByBorrowedPointer) );\
00869 }\
00870 inline PyObject* pyBuildSimpleObject_deprecated( t_ShadowObject::TCppClass* iByBorrowedPointer )\
00871 {\
00872     return t_ShadowObject::pyBuildSimpleObject_fromPtr( iByBorrowedPointer );\
00873 }\
00874 inline PyObject* pyBuildSimpleObject_deprecated( t_ShadowObject::TCppClass& iByBorrowedPointer )\
00875 {\
00876     return pyBuildSimpleObject_deprecated(&iByBorrowedPointer);\
00877 }\
00878 inline PyObject* pyBuildSimpleObject_deprecated( std::auto_ptr< t_ShadowObject::TCppClass > iBySinkedPointer )\
00879 {\
00880     return ::lass::python::impl::fixObjectType(new t_ShadowObject( iBySinkedPointer ));\
00881 }\
00882 inline int pyGetSimpleObject_deprecated( PyObject* iObject, t_ShadowObject::TCppClass*& oByBorrowedPointer )\
00883 {\
00884     if (t_ShadowObject::TCppClass* cppObject = \
00885         impl::ShadowTraits< t_ShadowObject >::cppObject(iObject))\
00886     {\
00887         oByBorrowedPointer = cppObject;\
00888         return 0;\
00889     }\
00890     return 1;\
00891 }\
00892 template <> \
00893 struct PyExportTraits< t_ShadowObject::TCppClass > \
00894 {\
00895     static PyObject* build(const t_ShadowObject::TCppClass& iByCopy) { return pyBuildSimpleObject_deprecated(iByCopy); }\
00896     static int get(PyObject* iV, t_ShadowObject::TCppClass& oV) { return pyGetSimpleObject_deprecated(iV,oV); }\
00897 };\
00898 template <> \
00899 struct PyExportTraits< std::auto_ptr< t_ShadowObject::TCppClass > > \
00900 {\
00901     static PyObject* build(std::auto_ptr< t_ShadowObject::TCppClass > iBySinkedPointer) { return pyBuildSimpleObject_deprecated(iBySinkedPointer); }\
00902 };\
00903 inline PyObject* LASS_CONCATENATE_3(pyBuildSimpleObject,t_ShadowObject,FromParent) ( \
00904     lass::meta::Select< \
00905         lass::meta::IsSame< t_ShadowObject::TPyParentClass, lass::python::PyObjectPlus>, \
00906             t_ShadowObject::TCppClass , \
00907             t_ShadowObject::TPyParentClass::TCppClass>::Type \
00908     * iByBorrowedPointer)\
00909 {\
00910     if (dynamic_cast< t_ShadowObject::TCppClass*>(iByBorrowedPointer))\
00911     {\
00912         t_ShadowObject::TCppClass* downCastedObject = dynamic_cast<t_ShadowObject::TCppClass*>(iByBorrowedPointer);\
00913         return lass::python::pyBuildSimpleObject_deprecated(downCastedObject);\
00914     }\
00915     return 0;\
00916 }\
00917 template <typename THasRealPyParent>\
00918 struct ParentClassInjectorSelector_##t_ShadowObject\
00919 {\
00920     static void doStuff()\
00921     {\
00922         THasRealPyParent::constructors().push_back(& LASS_CONCATENATE_3(pyBuildSimpleObject,t_ShadowObject,FromParent));    \
00923     }\
00924 };\
00925 template <> \
00926 struct ParentClassInjectorSelector_##t_ShadowObject < lass::python::PyObjectPlus >\
00927 {\
00928     static void doStuff() {}\
00929 };\
00930 typedef ParentClassInjectorSelector_##t_ShadowObject < t_ShadowObject::TPyParentClass > SelectorFor_##t_ShadowObject;\
00931 LASS_EXECUTE_BEFORE_MAIN_EX( t_ShadowObject, SelectorFor_##t_ShadowObject::doStuff(); )\
00932 }\
00933 }
00934 
00935 /*
00936 
00937 The insert before main does not seem to work, probably initialization order problem, so we inject at runtime!
00938 
00939 #define PY_CLASS_CONVERTOR_IMPL( t_ShadowObject, i_conversionFunction, i_dispatcher, i_typeOfConvertor )\
00940     namespace lass { namespace python { namespace impl {\
00941     void i_dispatcher()\
00942     {\
00943     impl::ShadowTraits< t_ShadowObject >::##i_typeOfConvertor##.push_back( i_conversionFunction);\
00944     }\
00945     LASS_EXECUTE_BEFORE_MAIN_EX( t_ShadowObjectConversionInjector, i_dispatcher(); )\
00946     } } }
00947 
00948 #define PY_CLASS_CONVERTOR_BYCOPY( t_ShadowObject, i_conversionFunction )\
00949     PY_CLASS_CONVERTOR_IMPL( t_ShadowObject, i_conversionFunction , LASS_UNIQUENAME(insertConversion), byCopyGetters )
00950 
00951 #define PY_CLASS_CONVERTOR_BYBORROW( t_ShadowObject, i_conversionFunction )\
00952     PY_CLASS_CONVERTOR_IMPL( t_ShadowObject, i_conversionFunction , LASS_UNIQUENAME(insertConversion), byBorrowGetters )
00953 */
00954 
00955 #define PY_CLASS_CONVERTOR( t_ShadowObject,  i_conversionFunction ) \
00956     lass::python::impl::ShadowTraits< t_ShadowObject >::byCopyGetters.push_back( & i_conversionFunction );
00957 
00958 
00959 
00960 #endif
00961 
00962 // EOF
00963 
00964 

Generated on Mon Nov 10 14:21:06 2008 for Library of Assembled Shared Sources by doxygen 1.5.7.1
SourceForge.net Logo