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

Replace class iterator and const_iterator by using a single template class to reduce code. #395

Merged
merged 2 commits into from
Dec 14, 2016

Conversation

Bosswestfalen
Copy link

Class iterator and const_iterator can be merged by a single template class.
Currently the classes differ by aliases. This can be handled by the template parameter.
Const_iterator can be created using an iterator. Iterator cannot be created from a const_iterator.
This can be achieved by a conversion function in the template class.

…late <typename U> iter_impl. iter_impl has operator const_iterator to create an const_iterator from an iterator.
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.

If the tests succeed, I am very impressed! I added some questions where I think the code can be even more refined.

static_assert(std::is_same<U, basic_json>::value
or std::is_same<U, const basic_json>::value,
"iter_impl only accepts (const) basic_json");

Copy link
Owner

Choose a reason for hiding this comment

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

Why not move this into the template specification std::enable_if<...>?

Copy link
Author

Choose a reason for hiding this comment

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

When U is not (const) basic_json this will give a more informative error message. Unfortunately you do not notice this requirement just by looking at the head of the class.

In fact it can be moved to the specification.

Copy link
Owner

Choose a reason for hiding this comment

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

As the iterators are only defined inside the basic_json class, I think it's OK to skip the error message and move it to the specification. The code could maybe even simplified by using std::is_same<U, std::remove_cv<basic_json>>.

Copy link
Author

Choose a reason for hiding this comment

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

Should be std::is_same<std::remove_cv<U>, basic_json>. But yes, this looks much better than my 3 lines above.

public:
/// the type of the values when the iterator is dereferenced
using value_type = typename basic_json::value_type;
/// a type to represent differences between iterators
using difference_type = typename basic_json::difference_type;
/// defines a pointer to the type iterated over (value_type)
using pointer = typename basic_json::const_pointer;
using pointer = typename std::conditional<std::is_const<U>::value,
Copy link
Owner

Choose a reason for hiding this comment

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

Can't you use typename U::pointer?

Copy link
Author

Choose a reason for hiding this comment

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

I am not familiar with allocators. My understanding is that std::allocator_traits<allocator_type>::pointer; (line 260) using AllocatorType</* no const */ basic_json> (line 257), is never const. So I did not test it. If I#m wrong I'd prefer typename U::pointer.

Copy link
Owner

Choose a reason for hiding this comment

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

You were right: const_iterator should have a const pointer, see http://en.cppreference.com/w/cpp/iterator/iterator_traits.

/// defines a reference to the type iterated over (value_type)
using reference = typename basic_json::const_reference;
using reference = typename std::conditional<std::is_const<U>::value,
Copy link
Owner

Choose a reason for hiding this comment

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

Same as above - why not use typename U::reference?

Copy link
Author

Choose a reason for hiding this comment

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

Same as above.

Copy link
Owner

Choose a reason for hiding this comment

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

Same as above.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 92e28c3 on Bosswestfalen:develop into 2f94c30 on nlohmann:develop.

@nlohmann nlohmann merged commit fe00b36 into nlohmann:develop Dec 14, 2016
@nlohmann nlohmann self-assigned this Dec 14, 2016
@nlohmann nlohmann added this to the Release 2.0.9 milestone Dec 14, 2016
@nlohmann
Copy link
Owner

Thanks!

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