-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
Conversation
…late <typename U> iter_impl. iter_impl has operator const_iterator to create an const_iterator from an iterator.
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.
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"); | ||
|
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.
Why not move this into the template specification std::enable_if<...>
?
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.
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.
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.
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>>
.
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.
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, |
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.
Can't you use typename U::pointer
?
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 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
.
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 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, |
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.
Same as above - why not use typename U::reference
?
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.
Same as 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.
Same as above.
Thanks! |
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.