Skip to content
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

Issue #593 Fix the arithmetic operators in the iterator and reverse iterator #595

Merged
merged 14 commits into from
Jun 10, 2017
Merged

Issue #593 Fix the arithmetic operators in the iterator and reverse iterator #595

merged 14 commits into from
Jun 10, 2017

Conversation

HenryRLee
Copy link
Contributor

Changes include:

  1. Override operator+(difference_type, const iter_impl&) in the iterator class
    
  2. Add const qualifier in the member operator+(difference_type) function
    
  3. Add test cases of the relevant issue
    

@HenryRLee HenryRLee changed the title Override operator+(n, iterator) in the iterator class Issue #593 Override operator+(n, iterator) in the iterator class May 27, 2017
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.03%) to 99.686% when pulling ed62129 on HenryRLee:iterator_arithmetic into 52adf3f on nlohmann:develop.

@HenryRLee
Copy link
Contributor Author

The travis test exceeded 10 mins time limit, but it seems that the other tests also took around 10 mins. Shall we extend the time limit a little?

As for the AppVeyor fail, I think it's a result of one previous PR before mine.

I really don't know what the coveralls is about. Is there a test report I can read?

@HenryRLee
Copy link
Contributor Author

HenryRLee commented May 29, 2017

The latest several commits are fixing the incorrect arithmetic operations in reverse iterator.

The changes include:

  1. Change the implementation of the arithmetic operators to using the result from the base class (std::reverse_iterator<T>) directly
  2. Change the incorrect test cases

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.03%) to 99.686% when pulling 3aef1a5 on HenryRLee:iterator_arithmetic into 52adf3f on nlohmann:develop.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.03%) to 99.686% when pulling e42db27 on HenryRLee:iterator_arithmetic into 52adf3f on nlohmann:develop.

@HenryRLee
Copy link
Contributor Author

HenryRLee commented May 29, 2017

The exception message checking has been commented out. Although most compilers implements the operator[] of reverse iterator using operator+, some are still using operator[] from the original iterator class. That makes the exception message unpredictable.

@HenryRLee
Copy link
Contributor Author

HenryRLee commented May 29, 2017

The other commit is adding some missing test cases for the n + iter operator.
It explicitly calls the iterator constructor during the checking, otherwise the CHECK macro doesn't understand the expression. In normal uses, the iterator constructor can be omitted.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 99.721% when pulling 0c2ed00 on HenryRLee:iterator_arithmetic into 52adf3f on nlohmann:develop.

@HenryRLee HenryRLee changed the title Issue #593 Override operator+(n, iterator) in the iterator class Issue #593 Fix the arithmetic operators in the iterator and reverse iterator May 29, 2017
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.0003%) to 99.72% when pulling daea213 on HenryRLee:iterator_arithmetic into 52adf3f on nlohmann:develop.

@nlohmann
Copy link
Owner

nlohmann commented Jun 5, 2017

@HenryRLee Could you please merge the current develop branch so the AppVeyor tests have a chance to succeed?

Copy link
Owner

@nlohmann nlohmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @HenryRLee, I have some question on the changes.

}
{
auto it = j_null.crbegin();
CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
//CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you uncomment this line again and change the test case to fit the actual exception message?

@@ -841,15 +873,15 @@ TEST_CASE("iterators 2")
auto it = j_null.rbegin();
CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
//CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you uncomment this line again and change the test case to fit the actual exception message?

CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
//CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
//CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you uncomment this line again and change the test case to fit the actual exception message?

CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
//CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.214] cannot get value");
//CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.214] cannot get value");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you uncomment this line again and change the test case to fit the actual exception message?

CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
//CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
//CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you uncomment this line again and change the test case to fit the actual exception message?

}
{
auto it = j_object.crbegin();
CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
//CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you uncomment this line again and change the test case to fit the actual exception message?

CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
//CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
//CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you uncomment this line again and change the test case to fit the actual exception message?

@@ -801,15 +833,15 @@ TEST_CASE("iterators 2")
auto it = j_object.rbegin();
CHECK_THROWS_AS(it[0], json::invalid_iterator);
CHECK_THROWS_AS(it[1], json::invalid_iterator);
CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
CHECK_THROWS_WITH(it[1], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
//CHECK_THROWS_WITH(it[0], "[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you uncomment this line again and change the test case to fit the actual exception message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far, there is no such an expression can pass all compilers. I tested with the original message and passed most of the travis test, but a few MS compilers were using [] to implement the [] in the reverse iterator, leading to another version exception output.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also put a comment in the end of #593, suggesting replacing the exception with a linear time implementation. If you think it's OK, I'll fix it right away.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how to retrieve the test log and show you. Basically, the original exception message passed is matched in most test machines, but three of them were printing 'cannot use operator[] for object iterators'. I also made an explanation in a comment after commit 0c2ed00.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for the replacement, I described in #593 (comment) why I think this is not a good idea.

About the error messages: I do not understand why different machines would throw different exceptions. This makes no sense and wasn't like this before. Do you have an idea about the reasons?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for two different exception message is, I changed the implementation of operator [] in the reverse iterator to calling the operator [] from std::reverse_iterator directly.

         /// access to successor
         reference operator[](difference_type n) const
         {
-            return *(this->operator+(n));
+            return base_iterator::operator[](n);
         }

Therefore the behavior depends on the implementation of the operator[] in std::reverse_iterator, which varies by compiler. Most of the compiler implements it using operator-, but a few others uses operator[].

Since you have disapproved that replacing exceptions with linear time implementation, I guess I have to revert my changes in this function to pass the test.

@@ -307,6 +317,7 @@ TEST_CASE("iterators 2")
auto it = j_array.begin();
it += 3;
CHECK((j_array.begin() + 3) == it);
CHECK(json::iterator(3 + j_array.begin()) == it);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason the addition is written the other way?

Copy link
Contributor Author

@HenryRLee HenryRLee Jun 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a required operation in a random accessible iterator. Please check: http://en.cppreference.com/w/cpp/concept/RandomAccessIterator

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh stupid me... I didn't see you added a line - I thought you changed the line to this order...

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.0003%) to 99.721% when pulling c98169d on HenryRLee:iterator_arithmetic into 1a9d766 on nlohmann:develop.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.0003%) to 99.72% when pulling 6661ec7 on HenryRLee:iterator_arithmetic into 92ef196 on nlohmann:develop.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.0003%) to 99.722% when pulling e12c2ee on HenryRLee:iterator_arithmetic into 52f934c on nlohmann:develop.

@HenryRLee
Copy link
Contributor Author

HenryRLee commented Jun 9, 2017

Hi Niels, I think this PR is ready for review. This one is supposed to be bug fixing and adding missing operators. As for the improvement at the end of #593, I can create another PR some other time if that's needed.

@nlohmann nlohmann self-assigned this Jun 10, 2017
@nlohmann nlohmann added this to the Release 3.0.0 milestone Jun 10, 2017
@nlohmann nlohmann merged commit 6caad48 into nlohmann:develop Jun 10, 2017
@nlohmann
Copy link
Owner

Thanks a lot. We shall continue the discussion in #593.

nlohmann added a commit that referenced this pull request Jun 10, 2017
@HenryRLee
Copy link
Contributor Author

Thank you as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants