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]

Re: [libstdc++/61347] std::distance(list.first(),list.end()) in O(1)


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.


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