This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

why does iter_swap internally test for reference being value_type&?


Hi everybody,

I think there is a well thought of reason behind the code, so maybe you
can help me achieve enlightenment on this issue.

I stumbled across the following piece of code in the implementation of
iter_swap in bits/stl_algobase.h

std::__iter_swap<
    __are_same<_ValueType1, _ValueType2>::__value
 && __are_same<_ValueType1&, _ReferenceType1>::__value
 && __are_same<_ValueType2&, _ReferenceType2>::__value
>::iter_swap(__a, __b);

if the meta expression evaluates to true, iter_swap will call swap
(*__a,*__b), else
move semantics are used.

The comment of the code pointed me to this older discussion which was
allready a good read:
http://gcc.gnu.org/ml/libstdc++/2004-08/msg00167.html

But there only a check for the equalness of value_type of the iterators
was mentioned.
Not that the reference should be equal to value_type&

Since in the discussion std::vector<bool> was explicitely mentioned, i
will base my
following points on this :)

let's assume in the following:
typedef std::vector<bool>::reference Reference;

I think the argument behind this implementation of iter_swap was that
there might not
exist an implementation of swap(Reference,Reference). In which case

Reference refA = *__a;
Reference refB = *__b;
swap(refA,refB)

would result in a call to std::swap which swaps the references and not the
values behind
it. But in the current implementation which is

swap(*__a, *__b);

this is not possible since in this case, the argument types would be const
Reference&
for which std::swap would fail. But if the user would now overload

void swap(Reference, Reference);

The correct swap can be found and there is no silent breakage of code. I
don't think
that the latter is a big requirement - especially when the requirements
for the iterators
of iter_swap only allow forward iterators for which Reference must be at
least convertible to
T&(when i understand forward iterator correctly). So when

swap(*__a,*__b);

fails during compilation this is because the iterators are not standard
conformant.

Given that the argument is correct, i would advocate the following
implementation:

std::__iter_swap<
    __are_same<_ReferenceType1, _ReferenceType2>::__value
>::iter_swap(__a, __b);

Greetings from Germany,
Oswin Krause


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]