library of assembled shared sources

http://lass.cocamware.com

pyobject_plus.inl

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  *  *** BEGIN LICENSE INFORMATION ***
00006  *  
00007  *  The contents of this file are subject to the Common Public Attribution License 
00008  *  Version 1.0 (the "License"); you may not use this file except in compliance with 
00009  *  the License. You may obtain a copy of the License at 
00010  *  http://lass.sourceforge.net/cpal-license. The License is based on the 
00011  *  Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 
00012  *  use of software over a computer network and provide for limited attribution for 
00013  *  the Original Developer. In addition, Exhibit A has been modified to be consistent 
00014  *  with Exhibit B.
00015  *  
00016  *  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 
00017  *  WARRANTY OF ANY KIND, either express or implied. See the License for the specific 
00018  *  language governing rights and limitations under the License.
00019  *  
00020  *  The Original Code is LASS - Library of Assembled Shared Sources.
00021  *  
00022  *  The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
00023  *  The Original Developer is the Initial Developer.
00024  *  
00025  *  All portions of the code written by the Initial Developer are:
00026  *  Copyright (C) 2004-2007 the Initial Developer.
00027  *  All Rights Reserved.
00028  *  
00029  *  Contributor(s):
00030  *
00031  *  Alternatively, the contents of this file may be used under the terms of the 
00032  *  GNU General Public License Version 2 or later (the GPL), in which case the 
00033  *  provisions of GPL are applicable instead of those above.  If you wish to allow use
00034  *  of your version of this file only under the terms of the GPL and not to allow 
00035  *  others to use your version of this file under the CPAL, indicate your decision by 
00036  *  deleting the provisions above and replace them with the notice and other 
00037  *  provisions required by the GPL License. If you do not delete the provisions above,
00038  *  a recipient may use your version of this file under either the CPAL or the GPL.
00039  *  
00040  *  *** END LICENSE INFORMATION ***
00041  */
00042 
00043 namespace lass
00044 {
00045 namespace python
00046 {
00047 
00048 // --- impl ----------------------------------------------------------------------------------------
00049 
00050 namespace impl
00051 {
00052 
00053 /** @internal
00054  */
00055 template <PyCFunction DispatcherAddress>
00056 PyObject* unaryDispatcher(PyObject* iSelf)
00057 {
00058     TPyObjPtr args(PyTuple_New(0));
00059     return DispatcherAddress(iSelf, args.get());
00060 }
00061 
00062 /** @internal
00063 */
00064 template <PyCFunction DispatcherAddress>
00065 PyObject* binaryDispatcher(PyObject* iSelf, PyObject* iOther)
00066 {
00067     TPyObjPtr args(Py_BuildValue("(O)", iOther));
00068     return DispatcherAddress(iSelf, args.get());
00069 }
00070 
00071 /** @internal
00072 */
00073 template <PyCFunction DispatcherAddress>
00074 PyObject* ternaryDispatcher(PyObject* iSelf, PyObject* iArgs, PyObject* iKw)
00075 {
00076     if (iKw)
00077     {
00078         PyErr_SetString(PyExc_TypeError, "keyword arguments are not supported");
00079         return 0;
00080     }
00081     return DispatcherAddress(iSelf, iArgs);
00082 }
00083 
00084 /** @internal
00085 */
00086 template <PyCFunction DispatcherAddress>
00087 PyObject* ssizeargDispatcher( PyObject * iSelf, Py_ssize_t iSize)
00088 {
00089     TPyObjPtr args(Py_BuildValue("(n)", iSize));
00090     return DispatcherAddress(iSelf,args.get());
00091 }
00092 
00093 /** @internal
00094 */
00095 template <PyCFunction DispatcherAddress>
00096 PyObject* ssizessizeargDispatcher( PyObject * iSelf, Py_ssize_t iSize, Py_ssize_t iSize2)
00097 {
00098     TPyObjPtr args(Py_BuildValue("(n,n)", iSize, iSize2));
00099     return DispatcherAddress(iSelf,args.get());
00100 }
00101 
00102 /** @internal
00103 */
00104 template <PyCFunction DispatcherAddress>
00105 Py_ssize_t lenDispatcher( PyObject * iSelf)
00106 {
00107     TPyObjPtr args(Py_BuildValue("()"));
00108     PyObject* temp = DispatcherAddress(iSelf,args.get());
00109     if (!temp)
00110         return 0;
00111     return PyInt_AsSsize_t(temp);
00112 }
00113 
00114 /** @internal
00115 */
00116 template <PyCFunction DispatcherAddress>
00117 int ssizeobjargDispatcher( PyObject * iSelf, Py_ssize_t iSize, PyObject * iOther)
00118 {
00119     TPyObjPtr args(Py_BuildValue("(n,O)",iSize,iOther));
00120     PyObject* temp = DispatcherAddress(iSelf,args.get());
00121     if (!temp)
00122         return 1;
00123     return 0;
00124 }
00125 
00126 /** @internal
00127 */
00128 template <PyCFunction DispatcherAddress>
00129 int  ssizessizeobjargDispatcher( PyObject * iSelf, Py_ssize_t iSize, Py_ssize_t iSize2, PyObject * iOther)
00130 {
00131     TPyObjPtr args(Py_BuildValue("(n,n,O)",iSize,iSize2,iOther));
00132     PyObject* temp = DispatcherAddress(iSelf,args.get());
00133     if (!temp)
00134         return 1;
00135     return 0;
00136 }
00137 
00138 /** @internal
00139 */
00140 template <PyCFunction DispatcherAddress>
00141 int objobjDispatcher( PyObject * iSelf, PyObject * iOther)
00142 {
00143     TPyObjPtr args(Py_BuildValue("(O)",iOther));
00144     PyObject* temp = DispatcherAddress(iSelf,args.get());
00145     if (!temp)
00146         return 1;
00147     return 0;
00148 }
00149 
00150 /** @internal 
00151  *  Returns a  pair<short name, pyobject pointing at the class object>
00152  *  We have to work around the static initializer fiasco by demanding the iModuleName instead of pealing 
00153  *  it from the module object (which may not be initialized yet... and then we have *kaboom*)
00154  */
00155 template <typename CppClass>
00156 inline std::pair<std::string,PyObject*> prepareClassForModuleInjection(const char* iModuleName, const char* iClassDocumentation)
00157 {
00158     char* shortName = const_cast<char*>(CppClass::_lassPyType.tp_name); // finalizePyType will expand tp_name with module name.
00159     finalizePyType(CppClass::_lassPyType, *CppClass::_lassPyGetParentType(), CppClass::_lassPyMethods, CppClass::_lassPyGetSetters,
00160         CppClass::_lassPyStatics, iModuleName, iClassDocumentation);
00161     return std::pair<std::string,PyObject*>(std::string(shortName), reinterpret_cast<PyObject*>(&CppClass::_lassPyType));
00162 }
00163 
00164 /** @internal
00165  */
00166 template <typename CppClass>
00167 inline void injectClassInModule(PyObject* iModule, const char* iClassDocumentation)
00168 {
00169     std::pair< std::string, PyObject* > classForModule = prepareClassForModuleInjection<CppClass>(PyModule_GetName(iModule),iClassDocumentation);
00170     PyModule_AddObject(iModule, const_cast<char*>(classForModule.first.c_str()), classForModule.second);
00171 }
00172 
00173 
00174 
00175 /** @internal
00176  *//*
00177 template <typename CppClass>
00178 void addClassMethod(
00179         const char* iMethodName, const char* iDocumentation, PyCFunction iMethodDispatcher,
00180         unaryfunc iUnaryDispatcher, binaryfunc iBinaryDispatcher, ternaryfunc iTernaryDispatcher, 
00181         OverloadLink& oOverloadChain) 
00182 {
00183     if (strcmp(iMethodName, "__call__") == 0)
00184     {
00185         oOverloadChain.setTernaryfunc(CppClass::Type.tp_call);
00186         CppClass::Type.tp_call = iTernaryDispatcher;
00187     }
00188     else if (strcmp(iMethodName, "__neg__") == 0)
00189     {
00190         if (CppClass::Type.tp_as_number == 0)
00191         {
00192             CppClass::Type.tp_as_number = new PyNumberMethods;
00193         }
00194         CppClass::Type.tp_as_number->nb_negative = iUnaryDispatcher;
00195     }
00196     else
00197     {
00198         ::std::vector<PyMethodDef>::iterator i = ::std::find_if(
00199             CppClass::_lassPyMethods.begin(), CppClass::_lassPyMethods.end(), PyMethodEqual(iMethodName));
00200         if (i == CppClass::_lassPyMethods.end())
00201         {
00202             CppClass::_lassPyMethods.insert(CppClass::_lassPyMethods.begin(), createPyMethodDef(
00203                 iMethodName, iMethodDispatcher, METH_VARARGS , iDocumentation));
00204             oOverloadChain.setNull();
00205         }
00206         else
00207         {
00208             LASS_ASSERT(i->ml_flags == METH_VARARGS);
00209             oOverloadChain.setPyCFunction(i->ml_meth);
00210             i->ml_meth = iMethodDispatcher;
00211             if (i->ml_doc == 0)
00212             {
00213                 i->ml_doc = const_cast<char*>(iDocumentation);
00214             }
00215         };
00216     }
00217 }
00218 */
00219 
00220 
00221 /** @intenal
00222  */
00223 template <typename CppClass>
00224 void addClassStaticMethod(
00225         const char* iMethodName, const char* iDocumentation,
00226         PyCFunction iMethodDispatcher, PyCFunction& oOverloadChain)
00227 {
00228 #if PY_VERSION_HEX >= 0x02030000 // >= 2.3
00229     ::std::vector<PyMethodDef>::iterator i = ::std::find_if(
00230         CppClass::_lassPyMethods.begin(), CppClass::_lassPyMethods.end(), PyMethodEqual(iMethodName));
00231     if (i == CppClass::_lassPyMethods.end())
00232     {
00233         CppClass::_lassPyMethods.insert(CppClass::_lassPyMethods.begin(), createPyMethodDef(
00234             iMethodName, iMethodDispatcher, METH_VARARGS | METH_STATIC, iDocumentation));
00235         oOverloadChain = 0;
00236     }
00237     else
00238     {
00239         LASS_ASSERT(i->ml_flags == (METH_VARARGS | METH_CLASS));
00240         oOverloadChain = i->ml_meth;
00241         i->ml_meth = iMethodDispatcher;
00242         if (i->ml_doc == 0)
00243         {
00244             i->ml_doc = const_cast<char*>(iDocumentation);
00245         }
00246     }
00247 #else
00248     TStaticMembers::iterator i = ::std::find_if(
00249         CppClass::_lassPyStatics.begin(), CppClass::_lassPyStatics.end(), StaticMemberEqual(iMethodName));
00250     if (i == CppClass::_lassPyStatics.end())
00251     {
00252         PyMethodDef* methodDef(new PyMethodDef(createPyMethodDef(
00253             iMethodName, iMethodDispatcher, METH_VARARGS, iDocumentation)));
00254         PyObject* cFunction = PyCFunction_New(methodDef, 0);
00255         PyObject* descr = PyStaticMethod_New(cFunction);
00256         CppClass::_lassPyStatics.push_back(createStaticMember(
00257             iMethodName, iDocumentation, staticMemberHelperObject(descr)));
00258         oOverloadChain = 0;
00259     }
00260     else
00261     {
00262         PyObject* descr = i->object;
00263         LASS_ASSERT(descr && PyObject_IsInstance(
00264             descr, reinterpret_cast<PyObject*>(&PyStaticMethod_Type)));     
00265         PyObject* cFunction = PyStaticMethod_Type.tp_descr_get(descr, 0, 0);
00266         LASS_ASSERT(cFunction && PyObject_IsInstance(
00267             cFunction, reinterpret_cast<PyObject*>(&PyCFunction_Type)));
00268         PyMethodDef* methodDef = reinterpret_cast<PyCFunctionObject*>(cFunction)->m_ml;
00269         LASS_ASSERT(methodDef && methodDef->ml_flags == METH_VARARGS);
00270         oOverloadChain = methodDef->ml_meth;
00271         methodDef->ml_meth = iMethodDispatcher;
00272         if (methodDef->ml_doc == 0)
00273         {
00274             methodDef->ml_doc = const_cast<char*>(iDocumentation);
00275         }
00276         i->doc = methodDef->ml_doc;
00277     }   
00278 #endif
00279 }   
00280 
00281 
00282 /** @internal
00283  */
00284 template <typename CppClass, typename T>
00285 void addClassStaticConst(const char* iName, const T& iValue)
00286 {
00287     LASS_ASSERT(std::count_if(
00288         CppClass::_lassPyStatics.begin(), CppClass::_lassPyStatics.end(), StaticMemberEqual(iName)) == 0);
00289     CppClass::_lassPyStatics.push_back(createStaticMember(iName, 0, staticMemberHelperObject(iValue)));
00290 }
00291 
00292 
00293 
00294 /** @internal
00295  */
00296 template <typename InnerCppClass>
00297 inline void addClassInnerClass(
00298         TStaticMembers& oOuterStatics, const char* iInnerClassName, const char* iDocumentation)
00299 {
00300     LASS_ASSERT(std::count_if(InnerCppClass::_lassPyStatics.begin(), InnerCppClass::_lassPyStatics.end(), 
00301         StaticMemberEqual(iInnerClassName)) == 0);
00302     oOuterStatics.push_back(createStaticMember(
00303         iInnerClassName, iDocumentation, staticMemberHelperType(&InnerCppClass::_lassPyType),
00304         InnerCppClass::_lassPyGetParentType(), &InnerCppClass::_lassPyMethods, &InnerCppClass::_lassPyGetSetters, 
00305         &InnerCppClass::_lassPyStatics));
00306 }
00307 
00308 
00309 /** @internal
00310  *  helper for pyNumericCast
00311  */
00312 template <bool InIsSigned> 
00313 struct PyNumericCaster
00314 {
00315     template <typename In, typename Out> static int cast( In iIn, Out& oOut )
00316     {
00317         LASS_ASSERT(num::NumTraits<Out>::isSigned == true);
00318 #if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_INTEL
00319         volatile Out min = num::NumTraits<Out>::min;
00320         volatile Out max = num::NumTraits<Out>::max;
00321 #else
00322         const Out min = num::NumTraits<Out>::min;
00323         const Out max = num::NumTraits<Out>::max;
00324 #endif
00325         if (iIn < min)
00326         {
00327             std::ostringstream buffer;
00328             buffer << "not a " << num::NumTraits<Out>::name() << ": underflow: "
00329                 << iIn << " < " << min;
00330             PyErr_SetString(PyExc_TypeError, buffer.str().c_str());
00331             return 1;
00332         }
00333         if (iIn > max)
00334         {
00335             std::ostringstream buffer;
00336             buffer << "not a " << num::NumTraits<Out>::name() << ": overflow: "
00337                 << iIn << " > " << max;
00338             PyErr_SetString(PyExc_TypeError, buffer.str().c_str());
00339             return 1;
00340         }
00341         oOut = static_cast<Out>(iIn);
00342         return 0;
00343     }
00344 };
00345 
00346 /** @internal
00347  *  helper for pyNumericCast
00348  */
00349 template <> 
00350 struct PyNumericCaster<false> // In is unsigned
00351 {
00352     template <typename In, typename Out> static int cast( In iIn, Out& oOut )
00353     {
00354         LASS_ASSERT(num::NumTraits<Out>::isSigned == false);
00355 #if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_INTEL
00356         volatile Out max = num::NumTraits<Out>::max;
00357 #else
00358         const Out max = num::NumTraits<Out>::max;
00359 #endif
00360         if (iIn > max)
00361         {
00362             std::ostringstream buffer;
00363             buffer << "not a " << num::NumTraits<Out>::name() << ": overflow: "
00364                 << iIn << " > " << max;
00365             PyErr_SetString(PyExc_TypeError, buffer.str().c_str());
00366             return 1;
00367         }
00368         oOut = static_cast<Out>(iIn);
00369         return 0;
00370     }
00371 };
00372 
00373 
00374 
00375 /** @internal
00376  *  casts one numerical value to another with range checking.
00377  *  implementation detail.
00378  *  @note range of In should fully contain range of Out.
00379  *  @note In and Out should both be signed or unsigned.
00380  */
00381 template <typename In, typename Out>
00382 int pyNumericCast(In iIn, Out& oOut)
00383 {
00384     return PyNumericCaster< num::NumTraits<In>::isSigned >::cast( iIn, oOut );
00385 }
00386 
00387 
00388 
00389 /** @internal
00390  *  convert a PyObject to an signed integer with range checking.
00391  *  implementation detail.
00392  */
00393 template <typename Integer>
00394 int pyGetSignedObject( PyObject* iValue, Integer& oV )
00395 {
00396     if (PyInt_Check(iValue))
00397     {
00398         long temp = PyInt_AS_LONG(iValue);
00399         return pyNumericCast( temp, oV );
00400     }
00401     if (PyLong_Check(iValue))
00402     {
00403 #if HAVE_LONG_LONG
00404         PY_LONG_LONG temp = PyLong_AsLongLong(iValue);
00405 #else
00406         long temp = PyLong_AsLong(iValue);
00407 #endif
00408         if (PyErr_Occurred())
00409         {
00410             PyErr_Format(PyExc_TypeError, "not a %s: overflow",
00411                 num::NumTraits<Integer>::name().c_str());
00412             return 1;
00413         }
00414         return pyNumericCast( temp, oV );
00415     }
00416     PyErr_Format(PyExc_TypeError, "not a %s", num::NumTraits<Integer>::name().c_str());
00417     return 1;
00418 }
00419 
00420 /** @internal
00421  *  convert a PyObject to an unsigned integer with range checking.
00422  *  implementation detail.
00423  */
00424 template <typename Integer>
00425 int pyGetUnsignedObject( PyObject* iValue, Integer& oV )
00426 {
00427     if (PyInt_Check(iValue))
00428     {
00429         long temp = PyInt_AS_LONG(iValue);
00430         if (temp < 0)
00431         {
00432             std::ostringstream buffer;
00433             buffer << "not a " << num::NumTraits<Integer>::name() << ": negative: "
00434                 << temp << " < 0";
00435             PyErr_SetString(PyExc_TypeError, buffer.str().c_str());
00436             return 1;
00437         }
00438         return pyNumericCast( static_cast<unsigned long>(temp), oV );
00439     }
00440     if (PyLong_Check(iValue))
00441     {
00442 #if HAVE_LONG_LONG
00443         unsigned PY_LONG_LONG temp = PyLong_AsUnsignedLongLong(iValue);
00444 #else
00445         unsigned long temp = PyLong_AsUnsignedLong(iValue);
00446 #endif
00447         if (PyErr_Occurred())
00448         {
00449             PyErr_Format(PyExc_TypeError, "not a %s: overflow",
00450                 num::NumTraits<Integer>::name().c_str());
00451             return 1;
00452         }
00453         return pyNumericCast( temp, oV );
00454     }
00455     PyErr_Format(PyExc_TypeError, "not a %s", num::NumTraits<Integer>::name().c_str());
00456     return 1;
00457 }
00458 
00459 /** @internal
00460  *  convert a PyObject to a floating point value with range checking.
00461  *  implementation detail.
00462  */
00463 template <typename Float>
00464 int pyGetFloatObject( PyObject* iValue, Float& oV )
00465 {
00466     if (PyFloat_Check(iValue))
00467     {
00468         double temp = PyFloat_AS_DOUBLE(iValue);
00469         return pyNumericCast( temp, oV );
00470     }
00471     if (PyInt_Check(iValue))
00472     {
00473         long temp = PyInt_AS_LONG(iValue);
00474         oV = static_cast<Float>( temp );
00475         return 0;
00476     }
00477     if (PyLong_Check(iValue))
00478     {
00479         double temp = PyLong_AsDouble(iValue);
00480         if (PyErr_Occurred())
00481         {
00482             PyErr_Format(PyExc_TypeError, "not a %s: overflow",
00483                 num::NumTraits<Float>::name().c_str());
00484             return 1;
00485         }
00486         return pyNumericCast( temp, oV );
00487     }
00488     PyErr_Format(PyExc_TypeError, "not a %s", num::NumTraits<Float>::name().c_str());
00489     return 1;
00490 }
00491 
00492 
00493 }
00494 
00495 /** @ingroup Python
00496  *  @internal
00497  */
00498 template <>
00499 struct PyExportTraits<bool>
00500 {
00501     static PyObject* build(bool iV)
00502     {
00503         return PyInt_FromLong(static_cast<long>(iV));
00504     }
00505     static int get( PyObject* iValue, bool& oV )
00506     {
00507         int result = PyObject_IsTrue(iValue);
00508         if (result == -1)
00509         {
00510             PyErr_SetString(PyExc_TypeError, "does not evaluate to a boolean");
00511             return 1;
00512         }
00513         oV = (result != 0);
00514         return 0;
00515     }
00516 };
00517 
00518 /** @ingroup Python
00519  *  @internal
00520  */
00521 template <>
00522 struct PyExportTraits<signed char>
00523 {
00524     static PyObject* build( signed char iV )
00525     {
00526         return PyInt_FromLong(static_cast<long>(iV));
00527     }
00528     static int get( PyObject* iValue, signed char& oV )
00529     {
00530         return impl::pyGetSignedObject( iValue, oV );
00531     }
00532 };
00533 
00534 /** @ingroup Python
00535  *  @internal
00536  */
00537 template <>
00538 struct PyExportTraits<unsigned char>
00539 {
00540     static PyObject* build( unsigned char iV )
00541     {
00542         return PyInt_FromLong(static_cast<long>(iV));
00543     }
00544     static int get( PyObject* iValue, unsigned char& oV )
00545     {
00546         return impl::pyGetUnsignedObject( iValue, oV );
00547     }
00548 };
00549 
00550 /** @ingroup Python
00551  *  @internal
00552  */
00553 template <>
00554 struct PyExportTraits<signed short>
00555 {
00556     static PyObject* build( signed short iV )
00557     {
00558         return PyInt_FromLong(static_cast<long>(iV));
00559     }
00560     static int get( PyObject* iValue, signed short& oV )
00561     {
00562         return impl::pyGetSignedObject( iValue, oV );
00563     }
00564 };
00565 
00566 /** @ingroup Python
00567  *  @internal
00568  */
00569 template <>
00570 struct PyExportTraits<unsigned short>
00571 {
00572     inline PyObject* build( unsigned short iV )
00573     {
00574         return PyInt_FromLong(static_cast<long>(iV));
00575     }
00576     static int get( PyObject* iValue, unsigned short& oV )
00577     {
00578         return impl::pyGetUnsignedObject( iValue, oV );
00579     }
00580 };
00581 
00582 /** @ingroup Python
00583  *  @internal
00584  */
00585 template <>
00586 struct PyExportTraits<signed int>
00587 {
00588     static PyObject* build( signed int iV )
00589     {
00590         return PyInt_FromLong(static_cast<long>(iV));
00591     }
00592     static int get( PyObject* iValue, signed int& oV )
00593     {
00594         return impl::pyGetSignedObject( iValue, oV );
00595     }
00596 };
00597 
00598 /** @ingroup Python
00599  *  @internal
00600  */
00601 template <>
00602 struct PyExportTraits<unsigned int>
00603 {
00604     static PyObject* build( unsigned int iV )
00605     {
00606         return PyLong_FromUnsignedLong(static_cast<unsigned long>(iV));
00607     }
00608     static int get( PyObject* iValue, unsigned int& oV )
00609     {
00610         return impl::pyGetUnsignedObject( iValue, oV );
00611     }
00612 };
00613 
00614 /** @ingroup Python
00615  *  @internal
00616  */
00617 template <>
00618 struct PyExportTraits<signed long>
00619 {
00620     static PyObject* build( signed long iV )
00621     {
00622         return PyInt_FromLong(iV);
00623     }
00624     static int get( PyObject* iValue, signed long& oV )
00625     {
00626         return impl::pyGetSignedObject( iValue, oV );
00627     }
00628 };
00629 
00630 /** @ingroup Python
00631  *  @internal
00632  */
00633 template <>
00634 struct PyExportTraits<unsigned long>
00635 {
00636     static PyObject* build(unsigned long iV)
00637     {
00638         return PyLong_FromUnsignedLong(iV);
00639     }
00640     static int get( PyObject* iValue, unsigned long& oV )
00641     {
00642         return impl::pyGetUnsignedObject( iValue, oV );
00643     }
00644 };
00645 
00646 #ifdef HAVE_LONG_LONG
00647 
00648 /** @ingroup Python
00649  *  @internal
00650  */
00651 template <>
00652 struct PyExportTraits<signed PY_LONG_LONG>
00653 {
00654     static PyObject* build( signed PY_LONG_LONG iV )
00655     {
00656         return PyLong_FromLongLong(iV);
00657     }
00658     static int get( PyObject* iValue, signed PY_LONG_LONG& oV )
00659     {
00660         return impl::pyGetSignedObject( iValue, oV );
00661     }
00662 };
00663 
00664 /** @ingroup Python
00665  *  @internal
00666  */
00667 template <>
00668 struct PyExportTraits<unsigned PY_LONG_LONG>
00669 {
00670     static PyObject* build( unsigned PY_LONG_LONG iV )
00671     {
00672         return PyLong_FromUnsignedLongLong(iV);
00673     }
00674     static int get( PyObject* iValue, unsigned PY_LONG_LONG& oV )
00675     {
00676         return impl::pyGetUnsignedObject( iValue, oV );
00677     }
00678 };
00679 
00680 #endif
00681 
00682 /** @ingroup Python
00683  *  @internal
00684  */
00685 template <>
00686 struct PyExportTraits<float>
00687 {
00688     static PyObject* build( float iV )
00689     {
00690         return PyFloat_FromDouble(static_cast<double>(iV));
00691     }
00692     static int get( PyObject* iValue, float& oV )
00693     {
00694         return impl::pyGetFloatObject( iValue, oV );
00695     }
00696 };
00697 
00698 /** @ingroup Python
00699  *  @internal
00700  */
00701 template <>
00702 struct PyExportTraits<double>
00703 {
00704     static PyObject* build( double iV )
00705     {
00706         return PyFloat_FromDouble(iV);
00707     }
00708     static int get( PyObject* iValue, double& oV )
00709     {
00710         return impl::pyGetFloatObject( iValue, oV );
00711     }
00712 };
00713 
00714 /** @ingroup Python
00715  *  @internal
00716  */
00717 template <>
00718 struct PyExportTraits<long double>
00719 {
00720     static PyObject* build( long double iV )
00721     {
00722         return PyFloat_FromDouble(static_cast<double>(iV));
00723     }
00724     static int get( PyObject* iValue, long double& oV )
00725     {
00726         return impl::pyGetFloatObject( iValue, oV );
00727     }
00728 };
00729 
00730 /** @ingroup Python
00731  *  @internal
00732  */
00733 template <>
00734 struct PyExportTraits<const char*>
00735 {
00736     static PyObject* build( const char* iV )
00737     {
00738         return PyString_FromString(iV);
00739     }
00740 };
00741 
00742 /** @ingroup Python
00743  *  @internal
00744  */
00745 template <size_t N>
00746 struct PyExportTraits<const char [N]>
00747 {
00748     static PyObject* build( const char iV[N] )
00749     {
00750         return PyString_FromString(iV);
00751     }
00752 };
00753 
00754 /** @ingroup Python
00755  *  @internal
00756  */
00757 template <typename T>
00758 struct PyExportTraits< util::SharedPtr<T, PyObjectStorage, PyObjectCounter> >
00759 {
00760     static PyObject* build( const util::SharedPtr<T, PyObjectStorage, PyObjectCounter>& iV )
00761     {
00762         if (!iV)
00763         {
00764             Py_RETURN_NONE;
00765         }
00766         return fromSharedPtrToNakedCast(iV);
00767     }
00768     static int get(PyObject* iValue, util::SharedPtr<T, PyObjectStorage, PyObjectCounter>& oV)
00769     {
00770         const bool isNone = (iValue == Py_None );
00771         if (isNone)
00772         {
00773             oV = util::SharedPtr<T, PyObjectStorage, PyObjectCounter>();
00774         }
00775         else
00776         {
00777             if (!PyType_IsSubtype(iValue->ob_type , &T::_lassPyType ))
00778             {
00779                 PyErr_Format(PyExc_TypeError,"not castable to %s",T::_lassPyType.tp_name);
00780                 return 1;
00781             }
00782             oV = fromNakedToSharedPtrCast<T>(iValue);
00783         }
00784         return 0;
00785     }
00786 };
00787 
00788 /** @ingroup Python
00789  *  @internal
00790  */
00791 template <>
00792 struct PyExportTraits< util::SharedPtr<PyObject, PyObjectStorage, PyObjectCounter> >
00793 {
00794     static PyObject* build( const util::SharedPtr<PyObject, PyObjectStorage, PyObjectCounter>& iV )
00795     {
00796         if (!iV)
00797         {
00798             Py_RETURN_NONE;
00799         }
00800         return fromSharedPtrToNakedCast(iV);
00801     }
00802     static int get(PyObject* iValue, util::SharedPtr<PyObject, PyObjectStorage, PyObjectCounter>& oV)
00803     {
00804         const bool isNone = (iValue == Py_None );
00805         if (isNone)
00806         {
00807             oV = util::SharedPtr<PyObject, PyObjectStorage, PyObjectCounter>();
00808         }
00809         else
00810         {
00811             oV = fromNakedToSharedPtrCast<PyObject>(iValue);
00812         }
00813         return 0;
00814     }
00815 };
00816 
00817 
00818 
00819 }
00820 }
00821 
00822 // EOF

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