[llvm] r207069 - [ADT] Add a generic iterator utility for adapting iterators much like
Duncan P. N. Exon Smith
dexonsmith at apple.com
Thu Apr 24 20:11:59 PDT 2014
On 2014-Apr-24, at 13:37, David Blaikie <dblaikie at gmail.com> wrote:
> On Thu, Apr 24, 2014 at 1:24 PM, Chandler Carruth <chandlerc at gmail.com> wrote:
>>
>> On Thu, Apr 24, 2014 at 1:16 PM, David Blaikie <dblaikie at gmail.com> wrote:
>>>
>>>> +/// \brief An iterator type that allows iterating over the pointees via
>>>> some
>>>> +/// other iterator.
>>>> +///
>>>> +/// The typical usage of this is to expose a type that iterates over
>>>> Ts, but
>>>> +/// which is implemented with some iterator over T*s:
>>>> +///
>>>> +/// \code
>>>> +/// typedef pointee_iterator<SmallVectorImpl<T *>::iterator>
>>>> iterator;
>>>> +/// \endcode
>>>> +template <
>>>> + typename WrappedIteratorT,
>>>> + typename T = typename std::remove_pointer<
>>>> + typename
>>>> std::iterator_traits<WrappedIteratorT>::value_type>::type>
>>>
>>> Just as a strawman, how do you feel about:
>>>
>>> template <typename WrappedIteratorT, typename T =
>>> decltype(**std::declval<WrappedIteratorT>())>
>>>
>>> I /think/ your version doesn't work for smart pointers, does it?
>>> (judging by http://en.cppreference.com/w/cpp/types/remove_pointer )
>>> and this version should.
>>
>>
>> Entertainingly, I almost used the version you posted prior to getting
>> std::remove_pointer to work.
>>
>> I feel strongly that pointee_iterator should work with smart pointers, and
>> I'm somewhat bummed that std::remove_pointer doesn't work.
>>
>> How about a slight variation: T =
>> decltype(*std::declval<WrappedIteratorT::value_type>())
>
> Are there cases you have in mind where this would be more
> appropriate/effective/correct than what I've suggested?
>
> In the case where the underlying iterator lies about its value type
> (such that the value type differs from the result of operator*) we're
> not going to get the desired behavior - at best the types will
> mismatch and the pointee_iterator's operator* will fail to compile,
> right? (since it's applying * to the result of the underlying
> iterator's op*, not to the value type (in the case where they're
> different)).
I agree that David's version is safer.
> Seems more terse and more correct to have the type basically match the
> expression in the op*.
>
> But I'm not entirely confident here - the sorts of shenanigans people
> might have going on with iterator traits and mismatched
> value/reference/pointer types are something I try not to dwell on, as
> a rule. They make me sad.
I sure wish Boost's iterator concepts [1] were in C++11. I think using `value_type`
as `reference` is a legitimate use case (as is `vector<bool>::iterator`), and it's
frustrating not to have STL support for it.
[1]: http://www.boost.org/doc/libs/1_55_0/libs/iterator/doc/new-iter-concepts.html
More information about the llvm-commits
mailing list