diff options
Diffstat (limited to 'sources/shiboken2/libshiboken/basewrapper.cpp')
-rw-r--r-- | sources/shiboken2/libshiboken/basewrapper.cpp | 223 |
1 files changed, 96 insertions, 127 deletions
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp index ec705a421..9eb686ed0 100644 --- a/sources/shiboken2/libshiboken/basewrapper.cpp +++ b/sources/shiboken2/libshiboken/basewrapper.cpp @@ -118,20 +118,15 @@ static int SbkObject_traverse(PyObject* self, visitproc visit, void* arg) //Visit children Shiboken::ParentInfo* pInfo = sbkSelf->d->parentInfo; if (pInfo) { - std::set<SbkObject*>::const_iterator it = pInfo->children.begin(); - for(; it != pInfo->children.end(); ++it) - Py_VISIT(*it); + for (SbkObject *c : pInfo->children) + Py_VISIT(c); } //Visit refs Shiboken::RefCountMap* rInfo = sbkSelf->d->referredObjects; if (rInfo) { - Shiboken::RefCountMap::const_iterator it = rInfo->begin(); - for (; it != rInfo->end(); ++it) { - std::list<PyObject*>::const_iterator ref = it->second.begin(); - for(; ref != it->second.end(); ++ref) - Py_VISIT(*ref); - } + for (auto it = rInfo->begin(), end = rInfo->end(); it != end; ++it) + Py_VISIT(it->second); } if (sbkSelf->ob_dict) @@ -325,7 +320,7 @@ PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* k Shiboken::ObjectType::initPrivateData(newType); SbkObjectTypePrivate *sotp = PepType_SOTP(newType); - std::list<SbkObjectType*> bases = Shiboken::getCppBaseClasses(reinterpret_cast<PyTypeObject*>(newType)); + const auto bases = Shiboken::getCppBaseClasses(reinterpret_cast<PyTypeObject*>(newType)); if (bases.size() == 1) { SbkObjectTypePrivate *parentType = PepType_SOTP(bases.front()); sotp->mi_offsets = parentType->mi_offsets; @@ -352,10 +347,9 @@ PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* k sotp->d_func = nullptr; sotp->is_user_type = 1; - std::list<SbkObjectType*>::const_iterator it = bases.begin(); - for (; it != bases.end(); ++it) { - if (PepType_SOTP(*it)->subtype_init) - PepType_SOTP(*it)->subtype_init(newType, args, kwds); + for (SbkObjectType *base : bases) { + if (PepType_SOTP(base)->subtype_init) + PepType_SOTP(base)->subtype_init(newType, args, kwds); } return reinterpret_cast<PyObject*>(newType); @@ -453,9 +447,6 @@ void _destroyParentInfo(SbkObject* obj, bool keepReference) namespace Shiboken { - -static void decRefPyObjectList(const std::list<PyObject*> &pyObj, PyObject* skip = 0); - static void _walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor) { PyObject* bases = currentType->tp_bases; @@ -522,8 +513,7 @@ void DtorCallerVisitor::visit(SbkObjectType* node) void DtorCallerVisitor::done() { - std::list<std::pair<void*, SbkObjectType*> >::const_iterator it = m_ptrs.begin(); - for (; it != m_ptrs.end(); ++it) { + for (auto it = m_ptrs.begin(), end = m_ptrs.end(); it != end; ++it) { Shiboken::ThreadStateSaver threadSaver; threadSaver.save(); PepType_SOTP(it->second)->cpp_dtor(it->first); @@ -623,9 +613,9 @@ class FindBaseTypeVisitor : public HierarchyVisitor PyTypeObject* m_typeToFind; }; -std::list<SbkObject*> splitPyObject(PyObject* pyObj) +std::vector<SbkObject *> splitPyObject(PyObject* pyObj) { - std::list<SbkObject*> result; + std::vector<SbkObject *> result; if (PySequence_Check(pyObj)) { AutoDecRef lst(PySequence_Fast(pyObj, "Invalid keep reference object.")); if (!lst.isNull()) { @@ -641,14 +631,11 @@ std::list<SbkObject*> splitPyObject(PyObject* pyObj) return result; } -static void decRefPyObjectList(const std::list<PyObject*>& lst, PyObject *skip) +template <class Iterator> +inline void decRefPyObjectList(Iterator i1, Iterator i2) { - std::list<PyObject*>::const_iterator iter = lst.begin(); - while(iter != lst.end()) { - if (*iter != skip) - Py_DECREF(*iter); - ++iter; - } + for (; i1 != i2; ++i1) + Py_DECREF(i1->second); } namespace ObjectType @@ -842,12 +829,13 @@ static void setSequenceOwnership(PyObject* pyObj, bool owner) if (PySequence_Check(pyObj) && has_length) { Py_ssize_t size = PySequence_Size(pyObj); if (size > 0) { - std::list<SbkObject*> objs = splitPyObject(pyObj); - for (auto it = objs.begin(), end = objs.end(); it != end; ++it) { - if (owner) - getOwnership(*it); - else - releaseOwnership(*it); + const auto objs = splitPyObject(pyObj); + if (owner) { + for (SbkObject *o : objs) + getOwnership(o); + } else { + for (SbkObject *o : objs) + releaseOwnership(o); } } } else if (Object::checkType(pyObj)) { @@ -975,10 +963,9 @@ void invalidate(SbkObject* self) static void recursive_invalidate(PyObject* pyobj, std::set<SbkObject*>& seen) { - std::list<SbkObject*> objs = splitPyObject(pyobj); - std::list<SbkObject*>::const_iterator it = objs.begin(); - for (; it != objs.end(); it++) - recursive_invalidate(*it, seen); + const auto objs = splitPyObject(pyobj); + for (SbkObject *o : objs) + recursive_invalidate(o, seen); } static void recursive_invalidate(SbkObject* self, std::set<SbkObject*>& seen) @@ -997,30 +984,22 @@ static void recursive_invalidate(SbkObject* self, std::set<SbkObject*>& seen) if (self->d->parentInfo) { // Create a copy because this list can be changed during the process ChildrenList copy = self->d->parentInfo->children; - ChildrenList::iterator it = copy.begin(); - for (; it != copy.end(); ++it) { + for (SbkObject *child : copy) { // invalidate the child - recursive_invalidate(*it, seen); + recursive_invalidate(child, seen); // if the parent not is a wrapper class, then remove children from him, because We do not know when this object will be destroyed if (!self->d->validCppObject) - removeParent(*it, true, true); + removeParent(child, true, true); } } // If has ref to other objects invalidate all if (self->d->referredObjects) { RefCountMap& refCountMap = *(self->d->referredObjects); - RefCountMap::iterator iter; - for (iter = refCountMap.begin(); iter != refCountMap.end(); ++iter) { - const std::list<PyObject*> lst = iter->second; - std::list<PyObject*>::const_iterator it = lst.begin(); - while(it != lst.end()) { - recursive_invalidate(*it, seen); - ++it; - } - } + for (auto it = refCountMap.begin(), end = refCountMap.end(); it != end; ++it) + recursive_invalidate(it->second, seen); } } @@ -1035,23 +1014,17 @@ void makeValid(SbkObject* self) // If it is a parent make all children valid if (self->d->parentInfo) { - ChildrenList::iterator it = self->d->parentInfo->children.begin(); - for (; it != self->d->parentInfo->children.end(); ++it) - makeValid(*it); + for (SbkObject *child : self->d->parentInfo->children) + makeValid(child); } // If has ref to other objects make all valid again if (self->d->referredObjects) { RefCountMap& refCountMap = *(self->d->referredObjects); RefCountMap::iterator iter; - for (iter = refCountMap.begin(); iter != refCountMap.end(); ++iter) { - const std::list<PyObject*> lst = iter->second; - std::list<PyObject*>::const_iterator it = lst.begin(); - while(it != lst.end()) { - if (Shiboken::Object::checkType(*it)) - makeValid(reinterpret_cast<SbkObject*>(*it)); - ++it; - } + for (auto it = refCountMap.begin(), end = refCountMap.end(); it != end; ++it) { + if (Shiboken::Object::checkType(it->second)) + makeValid(reinterpret_cast<SbkObject *>(it->second)); } } } @@ -1166,15 +1139,14 @@ SbkObject *findColocatedChild(SbkObject *wrapper, ChildrenList& children = pInfo->children; - ChildrenList::iterator childrenEnd = children.end(); - for (ChildrenList::iterator iChild = children.begin(); iChild != childrenEnd; ++iChild) { - if (!((*iChild)->d && (*iChild)->d->cptr)) + for (SbkObject *child : children) { + if (!(child->d && child->d->cptr)) continue; - if ((*iChild)->d->cptr[0] == wrapper->d->cptr[0]) { - if (reinterpret_cast<const void *>(Py_TYPE(*iChild)) == reinterpret_cast<const void *>(instanceType)) - return const_cast<SbkObject *>((*iChild)); + if (child->d->cptr[0] == wrapper->d->cptr[0]) { + if (reinterpret_cast<const void *>(Py_TYPE(child)) == reinterpret_cast<const void *>(instanceType)) + return child; else - return findColocatedChild(const_cast<SbkObject *>(*iChild), instanceType); + return findColocatedChild(child, instanceType); } } return 0; @@ -1433,57 +1405,56 @@ void* getTypeUserData(SbkObject* wrapper) return PepType_SOTP(Py_TYPE(wrapper))->user_data; } -void keepReference(SbkObject* self, const char* key, PyObject* referredObject, bool append) +static inline bool isNone(const PyObject *o) { - bool isNone = (!referredObject || (referredObject == Py_None)); - - if (!self->d->referredObjects) - self->d->referredObjects = new Shiboken::RefCountMap; - - RefCountMap& refCountMap = *(self->d->referredObjects); - RefCountMap::iterator iter = refCountMap.find(key); - std::list<PyObject*> objects; - if (iter != refCountMap.end()) { - objects = (*iter).second; - std::list<PyObject*>::const_iterator found = std::find(objects.begin(), objects.end(), referredObject); - - // skip if objects already exists - if (found != objects.end()) - return; - } + return o == nullptr || o == Py_None; +} - if (append && !isNone) { - refCountMap[key].push_back(referredObject); - Py_INCREF(referredObject); - } else if (!append) { - if (objects.size() > 0) - decRefPyObjectList(objects, isNone ? 0 : referredObject); - if (isNone) { - if (iter != refCountMap.end()) - refCountMap.erase(iter); - } else { - objects.clear(); - objects.push_back(referredObject); - refCountMap[key] = objects; - Py_INCREF(referredObject); +static void removeRefCountKey(SbkObject* self, const char *key) +{ + if (self->d->referredObjects) { + const auto iterPair = self->d->referredObjects->equal_range(key); + if (iterPair.first != iterPair.second) { + decRefPyObjectList(iterPair.first, iterPair.second); + self->d->referredObjects->erase(iterPair.first, iterPair.second); } } } -void removeReference(SbkObject* self, const char* key, PyObject* referredObject) +void keepReference(SbkObject* self, const char* key, PyObject* referredObject, bool append) { - if (!referredObject || (referredObject == Py_None)) + if (isNone(referredObject)) { + removeRefCountKey(self, key); return; + } - if (!self->d->referredObjects) + if (!self->d->referredObjects) { + self->d->referredObjects = + new Shiboken::RefCountMap{RefCountMap::value_type{key, referredObject}}; + Py_INCREF(referredObject); return; + } RefCountMap& refCountMap = *(self->d->referredObjects); - RefCountMap::iterator iter = refCountMap.find(key); - if (iter != refCountMap.end()) { - decRefPyObjectList(iter->second); - refCountMap.erase(iter); + const auto iterPair = refCountMap.equal_range(key); + if (std::any_of(iterPair.first, iterPair.second, + [referredObject](const RefCountMap::value_type &v) { return v.second == referredObject; })) { + return; } + + if (!append && iterPair.first != iterPair.second) { + decRefPyObjectList(iterPair.first, iterPair.second); + refCountMap.erase(iterPair.first, iterPair.second); + } + + refCountMap.insert(RefCountMap::value_type{key, referredObject}); + Py_INCREF(referredObject); +} + +void removeReference(SbkObject* self, const char* key, PyObject* referredObject) +{ + if (!isNone(referredObject)) + removeRefCountKey(self, key); } void clearReferences(SbkObject* self) @@ -1492,27 +1463,27 @@ void clearReferences(SbkObject* self) return; RefCountMap& refCountMap = *(self->d->referredObjects); - RefCountMap::iterator iter; - for (iter = refCountMap.begin(); iter != refCountMap.end(); ++iter) - decRefPyObjectList(iter->second); + for (auto it = refCountMap.begin(), end = refCountMap.end(); it != end; ++it) + Py_DECREF(it->second); self->d->referredObjects->clear(); } std::string info(SbkObject* self) { std::ostringstream s; - std::list<SbkObjectType*> bases; if (self->d && self->d->cptr) { + std::vector<SbkObjectType *> bases; if (ObjectType::isUserType(Py_TYPE(self))) bases = getCppBaseClasses(Py_TYPE(self)); else bases.push_back(reinterpret_cast<SbkObjectType*>(Py_TYPE(self))); s << "C++ address....... "; - std::list<SbkObjectType*>::const_iterator it = bases.begin(); - for (int i = 0; it != bases.end(); ++it, ++i) - s << reinterpret_cast<PyTypeObject *>(*it)->tp_name << '/' << self->d->cptr[i] << ' '; + for (size_t i = 0, size = bases.size(); i < size; ++i) { + auto base = reinterpret_cast<PyTypeObject *>(bases[i]); + s << base->tp_name << '/' << self->d->cptr[i] << ' '; + } s << "\n"; } else { @@ -1533,9 +1504,8 @@ std::string info(SbkObject* self) if (self->d->parentInfo && self->d->parentInfo->children.size()) { s << "children.......... "; - ChildrenList& children = self->d->parentInfo->children; - for (ChildrenList::const_iterator it = children.begin(); it != children.end(); ++it) { - Shiboken::AutoDecRef child(PyObject_Str(reinterpret_cast<PyObject *>(*it))); + for (SbkObject *sbkChild : self->d->parentInfo->children) { + Shiboken::AutoDecRef child(PyObject_Str(reinterpret_cast<PyObject *>(sbkChild))); s << String::toCString(child) << ' '; } s << '\n'; @@ -1544,17 +1514,16 @@ std::string info(SbkObject* self) if (self->d->referredObjects && self->d->referredObjects->size()) { Shiboken::RefCountMap& map = *self->d->referredObjects; s << "referred objects.. "; - Shiboken::RefCountMap::const_iterator it = map.begin(); - for (; it != map.end(); ++it) { - if (it != map.begin()) - s << " "; - s << '"' << it->first << "\" => "; - std::list<PyObject*>::const_iterator j = it->second.begin(); - for (; j != it->second.end(); ++j) { - Shiboken::AutoDecRef obj(PyObject_Str(*j)); - s << String::toCString(obj) << ' '; + std::string lastKey; + for (auto it = map.begin(), end = map.end(); it != end; ++it) { + if (it->first != lastKey) { + if (!lastKey.empty()) + s << " "; + s << '"' << it->first << "\" => "; + lastKey = it->first; } - s << ' '; + Shiboken::AutoDecRef obj(PyObject_Str(it->second)); + s << String::toCString(obj) << ' '; } s << '\n'; } |