-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove parametrization of end iterators #2168
Remove parametrization of end iterators #2168
Conversation
I don't agree with what you're proposing but maybe I'm failing to see the point. Maybe it's better to elaborate on the changes you want by actually implementing them, plus the necessary adjustments to the units tests. Based simply on what your wrote it's still unclear why you don't think it's "fair". When you use octree.begin(depth) you need to use the appropriate octree.end(depth). I believe that if the begin iterator is parameterized on a desired depth, the end iterator must also be. Iterators with different max depths don't perform traversal the same way, therefore the max depth needs to be taken into account during the equivalence comparison. If something is really equal, it means that if you apply the same operations to both "copies", they need to end up in the same state after those operations. With your proposal, you can no longer ensure this. |
This is the point of my proposition. Before the recent change of the iterator implementation, whatever the depth you use to walk over an octree, it was possible to reach the exit condition with an My preference is to allow the use of I don't want to care about the initial depth of an iterator to parametrise the end iterator accordingly. Maybe it's possible to adjust the comparison operator to get both behavior:
I'll do another proposition. |
In my last commit, I modify the comparison of iterator to preserve/get the behaviors I was talking about. Of course after this change, on the unit test './test/octree/test_octree_iterator' I get the following failures:
as expected. @SergioRAgostinho : Before to go further, do you agree with the spirit of this comparison operator? |
This is the main point I'm not willing to violate/wave. If you come up with a solution which respects this constraint and doesn't require I understand passing a parameter to |
Just noticed you asked me this directly. Can you change the failing units tests to showcase the new logic you implemented with your modifications i.e., modify them so that they all pass. Edit: In theory your comparison logic should do it. You'll need to remove all the end methods I added, to stop accepting a depth parameter. |
As far as I can see, our iterators are not decrementable. If they were, |
Ok, in this pull request, we have:
Ready for a review. |
|
||
EXPECT_NE (it_m_1, it_m_2); | ||
EXPECT_EQ (it_m_2, it_m); // tree depth is 2 | ||
EXPECT_NE (it_m_1, it_m_b_1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should leave the test in which you verify that the end iterators from different octrees are not the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests concern iterators from different depth and differnet octree. The test about iterators from different octrees is preserved above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait for your feedback.
@@ -258,16 +258,6 @@ TEST_F (OctreeBaseBeginEndIteratorsTest, End) | |||
EXPECT_EQ (it_a_1, it_a_2); | |||
EXPECT_NE (it_a_1, it_b); | |||
EXPECT_NE (it_a_2, it_b); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SergioRAgostinho: This is the test about iterator from different octrees.
42faab9
to
e3e23af
Compare
A rebase has been done. |
e3e23af
to
2b4a7d1
Compare
((!(current_state_) && !(other.current_state_)) || // end state case | ||
((max_octree_depth_ == other.max_octree_depth_) && | ||
(current_state_ && other.current_state_ && // null dereference protection | ||
(current_state_->key_ == other.current_state_->key_))))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I the only one who finds this return statement extremely convoluted and confusing? What about something like this? I suppose the compiler will produce the same assembly anyway.
if (this == &other) // same object
return true;
if (octree_ != other.octree_) // refer to different octrees
return false;
if (!current_state_ && !other.current_state_) // both are end iterators
return true;
if (max_octree_depth_ == other.max_octree_depth_ &&
current_state_ && other.current_state_ && // null dereference protection
current_state_->key_ == other.current_state_.key_)
return true;
return false;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should test it, but I completely agree with you, your proposition is obviously more readable @taketwo 👍
d521c6e
to
601288f
Compare
Adapt the operator==() of iterator to not take into account of the depth for iterators in end state.
601288f
to
8af7753
Compare
BTW, why are we breaking API without first deprecating it? I think we should keep parametrized versions for several releases. |
IIRC I introduced the parameterized version in this development stage. It never saw a public release. Or did I overlook something? Edit: Yep, just confirmed it. ABI Laboratory is reporting 100% between this current version and 1.8.1 for libpcl_octree. Supposedly it compiled the master branch on 2018-01-04 12:55, |
But parametrized versions have been around like... forever. Here is how |
The
|
Sorry, apparently I need a second coffee this morning. Everything is alright indeed. |
Only... why do we have the "Breaks API" tag then? |
Well... if you see it individually it breaks the API of the "current snapshot", the same way the parametrization I introduced before broke the ABI. When all changes are combined together, it no longer does. So the question is what is the policy we want to apply in these cases? I'm perfectly OK with both options (having/not having the API breakage tag) and we can always create more tags to provide more information in cases as special as this one. |
I think that the tags are supposed to help us put together a changelog. And in the changelog we list cumulative changes with respect to the previously released version. Whatever happened during the development stage does not really matter. E.g. if we introduced a bug and the fixed it, the world does not need to know about this, right? Same for API changes that were introduced and then removed. |
I'll tag with this in mind from now on. |
I'm removing the |
I add an octree test to check the behavior of current iterator with a 'for loop' (which is the main usage in reality I think). This test curently fails. In the second for loop, I got this message:
I think that the iterator goes over every node of depth egal to 0 and 1, as expected, but it is never equal to the end iterator. If you look at the source:
pcl/octree/include/pcl/octree/octree_iterator.h
Lines 131 to 139 in 6d4c5c8
to be equal, two iterators must have the same
max_octree_depth
value. I'm not sure checking that is fair. When you look at the creation of the end iterator:pcl/octree/include/pcl/octree/octree_base.h
Lines 118 to 121 in 6d4c5c8
the default
max_depth_arg
is 0, so max depth of the end iterator will be the depth of the octree by default. So in a for loop, when one specifies a max depth inferior to the depth of an octree, the exit condition will never match.Proposition
max_octree_depth_ == other.max_octree_depth_
max_depth_arg
for the end iterators, it is not necessary