00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_PYOBJECT_PLUS_H
00048 #define LASS_GUARDIAN_OF_INCLUSION_UTIL_PYOBJECT_PLUS_H
00049
00050 #include "util_common.h"
00051 #include "singleton.h"
00052
00053
00054
00055
00056
00057 #if defined(_POSIX_C_SOURCE)
00058 # undef _POSIX_C_SOURCE
00059 #endif
00060
00061 #if defined(_DEBUG) && LASS_PYTHON_HAS_DEBUG_BUILD == 0
00062 # undef _DEBUG
00063 # include "Python.h"
00064 # define _DEBUG
00065 #else
00066 # include "Python.h"
00067 #endif
00068
00069 #ifndef PySequence_ITEM
00070 # define PySequence_ITEM(o, i) PySequence_GetItem(o, i)
00071 #endif
00072
00073 #ifndef PySequence_Fast_ITEMS
00074 # define PySequence_Fast_ITEMS(o) \
00075 (PyTuple_Check(o) ? ((PyTupleObject *)(o))->ob_item : ((PyListObject *)(o))->ob_item)
00076 #endif
00077
00078 #ifndef Py_RETURN_FALSE
00079 # define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
00080 #endif
00081
00082 #ifndef Py_RETURN_TRUE
00083 # define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
00084 #endif
00085
00086 #ifndef Py_RETURN_NONE
00087 # define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
00088 #endif
00089
00090 #if (PY_VERSION_HEX < 0x02050000)
00091 # define Py_ssize_t int
00092 # define lenfunc inquiry
00093 # define ssizeargfunc intargfunc
00094 # define ssizessizeargfunc intintargfunc
00095 # define ssizeobjargproc intobjargproc
00096 # define ssizessizeobjargproc intintobjargproc
00097 #endif
00098
00099 #include "../meta/is_derived.h"
00100 #include "../meta/select.h"
00101 #include "shared_ptr.h"
00102 #include "string_cast.h"
00103 #include "thread.h"
00104 #include <cstdlib>
00105
00106 #if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
00107 # pragma warning(push)
00108 # pragma warning(disable: 4267) // conversion from 'size_t' to 'unsigned int', possible loss of data
00109 #endif
00110
00111
00112
00113
00114
00115 #define PY_HEADER_INTERNAL \
00116 public: \
00117 static PyTypeObject _lassPyType; \
00118 static ::std::vector<PyMethodDef> _lassPyMethods; \
00119 static ::std::vector<PyGetSetDef> _lassPyGetSetters; \
00120 virtual PyTypeObject *_lassPyGetType(void) const {return &_lassPyType;};\
00121 private:
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 #define PY_HEADER( t_parentClass ) \
00132 public: \
00133 typedef t_parentClass _lassPyParentType;\
00134 static PyTypeObject _lassPyType; \
00135 static ::std::vector<PyMethodDef> _lassPyMethods; \
00136 static ::std::vector<PyGetSetDef> _lassPyGetSetters; \
00137 static ::lass::python::impl::TStaticMembers _lassPyStatics; \
00138 static ::lass::python::impl::TCompareFuncs _lassPyCompareFuncs;\
00139 virtual PyTypeObject* _lassPyGetType(void) const {return &_lassPyType;};\
00140 static PyTypeObject* _lassPyGetParentType(void)\
00141 {\
00142 return &_lassPyParentType::_lassPyType != &::lass::python::PyObjectPlus::_lassPyType ?\
00143 &_lassPyParentType::_lassPyType : &PyBaseObject_Type;\
00144 }\
00145 private:
00146
00147 namespace lass
00148 {
00149 namespace python
00150 {
00151
00152 struct Caster
00153 {
00154 };
00155
00156 template<typename T>
00157 struct IsACaster
00158 {
00159 typedef lass::meta::False TValue;
00160 };
00161 template <typename T>
00162 struct NoCast : public Caster
00163 {
00164 typedef T TSelf;
00165 typedef T TTarget;
00166 static TTarget cast(TSelf iArg) { return iArg; }
00167 };
00168 template <>
00169 struct NoCast<void> : public Caster
00170 {
00171 typedef void TSelf;
00172 typedef void TTarget;
00173 static TTarget cast(void) {}
00174 };
00175
00176
00177 template <typename T>
00178 struct PointerCast : public Caster
00179 {
00180 typedef T TSelf;
00181 typedef T* TPointer;
00182 typedef TPointer TTarget;
00183 static TSelf cast(TTarget iArg) { return *iArg; }
00184 };
00185
00186 template<typename T>
00187 struct PointerCast<T&> : public Caster
00188 {
00189 typedef T& TSelf;
00190 typedef T* TPointer;
00191 typedef TPointer TTarget;
00192 static TSelf cast(TTarget iArg) { return *iArg; }
00193 };
00194 template<typename T>
00195 struct PointerCast<const T&> : public Caster
00196 {
00197 typedef T& TSelf;
00198 typedef T* TPointer;
00199 typedef TPointer TTarget;
00200 static TSelf cast(TTarget iArg) { return *iArg; }
00201 };
00202 template<typename T>
00203 struct PointerCast<T*> : public Caster
00204 {
00205 typedef T* TSelf;
00206 typedef T* TPointer;
00207 typedef TPointer TTarget;
00208 static TSelf cast(TTarget iArg) { return iArg; }
00209 };
00210 template<typename T>
00211 struct PointerCast<const T*> : public Caster
00212 {
00213 typedef const T* TSelf;
00214 typedef const T* TPointer;
00215 typedef TPointer TTarget;
00216 static TSelf cast(TTarget iArg) { return iArg; }
00217 };
00218
00219
00220
00221 template <typename T>
00222 struct CopyCast : public Caster
00223 {
00224 typedef T TSelf;
00225 typedef T TCopy;
00226 typedef TCopy TTarget;
00227 static TSelf cast(TTarget iArg) { return TSelf(iArg); }
00228 };
00229
00230 template<typename T>
00231 struct CopyCast<T&> : public Caster
00232 {
00233 typedef T& TSelf;
00234 typedef T TCopy;
00235 typedef TCopy TTarget;
00236 static TSelf cast(TTarget iArg) { return TSelf(iArg); }
00237 };
00238 template<typename T>
00239 struct CopyCast<const T&> : public Caster
00240 {
00241 typedef T& TSelf;
00242 typedef T TCopy;
00243 typedef TCopy TTarget;
00244 static TSelf cast(TTarget iArg) { return TSelf(iArg); }
00245 };
00246 template<typename T>
00247 struct CopyCast<T*> : public Caster
00248 {
00249 typedef T* TSelf;
00250 typedef T TCopy;
00251 typedef TCopy TTarget;
00252 };
00253 template<typename T>
00254 struct CopyCast<const T*> : public Caster
00255 {
00256 typedef const T* TSelf;
00257 typedef const T TCopy;
00258 typedef TCopy TTarget;
00259 };
00260
00261 template<typename T>
00262 struct IsACaster<PointerCast<T> >
00263 {
00264 typedef lass::meta::True TValue;
00265 };
00266 template<typename T>
00267 struct IsACaster<CopyCast<T> >
00268 {
00269 typedef lass::meta::True TValue;
00270 };
00271
00272 template< typename T>
00273 struct OwnerCaster
00274 {
00275 typedef typename lass::meta::Select< typename IsACaster<T>::TValue , T, NoCast<T> >::Type TCaster;
00276 };
00277
00278 }
00279 }
00280
00281
00282 namespace lass
00283 {
00284 namespace python
00285 {
00286
00287
00288
00289 template<typename T>
00290 struct PyExportTraits
00291 {
00292
00293
00294 };
00295
00296 #define PYEXPORTTRAITS_USINGDEPRECATED( t_basicType ) \
00297 template<>\
00298 struct PyExportTraits< t_basicType >\
00299 {\
00300 static PyObject* build(const t_basicType & iv) { return pyBuildSimpleObject_deprecated(iv); }\
00301 static int get(PyObject* iv, t_basicType & ov) { return pyGetSimpleObject_deprecated(iv,ov); }\
00302 };\
00303
00304 #define PYEXPORTTRAITS_USINGDEPRECATED_TEMPL( t_basicType ) \
00305 template< typename T >\
00306 struct PyExportTraits< t_basicType< T > >\
00307 {\
00308 static PyObject* build(const t_basicType< T > & iv) { return pyBuildSimpleObject_deprecated(iv); }\
00309 static int get(PyObject* iv, t_basicType< T > & ov) { return pyGetSimpleObject_deprecated(iv,ov); }\
00310 };
00311 #define PYEXPORTTRAITS_USINGDEPRECATED_TEMPL_2( t_basicType ) \
00312 template< typename T, typename U >\
00313 struct PyExportTraits< t_basicType< T, U > >\
00314 {\
00315 static PyObject* build(const t_basicType< T, U > & iv) { return pyBuildSimpleObject_deprecated(iv); }\
00316 static int get(PyObject* iv, t_basicType< T, U> & ov) { return pyGetSimpleObject_deprecated(iv,ov); }\
00317 };
00318 #define PYEXPORTTRAITS_USINGDEPRECATED_TEMPL_3( t_basicType ) \
00319 template< typename T, typename U, typename V >\
00320 struct PyExportTraits< t_basicType< T, U, V > >\
00321 {\
00322 static PyObject* build(const t_basicType< T, U, V > & iv) { return pyBuildSimpleObject_deprecated(iv); }\
00323 static int get(PyObject* iv, t_basicType< T, U, V > & ov) { return pyGetSimpleObject_deprecated(iv,ov); }\
00324 };
00325 #define PYEXPORTTRAITS_USINGDEPRECATED_TEMPL_4( t_basicType ) \
00326 template< typename T, typename U, typename V, typename W >\
00327 struct PyExportTraits< t_basicType< T, U, V, W > >\
00328 {\
00329 static PyObject* build(const t_basicType< T, U, V, W > & iv) { return pyBuildSimpleObject_deprecated(iv); }\
00330 static int get(PyObject* iv, t_basicType< T, U, V, W > & ov) { return pyGetSimpleObject_deprecated(iv,ov); }\
00331 };
00332
00333
00334
00335 template<typename T>
00336 PyObject* pyBuildSimpleObject(T& iV)
00337 {
00338 return PyExportTraits<T>::build(iV);
00339 }
00340
00341
00342
00343 template<typename T>
00344 PyObject* pyBuildSimpleObject(const T& iV)
00345 {
00346 return PyExportTraits<T>::build(iV);
00347 }
00348
00349
00350
00351 template<typename T>
00352 PyObject* pyBuildSimpleObject(std::auto_ptr<T> iV)
00353 {
00354 return PyExportTraits< std::auto_ptr<T> >::build(iV);
00355 }
00356
00357
00358
00359 template<typename T>
00360 int pyGetSimpleObject(PyObject* iV, T& oV)
00361 {
00362 return PyExportTraits<T>::get(iV,oV);
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 template <typename EnumType, typename IntegerType = long>
00383 struct PyExportTraitsEnum
00384 {
00385 static PyObject* build(const EnumType iv)
00386 {
00387 return pyBuildSimpleObject(static_cast<IntegerType>(iv));
00388 }
00389 static int get(PyObject* iv, EnumType& ov)
00390 {
00391 IntegerType temp;
00392 if (pyGetSimpleObject(iv, temp) != 0)
00393 {
00394 return 1;
00395 }
00396 ov = static_cast<EnumType>(temp);
00397 return 0;
00398 }
00399 };
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 class LASS_DLL PyObjectPlus :
00410 public PyObject
00411 {
00412 PY_HEADER_INTERNAL;
00413 public:
00414 typedef void TCppClass;
00415 PyObjectPlus();
00416 virtual ~PyObjectPlus();
00417 virtual std::string doPyRepr(void) { return std::string(ob_type->tp_name) + " object at " + util::stringCast<std::string>(this); }
00418 virtual std::string doPyStr(void) { return std::string(ob_type->tp_name) + " object string at " + util::stringCast<std::string>(this); }
00419
00420 protected:
00421 PyObjectPlus(const PyObjectPlus& other);
00422 PyObjectPlus& operator=(const PyObjectPlus& other);
00423 #ifdef LASS_PYTHON_INHERITANCE_FROM_EMBEDDING
00424 public:
00425 PyObject* dict_;
00426 #endif
00427 private:
00428 };
00429
00430 namespace impl
00431 {
00432
00433
00434
00435 inline util::CriticalSection& referenceMutex()
00436 {
00437 using namespace util;
00438 return *Singleton<CriticalSection, destructionPriorityInternalPythonMutex>::instance();
00439 }
00440
00441
00442
00443
00444
00445
00446
00447 template <typename T> T* fixObjectType(T* iObject)
00448 {
00449 if (meta::IsDerived<T, PyObjectPlus>::value &&
00450 iObject && !iObject->ob_type)
00451 {
00452 iObject->ob_type = static_cast<PyObjectPlus*>(iObject)->_lassPyGetType();
00453 }
00454 return iObject;
00455 }
00456
00457 }
00458
00459
00460
00461
00462
00463
00464
00465 template <typename T, typename Cascade = meta::EmptyType>
00466 class PyObjectStorage: public Cascade
00467 {
00468 public:
00469
00470 typedef PyObjectStorage<T, Cascade> TSelf;
00471 typedef T* TStorage;
00472 typedef T* TPointer;
00473 typedef T& TReference;
00474
00475 TStorage& storage() { return storage_; }
00476 const TStorage& storage() const { return storage_; }
00477
00478 protected:
00479
00480 PyObjectStorage(): Cascade(), storage_(defaultStorage()) {}
00481 explicit PyObjectStorage(T* pointee): Cascade(), storage_(impl::fixObjectType(pointee)) {}
00482 PyObjectStorage(const PyObjectStorage& other): Cascade(other), storage_(other.storage_) {}
00483 template <typename U> PyObjectStorage(const PyObjectStorage<U, Cascade>& other):
00484 Cascade(other), storage_(other.storage()) {}
00485 TPointer pointer() const { return storage_; }
00486 void dispose() { storage_ = 0; }
00487 bool isNull() const { return !storage_; }
00488 void swap(TSelf& other) { Cascade::swap(other); std::swap(storage_, other.storage_); }
00489 static TStorage defaultStorage() { return 0; }
00490 private:
00491 TStorage storage_;
00492 };
00493
00494
00495
00496
00497
00498
00499
00500
00501 class LASS_DLL PyObjectCounter
00502 {
00503 public:
00504 typedef int TCount;
00505 protected:
00506 PyObjectCounter() {}
00507 template <typename TStorage> void init(TStorage& ) {}
00508 template <typename TStorage> void dispose(TStorage& ) {}
00509 template <typename TStorage> void increment(TStorage& pointee)
00510 {
00511 LASS_LOCK(impl::referenceMutex())
00512 {
00513 Py_INCREF(pointee);
00514 }
00515 }
00516 template <typename TStorage> bool decrement(TStorage& pointee)
00517 {
00518 bool r = false;
00519 LASS_LOCK(impl::referenceMutex())
00520 {
00521 LASS_ASSERT(pointee);
00522 r = pointee->ob_refcnt <=1;
00523 Py_DECREF(pointee);
00524 }
00525 return r;
00526 }
00527 template <typename TStorage> TCount count(TStorage& pointee) const
00528 {
00529 LASS_ASSERT(pointee);
00530 return pointee->ob_refcnt;
00531 }
00532 void swap(PyObjectCounter& ) {}
00533 };
00534
00535
00536
00537
00538 template<class T>
00539 struct PyObjectPtr
00540 {
00541 typedef util::SharedPtr<T, PyObjectStorage, PyObjectCounter> Type;
00542 };
00543
00544
00545
00546
00547 typedef PyObjectPtr<PyObject>::Type TPyObjPtr;
00548
00549 namespace impl
00550 {
00551 LASS_DLL const std::string exceptionExtractMessage(
00552 const TPyObjPtr& type, const TPyObjPtr& value);
00553 }
00554
00555 class PythonException: public util::Exception
00556 {
00557 public:
00558 PythonException(
00559 const TPyObjPtr& type, const TPyObjPtr& value, const TPyObjPtr& traceback,
00560 const std::string& loc):
00561 util::Exception(impl::exceptionExtractMessage(type, value), loc),
00562 type_(type),
00563 value_(value),
00564 traceback_(traceback)
00565 {
00566 }
00567 ~PythonException() throw() {}
00568 const python::TPyObjPtr& type() const { return type_; }
00569 const python::TPyObjPtr& value() const { return value_; }
00570 const python::TPyObjPtr& traceback() const { return traceback_; }
00571 private:
00572 LASS_UTIL_EXCEPTION_PRIVATE_IMPL(PythonException)
00573 python::TPyObjPtr type_;
00574 python::TPyObjPtr value_;
00575 python::TPyObjPtr traceback_;
00576 };
00577
00578
00579
00580
00581
00582
00583 template<class T>
00584 lass::util::SharedPtr<T, PyObjectStorage, PyObjectCounter>
00585 fromNakedToSharedPtrCast(PyObject* object)
00586 {
00587 LASS_LOCK(impl::referenceMutex())
00588 {
00589 Py_XINCREF(object);
00590 }
00591 return util::SharedPtr<T,PyObjectStorage,PyObjectCounter>(static_cast<T*>(object));
00592 }
00593
00594
00595
00596
00597
00598
00599
00600 template<class T>
00601 PyObject*
00602 fromSharedPtrToNakedCast(const util::SharedPtr<T,PyObjectStorage,PyObjectCounter>& object)
00603 {
00604 PyObject* const obj = object.get();
00605 LASS_LOCK(impl::referenceMutex())
00606 {
00607 Py_XINCREF(obj);
00608 }
00609 return obj;
00610 }
00611
00612
00613
00614
00615 template <typename Out, typename In> inline
00616 Out staticPyCast(const In& in)
00617 {
00618 typedef typename Out::TPointer TPtr;
00619 TPtr ptr = static_cast<TPtr>(in.get());
00620 Py_XINCREF(ptr);
00621 return Out(ptr);
00622 }
00623
00624
00625
00626
00627 template <typename Out, typename In> inline
00628 Out dynamicPyCast(const In& in)
00629 {
00630 typedef typename Out::TPointer TPtr;
00631 TPtr ptr = dynamic_cast<TPtr>(in.get());
00632 Py_XINCREF(ptr);
00633 return Out(ptr);
00634 }
00635
00636
00637
00638
00639 template <typename T> struct IsPyObject: meta::IsDerived<T, PyObject> {};
00640
00641 LASS_DLL TPyObjPtr LASS_CALL getPyObjectByName(const std::string& iName);
00642
00643 namespace impl
00644 {
00645 LASS_DLL void LASS_CALL dealloc(PyObject* obj);
00646 LASS_DLL PyObject* LASS_CALL repr(PyObject* obj);
00647 LASS_DLL PyObject* LASS_CALL str(PyObject* obj);
00648
00649
00650
00651
00652 class LASS_DLL OverloadLink
00653 {
00654 public:
00655 OverloadLink();
00656 void setNull();
00657 void setPyCFunction(PyCFunction iOverload);
00658 void setUnaryfunc(unaryfunc iOverload);
00659 void setBinaryfunc(binaryfunc iOverload);
00660 void setTernaryfunc(ternaryfunc iOverload);
00661
00662 void setSsizeArgfunc(ssizeargfunc iOverload);
00663 void setSsizeSsizeArgfunc(ssizessizeargfunc iOverload);
00664 void setLenfunc(lenfunc iOverload);
00665 void setSsizeObjArgProcfunc(ssizeobjargproc iOverload);
00666 void setSsizeSsizeObjArgProcfunc(ssizessizeobjargproc iOverload);
00667 void setObjObjProcfunc(objobjproc iOverload);
00668
00669 bool operator()(PyObject* iSelf, PyObject* iArgs,
00670 PyObject*& result) const;
00671 private:
00672 PyCFunction pyCFunction_;
00673 unaryfunc unaryfunc_;
00674 binaryfunc binaryfunc_;
00675 ternaryfunc ternaryfunc_;
00676
00677 ssizeargfunc ssizeargfunc_;
00678 ssizessizeargfunc ssizessizeargfunc_;
00679 lenfunc lenfunc_;
00680 ssizeobjargproc ssizeobjargproc_;
00681 ssizessizeobjargproc ssizessizeobjargproc_;
00682 objobjproc objobjproc_;
00683 };
00684
00685 template <PyCFunction DispatcherAddress> PyObject* unaryDispatcher(
00686 PyObject* iSelf);
00687 template <PyCFunction DispatcherAddress> PyObject* binaryDispatcher(
00688 PyObject* iSelf, PyObject* other);
00689 template <PyCFunction DispatcherAddress> PyObject* ternaryDispatcher(
00690 PyObject* iSelf, PyObject* iArgs, PyObject* iKw);
00691
00692 template <PyCFunction DispatcherAddress> PyObject* ssizeargDispatcher(
00693 PyObject *, Py_ssize_t);
00694 template <PyCFunction DispatcherAddress> PyObject* ssizessizeargDispatcher(
00695 PyObject *, Py_ssize_t, Py_ssize_t);
00696 template <PyCFunction DispatcherAddress> Py_ssize_t lenDispatcher(
00697 PyObject *);
00698 template <PyCFunction DispatcherAddress> int ssizeobjargDispatcher(
00699 PyObject *, Py_ssize_t, PyObject *);
00700 template <PyCFunction DispatcherAddress> int ssizessizeobjargDispatcher(
00701 PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
00702 template <PyCFunction DispatcherAddress> int objobjDispatcher(
00703 PyObject *, PyObject *);
00704
00705
00706
00707
00708
00709 template <PyCFunction DispatcherAddress>
00710 struct DispatcherConvertor
00711 {
00712 static PyObject* asTernary(
00713 PyObject* iSelf, PyObject* iArgs, PyObject* iKw)
00714 {
00715 if (iKw)
00716 {
00717 PyErr_SetString(PyExc_TypeError,
00718 "keyword arguments are not supported");
00719 return 0;
00720 }
00721 return DispatcherAddress(iSelf, iArgs);
00722 }
00723 };
00724
00725
00726
00727
00728 struct LASS_DLL CompareFunc
00729 {
00730 PyCFunction dispatcher;
00731 int op;
00732 CompareFunc(PyCFunction dispatcher, int op): dispatcher(dispatcher), op(op) {}
00733 };
00734
00735
00736
00737
00738 typedef std::vector<CompareFunc> TCompareFuncs;
00739
00740
00741
00742
00743 template <typename CppClass>
00744 struct RichCompare
00745 {
00746 static PyObject* call(PyObject* self, PyObject* other, int op)
00747 {
00748 if (other==Py_None)
00749 {
00750
00751
00752 switch (op)
00753 {
00754 case Py_EQ:
00755 {
00756 if (self==other)
00757 Py_RETURN_TRUE;
00758 else
00759 Py_RETURN_FALSE;
00760 }
00761 case Py_NE:
00762 {
00763 if (self!=other)
00764 Py_RETURN_TRUE;
00765 else
00766 Py_RETURN_FALSE;
00767 }
00768
00769 default:
00770 Py_RETURN_FALSE;
00771 };
00772 }
00773
00774 TPyObjPtr args(Py_BuildValue("(O)", other));
00775 const TCompareFuncs::const_iterator end = CppClass::_lassPyCompareFuncs.end();
00776 for (TCompareFuncs::const_iterator i = CppClass::_lassPyCompareFuncs.begin(); i != end; ++i)
00777 {
00778 if (i->op == op)
00779 {
00780 PyObject* result = (i->dispatcher)(self, args.get());\
00781 if (result || PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
00782 {
00783 return result;
00784 }
00785 }
00786 }
00787
00788 return RichCompare<typename CppClass::_lassPyParentType>::call(self, other, op);
00789 }
00790 };
00791
00792
00793
00794
00795 template <>
00796 struct RichCompare<PyObjectPlus>
00797 {
00798 static PyObject* call(PyObject* , PyObject* , int op)
00799 {
00800 static char* symbols[] = { "<", "<=", "==", "!=", ">", ">=" };
00801 LASS_ASSERT(op >= 0 && op <= Py_GE);
00802 std::ostringstream buffer;
00803 buffer << "Comparison operator " << symbols[op] << " not implemented for this type";
00804 PyErr_SetString(PyExc_NotImplementedError, buffer.str().c_str());
00805 return 0;
00806 }
00807 };
00808
00809 class StaticMemberHelper
00810 {
00811 public:
00812 virtual ~StaticMemberHelper() {}
00813 virtual PyObject* build() const = 0;
00814 };
00815 typedef util::SharedPtr<StaticMemberHelper> TStaticMemberHelperPtr;
00816 template <typename T>
00817 class StaticMemberHelperObject: public StaticMemberHelper
00818 {
00819 public:
00820 StaticMemberHelperObject(const T& obj): obj_(obj) {}
00821 PyObject* build() const { return pyBuildSimpleObject(obj_); }
00822 private:
00823 T obj_;
00824 };
00825 template <>
00826 class StaticMemberHelperObject<PyObject*>: public StaticMemberHelper
00827 {
00828 public:
00829 StaticMemberHelperObject(PyObject* obj): obj_(obj) {}
00830 PyObject* build() const { return obj_; }
00831 private:
00832 PyObject* obj_;
00833 };
00834 template <typename T>
00835 inline TStaticMemberHelperPtr staticMemberHelperObject(const T& obj)
00836 {
00837 return TStaticMemberHelperPtr(new StaticMemberHelperObject<T>(obj));
00838 }
00839 class StaticMemberHelperType: public StaticMemberHelper
00840 {
00841 public:
00842 StaticMemberHelperType(PyTypeObject* type): type_(type) {}
00843 PyObject* build() const { return reinterpret_cast<PyObject*>(type_); }
00844 private:
00845 PyTypeObject* type_;
00846 };
00847 inline TStaticMemberHelperPtr staticMemberHelperType(PyTypeObject* type)
00848 {
00849 return TStaticMemberHelperPtr(new StaticMemberHelperType(type));
00850 }
00851
00852
00853
00854
00855 struct StaticMember
00856 {
00857 TStaticMemberHelperPtr member;
00858 PyTypeObject* parentType;
00859 std::vector<PyMethodDef>* methods;
00860 std::vector<PyGetSetDef>* getSetters;
00861 const std::vector<StaticMember>* statics;
00862 const char* name;
00863 const char* doc;
00864 };
00865 typedef std::vector<StaticMember> TStaticMembers;
00866
00867
00868
00869
00870
00871 class LASS_DLL StaticMemberEqual
00872 {
00873 public:
00874 StaticMemberEqual(const char* iName);
00875 bool operator()(const StaticMember& iMethod) const;
00876 private:
00877 const char* name_;
00878 };
00879
00880
00881
00882
00883
00884 class LASS_DLL PyMethodEqual
00885 {
00886 public:
00887 PyMethodEqual( const char* iName );
00888 bool operator()(const PyMethodDef& iMethod) const;
00889 private:
00890 const char* name_;
00891 };
00892
00893 LASS_DLL StaticMember LASS_CALL createStaticMember(
00894 const char* iName, const char * iDocumentation, const TStaticMemberHelperPtr& iObject,
00895 PyTypeObject* iParentType = 0, std::vector<PyMethodDef>* iMethods = 0,
00896 std::vector<PyGetSetDef>* iGetSetters = 0,
00897 const TStaticMembers* iStatics = 0);
00898 LASS_DLL PyMethodDef LASS_CALL createPyMethodDef(
00899 const char *ml_name, PyCFunction ml_meth, int ml_flags,
00900 const char *ml_doc);
00901 LASS_DLL PyGetSetDef LASS_CALL createPyGetSetDef(
00902 const char* name, getter get, setter set, const char* doc, void* closure);
00903
00904 LASS_DLL void LASS_CALL injectStaticMembers(
00905 PyTypeObject& iPyType, const TStaticMembers& iStatics);
00906 LASS_DLL void LASS_CALL finalizePyType(
00907 PyTypeObject& iPyType, PyTypeObject& iPyParentType,
00908 std::vector<PyMethodDef>& iMethods,
00909 std::vector<PyGetSetDef>& iGetSetters,
00910 const TStaticMembers& iStatics,
00911 const char* iModuleName, const char* iDocumentation);
00912 LASS_DLL void LASS_CALL addModuleFunction(
00913 std::vector<PyMethodDef>& ioModuleMethods,
00914 const char* iMethodName, const char* iDocumentation,
00915 PyCFunction iMethodDispatcher, PyCFunction& oOverloadChain);
00916 LASS_DLL void LASS_CALL addClassMethod(
00917 PyTypeObject& pyType,
00918 std::vector<PyMethodDef>& classMethods, TCompareFuncs& compareFuncs,
00919 const char* methodName, const char* documentation,
00920 PyCFunction dispatcher, unaryfunc dispatcherUnary,
00921 binaryfunc dispatcherBinary, ternaryfunc dispatcherTernary,
00922 ssizeargfunc dispatcherSsizeArg, ssizessizeargfunc dispatcherSsizeSsizeArg,
00923 lenfunc dispatcherLen, ssizeobjargproc dispatcherSsizeObjArgProc,
00924 ssizessizeobjargproc dispatcherSsizeSsizeObjArgProc,
00925 objobjproc dispatcherObjObjProc,
00926 OverloadLink& overloadChain);
00927
00928 template <typename CppClass> void injectClassInModule(
00929 PyObject* iModule, const char* iClassDocumentation);
00930 template <typename CppClass> void addClassStaticMethod(
00931 const char* iMethodName, const char* iDocumentation,
00932 PyCFunction iMethodDispatcher, PyCFunction& oOverloadChain);
00933 template <typename CppClass, typename T> void addClassStaticConst(
00934 const char* iName, const T& iValue);
00935 template <typename InnerCppClass> void addClassInnerClass(
00936 TStaticMembers& oOuterStatics,
00937 const char* iInnerClassName, const char* iDocumentation);
00938
00939 template <typename In, typename Out> int pyNumericCast(In iIn, Out& oV);
00940 template <typename Integer> int pyGetSignedObject(
00941 PyObject* iValue, Integer& oV);
00942 template <typename Integer> int pyGetUnsignedObject(
00943 PyObject* iValue, Integer& oV);
00944 template <typename Float> int pyGetFloatObject(
00945 PyObject* iValue, Float& oV);
00946
00947 LASS_DLL void LASS_CALL addMessageHeader(const std::string& iHeader);
00948 LASS_DLL bool LASS_CALL checkSequenceSize(PyObject* iValue, Py_ssize_t iExpectedSize);
00949 LASS_DLL TPyObjPtr LASS_CALL checkedFastSequence(PyObject* iValue, Py_ssize_t iExpectedSize);
00950 }
00951 }
00952 }
00953
00954 #if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
00955 # pragma warning(pop)
00956 #endif
00957
00958 #include "pyobject_plus.inl"
00959
00960 #endif