38bool HasAttrDirect(
PyObject* pyclass,
PyObject* pyname,
bool mustBeCPyCppyy =
false) {
41 PyObject* dct = PyObject_GetAttr(pyclass, PyStrings::gDict);
57 PyObject* dct = PyObject_GetAttr(pyclass, PyStrings::gDict);
67inline bool IsTemplatedSTLClass(
const std::string&
name,
const std::string& klass) {
69 auto pos =
name.find(klass);
70 return (pos == 0 || pos == 5) &&
name.find(
"::",
name.rfind(
">")) == std::string::npos;
78 PyObject*
result = PyObject_CallMethod(obj,
const_cast<char*
>(meth),
const_cast<char*
>(
""));
89 obj,
const_cast<char*
>(meth),
const_cast<char*
>(
"O"), arg1);
103 if (idx >=
size || (idx < 0 && idx < -
size)) {
104 PyErr_SetString(PyExc_IndexError,
"index out of range");
113 pyindex = PyLong_FromSsize_t(
size+idx);
122 if ((step > 0 && stop <= start) || (step < 0 && start <= stop))
125 if (start < 0)
start = 0;
126 if (start >= nlen)
start = nlen-1;
127 if (step >= nlen) step = nlen;
129 stop = step > 0 ? std::min(nlen, stop) : (stop >= 0 ? stop : -1);
155 if (
name == PyStrings::gTypeCode ||
name == PyStrings::gCTypesType) {
164 PyErr_SetString(PyExc_TypeError,
"getattr(): attribute name must be string");
172 PyObject* val1 = PyObject_Str(self);
174 PyErr_Format(PyExc_AttributeError,
"%s has no attribute \'%s\'",
194 PyErr_SetString(PyExc_TypeError,
"getattr(): attribute name must be string");
209 PyErr_SetString(PyExc_TypeError,
"C++ object proxy expected");
220#if PY_VERSION_HEX < 0x03040000
221#define PyObject_LengthHint _PyObject_LengthHint
226 ItemGetter(
PyObject* pyobj) : fPyObject(pyobj) { Py_INCREF(fPyObject); }
227 virtual ~ItemGetter() { Py_DECREF(fPyObject); }
233struct CountedItemGetter :
public ItemGetter {
234 CountedItemGetter(
PyObject* pyobj) : ItemGetter(pyobj), fCur(0) {}
238struct TupleItemGetter :
public CountedItemGetter {
239 using CountedItemGetter::CountedItemGetter;
242 if (fCur < PyTuple_GET_SIZE(fPyObject)) {
243 PyObject* item = PyTuple_GET_ITEM(fPyObject, fCur++);
247 PyErr_SetString(PyExc_StopIteration,
"end of tuple");
252struct ListItemGetter :
public CountedItemGetter {
253 using CountedItemGetter::CountedItemGetter;
256 if (fCur < PyList_GET_SIZE(fPyObject)) {
257 PyObject* item = PyList_GET_ITEM(fPyObject, fCur++);
261 PyErr_SetString(PyExc_StopIteration,
"end of list");
266struct SequenceItemGetter :
public CountedItemGetter {
267 using CountedItemGetter::CountedItemGetter;
276 virtual PyObject* get() {
return PySequence_GetItem(fPyObject, fCur++); }
279struct IterItemGetter :
public ItemGetter {
280 using ItemGetter::ItemGetter;
282 virtual PyObject* get() {
return (*(
Py_TYPE(fPyObject)->tp_iternext))(fPyObject); }
285static ItemGetter* GetGetter(
PyObject* args)
288 ItemGetter* getter =
nullptr;
290 if (PyTuple_GET_SIZE(args) == 1) {
291 PyObject* fi = PyTuple_GET_ITEM(args, 0);
298 if (PyObject_CheckBuffer(fi))
301 if (PyTuple_CheckExact(fi))
302 getter =
new TupleItemGetter(fi);
303 else if (PyList_CheckExact(fi))
304 getter =
new ListItemGetter(fi);
305 else if (PySequence_Check(fi))
306 getter =
new SequenceItemGetter(fi);
308 PyObject* iter = PyObject_GetIter(fi);
310 getter =
new IterItemGetter{iter};
328 PyObject* res = PyObject_CallMethod(vecin, (
char*)
"reserve", (
char*)
"n", sz);
337 PyObject* fi = PySequence_GetItem(PyTuple_GET_ITEM(args, 0), 0);
338 if (!fi) PyErr_Clear();
339 if (fi && (PyTuple_CheckExact(fi) || PyList_CheckExact(fi))) {
341 PyObject* eb_call = PyObject_GetAttrString(vecin, (
char*)
"emplace_back");
343 bool value_is_vector =
false;
347 value_is_vector =
true;
354 for (
int i = 0; ; ++i) {
357 if (value_is_vector && PySequence_Check(item)) {
358 eb_args = PyTuple_New(1);
359 PyTuple_SET_ITEM(eb_args, 0, item);
360 }
else if (PyTuple_CheckExact(item)) {
362 }
else if (PyList_CheckExact(item)) {
364 eb_args = PyTuple_New(isz);
366 PyObject* iarg = PyList_GET_ITEM(item, j);
368 PyTuple_SET_ITEM(eb_args, j, iarg);
373 PyErr_Format(PyExc_TypeError,
"argument %d is not a tuple or list", i);
377 PyObject* ebres = PyObject_CallObject(eb_call, eb_args);
385 if (PyErr_Occurred()) {
386 if (!(PyErr_ExceptionMatches(PyExc_IndexError) ||
387 PyErr_ExceptionMatches(PyExc_StopIteration)))
389 else { PyErr_Clear(); }
398 PyObject* pb_call = PyObject_GetAttrString(vecin, (
char*)
"push_back");
403 PyObject* pbres = PyObject_CallFunctionObjArgs(pb_call, item,
nullptr);
411 if (PyErr_Occurred()) {
412 if (!(PyErr_ExceptionMatches(PyExc_IndexError) ||
413 PyErr_ExceptionMatches(PyExc_StopIteration)))
415 else { PyErr_Clear(); }
431 ItemGetter* getter = GetGetter(args);
434 bool fill_ok =
FillVector(self, args, getter);
446 if (PyTuple_GET_SIZE(args) == 1) {
447 PyObject* fi = PyTuple_GET_ITEM(args, 0);
451 PyObject*
result = PyObject_CallMethodObjArgs(self, PyStrings::gInsert, vend, fi,
nullptr);
458 if (!PyErr_Occurred())
459 PyErr_SetString(PyExc_TypeError,
"argument is not iterable");
472 ItemGetter* getter = GetGetter(args);
482 bool fill_ok =
FillVector(self, args, getter);
494 PyObject* realInit = PyObject_GetAttr(self, PyStrings::gRealInit);
507 PyObject* pydata = CallPyObjMethod(self,
"__real_data");
517 long clen = PyInt_AsLong(pylen);
533 PyObject* pydata = VectorData(self,
nullptr);
543 if (!vi)
return nullptr;
557 vi->
vi_stride = PyLong_AsLong(pyvalue_size);
558 Py_DECREF(pyvalue_size);
581 if (value_type.back() !=
'*')
595 PyObject* pydata = CallPyObjMethod(
v,
"__real_data");
609 Py_XDECREF(pyvalue_type);
612 vi->
ii_len = PySequence_Size(
v);
614 PyObject_GC_Track(vi);
621 if (PySlice_Check(
index)) {
623 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
628 PyObject* nseq = PyObject_CallObject(pyclass,
nullptr);
634 if (!AdjustSlice(nlen, start, stop, step))
638 for (
Py_ssize_t i = start; i*sign < stop*sign; i += step) {
641 CallPyObjMethod(nseq,
"push_back", item);
649 return CallSelfIndex(self, (
PyObject*)
index, PyStrings::gGetNoCheck);
660 PyErr_Format(PyExc_TypeError,
661 "require object of type std::vector<bool>, but %s given",
667 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
671 if (PySlice_Check(idx)) {
673 PyObject* nseq = PyObject_CallObject(pyclass,
nullptr);
678 if (!AdjustSlice(nlen, start, stop, step))
682 for (
Py_ssize_t i = start; i*sign < stop*sign; i += step) {
685 CallPyObjMethod(nseq,
"push_back", item);
697 int index = (
int)PyLong_AsLong(pyindex);
701 std::vector<bool>* vb = (std::vector<bool>*)self->
GetObject();
704 if (
bool((*vb)[
index]))
714 PyErr_Format(PyExc_TypeError,
715 "require object of type std::vector<bool>, but %s given",
721 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
725 int bval = 0;
PyObject* idx =
nullptr;
726 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"Oi:__setitem__"), &idx, &bval))
733 int index = (
int)PyLong_AsLong(pyindex);
737 std::vector<bool>* vb = (std::vector<bool>*)self->
GetObject();
753 if (args && PyTuple_GET_SIZE(args) == 1 && PySequence_Check(PyTuple_GET_ITEM(args, 0))) {
759 PyObject* items = PyTuple_GET_ITEM(args, 0);
761 if (PySequence_Size(self) != fillsz) {
762 PyErr_Format(PyExc_ValueError,
"received sequence of size %zd where %zd expected",
763 fillsz, PySequence_Size(self));
768 PyObject* si_call = PyObject_GetAttr(self, PyStrings::gSetItem);
770 PyObject* item = PySequence_GetItem(items, i);
772 PyObject* sires = PyObject_CallFunctionObjArgs(si_call,
index, item,
nullptr);
789 PyObject* realInit = PyObject_GetAttr(self, PyStrings::gRealInit);
808 PyObject* si_call = PyObject_GetAttr(self, PyStrings::gSetItem);
809 for (
Py_ssize_t i = 0; i < PySequence_Size(pairs); ++i) {
810 PyObject* pair = PySequence_GetItem(pairs, i);
812 if (pair && PySequence_Check(pair) && PySequence_Size(pair) == 2) {
813 PyObject* key = PySequence_GetItem(pair, 0);
815 sires = PyObject_CallFunctionObjArgs(si_call, key,
value,
nullptr);
823 if (!PyErr_Occurred())
824 PyErr_SetString(PyExc_TypeError,
"Failed to fill map (argument not a dict or sequence of pairs)");
842 if (PyTuple_GET_SIZE(args) == 1 && PyMapping_Check(PyTuple_GET_ITEM(args, 0)) && \
843 !(PyTuple_Check(PyTuple_GET_ITEM(args, 0)) || PyList_Check(PyTuple_GET_ITEM(args, 0)))) {
844 PyObject* assoc = PyTuple_GET_ITEM(args, 0);
845#if PY_VERSION_HEX < 0x03000000
847 PyObject* items = PyObject_CallMethod(assoc, (
char*)
"items",
nullptr);
850 PyObject* items = PyMapping_Items(assoc);
852 if (items && PySequence_Check(items)) {
865 if (PyTuple_GET_SIZE(args) == 1 && PySequence_Check(PyTuple_GET_ITEM(args, 0)))
866 return MapFromPairs(self, PyTuple_GET_ITEM(args, 0));
869 PyObject* realInit = PyObject_GetAttr(self, PyStrings::gRealInit);
884 PyObject* iter = CallPyObjMethod(self,
"find", obj);
888 if (!PyObject_RichCompareBool(iter, end, Py_EQ)) {
911 if (PyTuple_GET_SIZE(args) == 1 && PySet_Check(PyTuple_GET_ITEM(args, 0))) {
912 PyObject* pyset = PyTuple_GET_ITEM(args, 0);
919 PyObject* iter = PyObject_GetIter(pyset);
921 PyObject* ins_call = PyObject_GetAttrString(self, (
char*)
"insert");
923 IterItemGetter getter{iter};
928 PyObject* insres = PyObject_CallFunctionObjArgs(ins_call, item,
nullptr);
945 PyObject* realInit = PyObject_GetAttr(self, PyStrings::gRealInit);
957static const ptrdiff_t PS_END_ADDR = 7;
958static const ptrdiff_t PS_FLAG_ADDR = 11;
959static const ptrdiff_t PS_COLL_ADDR = 13;
981 PyErr_SetString(PyExc_TypeError,
"unrecognized iterator type for low level views");
997 auto& dmc = ((
CPPInstance*)iter)->GetDatamemberCache();
998 dmc.push_back(std::make_pair(PS_END_ADDR, end));
1001 Py_INCREF(Py_False);
1002 dmc.push_back(std::make_pair(PS_FLAG_ADDR, Py_False));
1006 dmc.push_back(std::make_pair(PS_COLL_ADDR, self));
1021 if (!ii)
return nullptr;
1026 ii->
ii_len = PySequence_Size(
c);
1028 PyObject_GC_Track(ii);
1066 long idx = PyLong_AsLong(pyindex);
1067 if (idx == -1 && PyErr_Occurred())
1071 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
1076 return PyObject_GetAttr(self, PyStrings::gFirst);
1077 else if ((
int)idx == 1)
1078 return PyObject_GetAttr(self, PyStrings::gSecond);
1081 PyErr_SetString(PyExc_IndexError,
"out of bounds");
1087 return PyInt_FromLong(2);
1095 PyObject* realInit = PyObject_GetAttr(self, PyStrings::gRealInit);
1098 Py_DECREF(realInit);
1110#if PY_VERSION_HEX >= 0x03000000
1113 return !PyObject_RichCompareBool(one, other, Py_EQ);
1117PyObject* CPyCppyy_PyString_FromCppString(std::string* s,
bool native=
true) {
1124PyObject* CPyCppyy_PyString_FromCppString(std::wstring* s,
bool native=
true) {
1125 PyObject* pyobj = PyUnicode_FromWideChar(s->data(), s->size());
1126 if (pyobj && native) {
1127 PyObject* pybytes = PyUnicode_AsEncodedString(pyobj,
"UTF-8",
"strict");
1134#define CPPYY_IMPL_STRING_PYTHONIZATION(type, name) \
1136PyObject* name##StringGetData(PyObject* self, bool native=true) \
1138 if (CPyCppyy::CPPInstance_Check(self)) { \
1139 type* obj = ((type*)((CPPInstance*)self)->GetObject()); \
1140 if (obj) return CPyCppyy_PyString_FromCppString(obj, native); \
1142 PyErr_Format(PyExc_TypeError, "object mismatch (%s expected)", #type); \
1146PyObject* name##StringStr(PyObject* self) \
1148 PyObject* pyobj = name##StringGetData(self, false); \
1152 PyObject* pybytes = name##StringGetData(self, true); \
1154 pyobj = PyObject_Str(pybytes); \
1155 Py_DECREF(pybytes); \
1161PyObject* name##StringBytes(PyObject* self) \
1163 return name##StringGetData(self, true); \
1166PyObject* name##StringRepr(PyObject* self) \
1168 PyObject* data = name##StringGetData(self, true); \
1170 PyObject* repr = PyObject_Repr(data); \
1177PyObject* name##StringIsEqual(PyObject* self, PyObject* obj) \
1179 PyObject* data = name##StringGetData(self, PyBytes_Check(obj)); \
1181 PyObject* result = PyObject_RichCompare(data, obj, Py_EQ); \
1188PyObject* name##StringIsNotEqual(PyObject* self, PyObject* obj) \
1190 PyObject* data = name##StringGetData(self, PyBytes_Check(obj)); \
1192 PyObject* result = PyObject_RichCompare(data, obj, Py_NE); \
1200#define CPPYY_IMPL_STRING_PYTHONIZATION_CMP(type, name) \
1201CPPYY_IMPL_STRING_PYTHONIZATION(type, name) \
1202PyObject* name##StringCompare(PyObject* self, PyObject* obj) \
1204 PyObject* data = name##StringGetData(self, PyBytes_Check(obj)); \
1207 result = PyObject_Compare(data, obj); \
1210 if (PyErr_Occurred()) \
1212 return PyInt_FromLong(result); \
1218static inline std::string* GetSTLString(
CPPInstance* self) {
1220 PyErr_SetString(PyExc_TypeError,
"std::string object expected");
1224 std::string* obj = (std::string*)self->
GetObject();
1226 PyErr_SetString(PyExc_ReferenceError,
"attempt to access a null-pointer");
1233 std::string* obj = GetSTLString(self);
1237 char* keywords[] = {(
char*)
"encoding", (
char*)
"errors", (
char*)
nullptr};
1238 const char* encoding;
const char* errors;
1239 if (!PyArg_ParseTupleAndKeywords(args, kwds,
1240 const_cast<char*
>(
"s|s"), keywords, &encoding, &errors))
1243 return PyUnicode_Decode(obj->data(), obj->size(), encoding, errors);
1248 std::string* obj = GetSTLString(self);
1256 if (obj->find(needle) != std::string::npos) {
1265 std::string* obj = GetSTLString(self);
1275 PyObject* meth = PyObject_GetAttrString(pystr, (
char*)
"replace");
1282 PyObject* cppreplace = PyObject_GetAttrString((
PyObject*)self, (
char*)
"__cpp_replace");
1285 Py_DECREF(cppreplace);
1289 PyErr_SetString(PyExc_AttributeError,
"\'std::string\' object has no attribute \'replace\'");
1293#define CPYCPPYY_STRING_FINDMETHOD(name, cppname, pyname) \
1294PyObject* STLString##name(CPPInstance* self, PyObject* args, PyObject* ) \
1296 std::string* obj = GetSTLString(self); \
1300 PyObject* cppmeth = PyObject_GetAttrString((PyObject*)self, (char*)#cppname);\
1302 PyObject* result = PyObject_Call(cppmeth, args, nullptr); \
1303 Py_DECREF(cppmeth); \
1305 if (PyLongOrInt_AsULong64(result) == (PY_ULONG_LONG)std::string::npos) {\
1306 Py_DECREF(result); \
1307 return PyInt_FromLong(-1); \
1314 PyObject* pystr = CPyCppyy_PyText_FromStringAndSize(obj->data(), obj->size());\
1315 PyObject* pymeth = PyObject_GetAttrString(pystr, (char*)#pyname); \
1317 PyObject* result = PyObject_CallObject(pymeth, args); \
1318 Py_DECREF(pymeth); \
1329 std::string* obj = GetSTLString(self);
1347 PyObject* str_res = PyObject_Str(res);
1358 PyObject* str_res = PyObject_Str(res);
1381 PyObject* realInit = PyObject_GetAttr(self, PyStrings::gRealInit);
1383 PyObject *strbuf =
nullptr, *newArgs =
nullptr;
1384 if (PyTuple_GET_SIZE(args) == 1) {
1385 PyObject* arg0 = PyTuple_GET_ITEM(args, 0);
1386 if (PyUnicode_Check(arg0)) {
1388 strbuf = PyUnicode_AsEncodedString(arg0,
"UTF-8",
"strict");
1389 newArgs = PyTuple_New(1);
1391 PyTuple_SET_ITEM(newArgs, 0, strbuf);
1399 PyObject*
result = PyObject_Call(realInit, newArgs ? newArgs : args, nullptr);
1401 Py_XDECREF(newArgs);
1402 Py_DECREF(realInit);
1406 if (
result && self && strbuf)
1407 PyObject_SetAttr(self, PyStrings::gLifeLine, strbuf);
1420 bool mustIncrement =
true;
1423 auto& dmc = ((
CPPInstance*)self)->GetDatamemberCache();
1424 for (
auto&
p: dmc) {
1425 if (
p.first == PS_END_ADDR) {
1428 }
else if (
p.first == PS_FLAG_ADDR) {
1429 mustIncrement =
p.second == Py_True;
1430 if (!mustIncrement) {
1431 Py_DECREF(
p.second);
1442 if (!PyObject_RichCompareBool(last, self, Py_EQ)) {
1443 bool iter_valid =
true;
1444 if (mustIncrement) {
1450 static PyObject* dummy = PyInt_FromLong(1l);
1453 iter_valid = iter && PyObject_RichCompareBool(last, self, Py_NE);
1459 if (!next) PyErr_Clear();
1465 if (!next) PyErr_SetString(PyExc_StopIteration,
"");
1471#define COMPLEX_METH_GETSET(name, cppname) \
1472static PyObject* name##ComplexGet(PyObject* self, void*) { \
1473 return PyObject_CallMethodNoArgs(self, cppname); \
1475static int name##ComplexSet(PyObject* self, PyObject* value, void*) { \
1476 PyObject* result = PyObject_CallMethodOneArg(self, cppname, value); \
1478 Py_DECREF(result); \
1483PyGetSetDef name##Complex{(char*)#name, (getter)name##ComplexGet, (setter)name##ComplexSet, nullptr, nullptr};
1490 if (!real)
return nullptr;
1491 double r = PyFloat_AsDouble(real);
1493 if (
r == -1. && PyErr_Occurred())
1497 if (!imag)
return nullptr;
1498 double i = PyFloat_AsDouble(imag);
1500 if (i == -1. && PyErr_Occurred())
1503 return PyComplex_FromDoubles(
r, i);
1508 if (!real)
return nullptr;
1509 double r = PyFloat_AsDouble(real);
1511 if (
r == -1. && PyErr_Occurred())
1515 if (!imag)
return nullptr;
1516 double i = PyFloat_AsDouble(imag);
1518 if (i == -1. && PyErr_Occurred())
1521 std::ostringstream s;
1522 s <<
'(' <<
r <<
'+' << i <<
"j)";
1528 return PyFloat_FromDouble(((std::complex<double>*)self->
GetObject())->real());
1533 double d = PyFloat_AsDouble(
value);
1534 if (
d == -1.0 && PyErr_Occurred())
1536 ((std::complex<double>*)self->
GetObject())->real(
d);
1540PyGetSetDef ComplexDReal{(
char*)
"real", (getter)ComplexDRealGet, (setter)ComplexDRealSet,
nullptr,
nullptr};
1545 return PyFloat_FromDouble(((std::complex<double>*)self->
GetObject())->imag());
1550 double d = PyFloat_AsDouble(
value);
1551 if (
d == -1.0 && PyErr_Occurred())
1553 ((std::complex<double>*)self->
GetObject())->imag(
d);
1557PyGetSetDef ComplexDImag{(
char*)
"imag", (getter)ComplexDImagGet, (setter)ComplexDImagSet,
nullptr,
nullptr};
1561 double r = ((std::complex<double>*)self->
GetObject())->real();
1562 double i = ((std::complex<double>*)self->
GetObject())->imag();
1563 return PyComplex_FromDoubles(
r, i);
1579 Py_INCREF(pyclass); PyTuple_SET_ITEM(args, 0, pyclass);
1580 Py_INCREF(pyname); PyTuple_SET_ITEM(args, 1, pyname);
1582 bool pstatus =
true;
1583 for (
auto pythonizor :
v) {
1617 if (HasAttrDirect(pyclass, PyStrings::gCppBool)) {
1618#if PY_VERSION_HEX >= 0x03000000
1619 const char* pybool_name =
"__bool__";
1621 const char* pybool_name =
"__nonzero__";
1627 if (HasAttrDirect(pyclass, PyStrings::gSize))
1630 if (!IsTemplatedSTLClass(
name,
"vector") &&
1631 !((PyTypeObject*)pyclass)->tp_iter) {
1632 if (HasAttrDirect(pyclass, PyStrings::gBegin) && HasAttrDirect(pyclass, PyStrings::gEnd)) {
1642 if (resname.find(
"iterator") == std::string::npos)
1649 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)STLSequenceIter;
1655 if (resolved.back() ==
'*' &&
Cppyy::IsBuiltin(resolved.substr(0, resolved.size()-1))) {
1656 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)LLSequenceIter;
1662 if (!((PyTypeObject*)pyclass)->tp_iter &&
1663 HasAttrDirect(pyclass, PyStrings::gGetItem) && PyObject_HasAttr(pyclass, PyStrings::gLen)) {
1668 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)index_iter;
1676 if (HasAttrDirect(pyclass, PyStrings::gEq,
true) && \
1678 PyObject* cppol = PyObject_GetAttr(pyclass, PyStrings::gEq);
1686 top_eq = PyObject_GetAttr(top_cls, PyStrings::gEq);
1690 PyObject_SetAttr(pyclass, PyStrings::gEq, top_eq);
1693 if (HasAttrDirect(pyclass, PyStrings::gNe,
true) && \
1695 PyObject* cppol = PyObject_GetAttr(pyclass, PyStrings::gNe);
1702 top_ne = PyObject_GetAttr(top_cls, PyStrings::gNe);
1706 PyObject_SetAttr(pyclass, PyStrings::gNe, top_ne);
1710 if (HasAttrDirect(pyclass, PyStrings::gRepr,
true)) {
1716 if (HasAttrDirect(pyclass, PyStrings::gStr,
true)) {
1730 std::string rname =
name;
1733 std::ostringstream initdef;
1734 initdef <<
"namespace __cppyy_internal {\n"
1735 <<
"void init_" << rname <<
"(" <<
name <<
"*& self";
1736 bool codegen_ok =
true;
1737 std::vector<std::string> arg_types, arg_names, arg_defaults;
1738 arg_types.reserve(ndata); arg_names.reserve(ndata); arg_defaults.reserve(ndata);
1748 if (res_clean ==
"internal_enum_type_t")
1751 if (res.rfind(
']') == std::string::npos && res.rfind(
')') == std::string::npos) {
1752 if (!cpd.empty()) arg_types.push_back(res_clean+cpd);
1753 else arg_types.push_back(
"const "+res_clean+
"&");
1756 arg_defaults.push_back(
"0");
1767 if (codegen_ok && !arg_types.empty()) {
1768 bool defaults_ok = arg_defaults.size() == arg_types.size();
1769 for (std::vector<std::string>::size_type i = 0; i < arg_types.size(); ++i) {
1770 initdef <<
", " << arg_types[i] <<
" " << arg_names[i];
1771 if (defaults_ok) initdef <<
" = " << arg_defaults[i];
1773 initdef <<
") {\n self = new " <<
name <<
"{";
1774 for (std::vector<std::string>::size_type i = 0; i < arg_names.size(); ++i) {
1775 if (i != 0) initdef <<
", ";
1776 initdef << arg_names[i];
1778 initdef <<
"};\n} }";
1797 if (IsTemplatedSTLClass(
name,
"vector")) {
1801 if (klass->
fCppType == sVectorBoolTypeID) {
1807 Utility::AddToClass(pyclass,
"__init__", (PyCFunction)VectorInit, METH_VARARGS | METH_KEYWORDS);
1817 if (HasAttrDirect(pyclass, PyStrings::gLen)) {
1823 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)vector_iter;
1826 Utility::AddToClass(pyclass,
"__iadd__", (PyCFunction)VectorIAdd, METH_VARARGS | METH_KEYWORDS);
1830 if (vtype.rfind(
"value_type") == std::string::npos) {
1832 PyObject_SetAttr(pyclass, PyStrings::gValueType, pyvalue_type);
1833 Py_DECREF(pyvalue_type);
1838 PyObject* pyvalue_size = PyLong_FromSsize_t(typesz);
1839 PyObject_SetAttr(pyclass, PyStrings::gValueSize, pyvalue_size);
1840 Py_DECREF(pyvalue_size);
1845 else if (IsTemplatedSTLClass(
name,
"array")) {
1848 Utility::AddToClass(pyclass,
"__init__", (PyCFunction)ArrayInit, METH_VARARGS | METH_KEYWORDS);
1851 else if (IsTemplatedSTLClass(
name,
"map") || IsTemplatedSTLClass(
name,
"unordered_map")) {
1854 Utility::AddToClass(pyclass,
"__init__", (PyCFunction)MapInit, METH_VARARGS | METH_KEYWORDS);
1859 else if (IsTemplatedSTLClass(
name,
"set")) {
1862 Utility::AddToClass(pyclass,
"__init__", (PyCFunction)SetInit, METH_VARARGS | METH_KEYWORDS);
1867 else if (IsTemplatedSTLClass(
name,
"pair")) {
1872 if (IsTemplatedSTLClass(
name,
"shared_ptr") || IsTemplatedSTLClass(
name,
"unique_ptr")) {
1874 Utility::AddToClass(pyclass,
"__init__", (PyCFunction)SmartPtrInit, METH_VARARGS | METH_KEYWORDS);
1877 else if (!((PyTypeObject*)pyclass)->tp_iter && \
1879 ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)STLIterNext;
1881 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)PyObject_SelfIter;
1885 else if (
name ==
"string" ||
name ==
"std::string") {
1893 Utility::AddToClass(pyclass,
"decode", (PyCFunction)STLStringDecode, METH_VARARGS | METH_KEYWORDS);
1895 Utility::AddToClass(pyclass,
"find", (PyCFunction)STLStringFind, METH_VARARGS | METH_KEYWORDS);
1897 Utility::AddToClass(pyclass,
"rfind", (PyCFunction)STLStringRFind, METH_VARARGS | METH_KEYWORDS);
1899 Utility::AddToClass(pyclass,
"replace", (PyCFunction)STLStringReplace, METH_VARARGS | METH_KEYWORDS);
1903 ((PyTypeObject*)pyclass)->tp_hash = (hashfunc)STLStringHash;
1906 else if (
name ==
"basic_string_view<char>" ||
name ==
"std::basic_string_view<char>") {
1908 Utility::AddToClass(pyclass,
"__init__", (PyCFunction)StringViewInit, METH_VARARGS | METH_KEYWORDS);
1911 else if (
name ==
"basic_string<wchar_t,char_traits<wchar_t>,allocator<wchar_t> >" ||
name ==
"std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >") {
1920 else if (
name ==
"complex<double>" ||
name ==
"std::complex<double>") {
1922 PyObject_SetAttrString(pyclass,
"real", PyDescr_NewGetSet((PyTypeObject*)pyclass, &ComplexDReal));
1924 PyObject_SetAttrString(pyclass,
"imag", PyDescr_NewGetSet((PyTypeObject*)pyclass, &ComplexDImag));
1929 else if (IsTemplatedSTLClass(
name,
"complex")) {
1931 PyObject_SetAttrString(pyclass,
"real", PyDescr_NewGetSet((PyTypeObject*)pyclass, &realComplex));
1933 PyObject_SetAttrString(pyclass,
"imag", PyDescr_NewGetSet((PyTypeObject*)pyclass, &imagComplex));
1941 bool bUserOk =
true;
PyObject* res =
nullptr;
1943 if (HasAttrDirect(pyclass, PyStrings::gExPythonize)) {
1944 res = PyObject_CallMethodObjArgs(pyclass, PyStrings::gExPythonize, pyclass, pyname,
nullptr);
1945 bUserOk = (
bool)res;
1947 PyObject* func = PyObject_GetAttr(pyclass, PyStrings::gPythonize);
1949 res = PyObject_CallFunctionObjArgs(func, pyclass, pyname,
nullptr);
1951 bUserOk = (
bool)res;
1965 bool pstatus =
true;
1967 if (!outer_scope.empty()) {
1971 name.substr(outer_scope.size()+2, std::string::npos).c_str());
#define PyInt_FromSsize_t
#define CPyCppyy_PyText_FromStringAndSize
#define CPyCppyy_PySliceCast
#define CPyCppyy_PyText_AsString
static PyObject * PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg)
#define PyBytes_FromStringAndSize
#define CPyCppyy_PyText_Type
static PyObject * PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name)
#define CPyCppyy_PyText_FromString
#define CPyCppyy_PyText_Check
#define CPPYY_IMPL_STRING_PYTHONIZATION_CMP(type, name)
static bool run_pythonizors(PyObject *pyclass, PyObject *pyname, const std::vector< PyObject * > &v)
#define COMPLEX_METH_GETSET(name, cppname)
#define CPYCPPYY_STRING_FINDMETHOD(name, cppname, pyname)
#define PyObject_LengthHint
void FillVector(std::vector< double > &v, int size, T *a)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
Cppyy::TCppType_t ObjectIsA(bool check_smart=true) const
Utility::PyOperators * fOperators
Cppyy::TCppType_t fCppType
void cppscope_to_legalname(std::string &cppscope)
std::string clean_type(const std::string &cppname, bool template_strip=true, bool const_strip=true)
std::string compound(const std::string &name)
std::string extract_namespace(const std::string &name)
Py_ssize_t GetBuffer(PyObject *pyobject, char tc, int size, void *&buf, bool check=true)
bool AddToClass(PyObject *pyclass, const char *label, PyCFunction cfunc, int flags=METH_VARARGS)
PyTypeObject VectorIter_Type
static PyObject * GetAttrDirect(PyObject *pyclass, PyObject *pyname)
bool Pythonize(PyObject *pyclass, const std::string &name)
bool CPPOverload_Check(T *object)
std::map< std::string, std::vector< PyObject * > > gPythonizations
bool CPPScope_Check(T *object)
bool LowLevelView_Check(T *object)
bool CPPInstance_Check(T *object)
PyTypeObject IndexIter_Type
CPYCPPYY_EXTERN Converter * CreateConverter(const std::string &name, cdims_t=0)
std::set< std::string > gIteratorTypes
RPY_EXPORTED size_t SizeOf(TCppType_t klass)
RPY_EXPORTED bool IsDefaultConstructable(TCppType_t type)
RPY_EXPORTED bool IsEnum(const std::string &type_name)
RPY_EXPORTED std::vector< TCppIndex_t > GetMethodIndicesFromName(TCppScope_t scope, const std::string &name)
RPY_EXPORTED TCppIndex_t GetNumDatamembers(TCppScope_t scope, bool accept_namespace=false)
RPY_EXPORTED bool Compile(const std::string &code, bool silent=false)
RPY_EXPORTED std::string ResolveName(const std::string &cppitem_name)
RPY_EXPORTED bool IsAggregate(TCppType_t type)
RPY_EXPORTED std::string GetScopedFinalName(TCppType_t type)
RPY_EXPORTED bool IsPublicData(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED bool IsBuiltin(const std::string &type_name)
RPY_EXPORTED bool IsStaticData(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED std::string GetDatamemberType(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED TCppMethod_t GetMethod(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED bool IsSmartPtr(TCppType_t type)
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
RPY_EXPORTED std::string GetMethodResultType(TCppMethod_t)
RPY_EXPORTED std::string GetDatamemberName(TCppScope_t scope, TCppIndex_t idata)
PyObject_HEAD PyObject * ii_container
Cppyy::TCppType_t vi_klass
CPyCppyy::Converter * vi_converter