On 13/04/15 16:14 +0200, Marc Glisse wrote:
On Mon, 13 Apr 2015, Jonathan Wakely wrote:
On 13/04/15 13:42 +0200, Marc Glisse wrote:
this patch makes std::distance(list.first(),list.end()) a constant
time operation when optimizing, with no penalty for other calls.
We could do the test always (no __builtin_constant_p) but then it
will add a small runtime penalty for other calls, someone else can
take responsibility for that.
I like the way you've done it. No penalty for other calls is great
and IMHO it's OK that the optimisation only happens when optimising.
(Does it work even at -Og?)
No, the testcase currently passes with -O1 but not -Og.
OK, we can live with that.
Sadly, that node is going to look even stranger when I finish adding
support for C++11 allocators, as the type of node becomes dependent on
the allocator's pointer, which makes _List_node<size_t> much more
complicated :-(
But then I assume _List_node_base is the part really getting more
complicated, so without looking too closely it seems almost
orthogonal.
In order to avoid making any changes to std::list<T, std::allocator<T>>
I'm adding an entire parallel hierarchy of a new node base type
(parameterized on the allocator's void_pointer type), a new node type
and new iterators (parameterized on the pointer type), which will only
be used when !is_pointer<Alloc::pointer>. So it will just mean adding
two new overloads for the two new iterator types.
Not a big deal, as long as I remember to do it :-)
This should still be a qualified call to std::__distance, otherwise the
compiler might end up instantiating things to figure out if there are
any associated namespaces, e.g. for vector<unique_ptr<T>>::iterator we
don't want to know T's base classes and rheir associated namespaces.
Then the approach will not work. C++ overload resolution will not
consider the later __distance declarations in stl_list.h if the call
is qualified (I didn't change it gratuitously).
Ahhh, yes, of course.
A forward declaration
of list iterators and those __distance overloads in
bits/stl_iterator_base_funcs.h is not very appealing but may work (or
it may cause issues, I don't know). Otherwise, I guess we are back to
creating a new file bits/list_iterator.h, which <list> includes if
<iterator> has already been included and vice versa, and which
provides overloads for distance directly.
I don't have a preference, but I think the forward declarations should
work without problems. <list> includes bits/stl_iterator_base_funcs.h
so if the forward declarations didn't match the definitions for some
reason we'd know right away.