[squid-dev] [PATCH] SBuf const iterator fixes

Amos Jeffries squid3 at treenet.co.nz
Mon Feb 8 20:25:44 UTC 2016


On 9/02/2016 8:38 a.m., Kinkie wrote:
> On Mon, Feb 8, 2016 at 8:15 PM, Alex Rousskov
> <rousskov at measurement-factory.com> wrote:
>> On 02/08/2016 11:18 AM, Amos Jeffries wrote:
>>> The SBufIterator is mostly actually a const iterator. But not quite.
>>
>> I am not sure I understand what you are implying because you did not
>> change any const-related aspects of SBufIterator. What are the
>> requirements for being a "const iterator" class that old SBufIterator
>> violated?
> 
> It behaves like a const while not being explicitly so.
> You can't do
> auto i = sbuf.begin();
> *i = 'a';
> 
>>> The point of difference from const_iterator is the operator*() API which
>>> is also different from the normal itertor API in that is returns a char
>>> instead of a char& or const char &.
>>
>> Please explain why returning char is wrong for const_iterator. I
>> understand that [all?] standard iterators return a reference, and I also
>> understand that a non-const iterator cannot return a char, but I do not
>> yet understand how that difference affects constant SBufIterator.
> 
> It behaves the same,but it's a different API.

With some auto-magic differences resulting from that.

The char return is a temporary copy that the compiler can apply move
semantics to. Whereas a reference is not - new objects from it must be
copy-constructed.

Also, non-const iterators can have reference taken to the iter[] member
and not to the 'stack' temporary - if anything were actually using
iterators that way we would get into trouble.

eg. roughly like so (this fails only due to our c_str())

  auto itr = string.begin()
  char *foo = &*itr;
  assert(strcmp(foo, string.c_str()) == 0);



> 
>> Overall, it feels like returning a simple "char" may be more efficient
>> than forcing the compiler to optimize away references to "char", but I
>> may be missing something important here.
> 
> WRT the const iterator, yes. But the iterator should return a char
> referente, and COW on access which is tricky.

And as it turns out we dont need non-const iterator at this point. So I
have not even bothered to make this implement both. Just adjusted it to
an STL consistent API, and called it such.


> 
>>> This has side effects on the reverse iterator and SBuf begin/end
>>> methods. Which are also const'ified.
>>
>> Please note that in the C++11 land, we are supposed to use
>> cbegin/cend/etc. methods if we unconditionally want a const_iterator.
>> These are added to the old set of begin/end/etc. methods (half of those
>> old methods return const_iterators, depending on the object constness
>> rather than method name):
> 
> nod. so far we are only reading from iterators.


For some reason the GCC range-for loop requires begin()/end() for its
expansion. Even when "const auto" is used explicitly.

"
tests/testRFC3986.cc:60:5:   required from here
anyp/Rfc3986.h:67:5: error: ‘begin’ was not declared in this scope
     for (const auto c : s) {
     ^
"


So I have just converted the begin/end methods of SBuf to be the C++11
const form, omitting the non-const and c*() variants.

If you would like the c*() methods added I am okay with doing that on
commit. We just dont use them, so it seems pointless extra code right now.

Amos



More information about the squid-dev mailing list