[Bf-blender-cvs] [c4286ddb095] master: RNA: support range-based for loops in C++ api

Jacques Lucke noreply at git.blender.org
Fri Jan 15 16:39:50 CET 2021


Commit: c4286ddb095d32714c9d5f10751a14f5871b3844
Author: Jacques Lucke
Date:   Fri Jan 15 16:35:22 2021 +0100
Branches: master
https://developer.blender.org/rBc4286ddb095d32714c9d5f10751a14f5871b3844

RNA: support range-based for loops in C++ api

Cycles has a lot of code like this:
```lang=c++
BL::Object::modifiers_iterator b_mod;
for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
```

Range-based for loops allow us to simplify this to:
```lang=c++
for (BL::Modifier &b_mod : b_ob->modifiers) {
```

In order to support this, a collection (such as `b_ob->modifiers`) must have
a `begin()` and `end()` method, that take no parameters and return an iterator.
The `end` method already exists, but the `begin` method takes the iterator as
argument currently.

This patch adds a new `begin` method that returns the iterator. The old `begin`
method is still available to avoid breaking existing code.

My assumption is that the old `begin` method took the iterator as parameter so
that the iterator is not copied or moved, i.e. its memory address is stable and
the destructor is only called once. I'm not sure if both of these requirements
are really necessary to ensure that the iterators work correctly. To be on the
safe side, I deleted the copy/move constructors/assignment operators.

Since C++17 there is "guaranteed copy elision" which basically allows us to
return a non-copyable and non-movable type from a function. To make that work,
I had to add a new constructor to `CollectionIterator` that calls `begin` on itself.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D10120

===================================================================

M	source/blender/makesrna/intern/makesrna.c

===================================================================

diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index e9e00ff6f71..bec3db10905 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -4758,8 +4758,14 @@ static const char *cpp_classes =
     "class CollectionIterator {\n"
     "public:\n"
     "    CollectionIterator() : iter(), t(iter.ptr), init(false) { iter.valid = false; }\n"
+    "    CollectionIterator(const PointerRNA &ptr) : CollectionIterator() { this->begin(ptr); }\n"
     "    ~CollectionIterator(void) { if (init) Tend(&iter); };\n"
     "\n"
+    "    CollectionIterator(const CollectionIterator &other) = delete;\n"
+    "    CollectionIterator(CollectionIterator &&other) = delete;\n"
+    "    CollectionIterator &operator=(const CollectionIterator &other) = delete;\n"
+    "    CollectionIterator &operator=(CollectionIterator &&other) = delete;\n"
+    "\n"
     "    operator bool(void)\n"
     "    { return iter.valid != 0; }\n"
     "    const CollectionIterator<T, Tbegin, Tnext, Tend>& operator++() { Tnext(&iter); t = "
@@ -4777,9 +4783,6 @@ static const char *cpp_classes =
     "true; }\n"
     "\n"
     "private:\n"
-    "    const CollectionIterator<T, Tbegin, Tnext, Tend>& operator = "
-    "(const CollectionIterator<T, Tbegin, Tnext, Tend>& /*copy*/) {}\n"
-    ""
     "    CollectionPropertyIterator iter;\n"
     "    T t;\n"
     "    bool init;\n"
@@ -4794,6 +4797,8 @@ static const char *cpp_classes =
     "\n"
     "    void begin(CollectionIterator<T, Tbegin, Tnext, Tend>& iter)\n"
     "    { iter.begin(ptr); }\n"
+    "    CollectionIterator<T, Tbegin, Tnext, Tend> begin()\n"
+    "    { return CollectionIterator<T, Tbegin, Tnext, Tend>(ptr); }\n"
     "    CollectionIterator<T, Tbegin, Tnext, Tend> end()\n"
     "    { return CollectionIterator<T, Tbegin, Tnext, Tend>(); } /* test */ \n"
     ""



More information about the Bf-blender-cvs mailing list