C++ Logo

std-proposals

Advanced search

Re: Container.iterator_to for getting an iterator form the reference to value

From: Ion Gaztañaga <igaztanaga_at_[hidden]>
Date: Fri, 14 Aug 2020 17:07:38 +0200
On 13/08/2020 16:58, Arthur O'Dwyer via Std-Proposals wrote:
>
> To implement `iterator_to` for anything except `vector`, you have to
> rely on a cast like this:
>
> struct Node {
> T t;
> Node *next;
> };
> Node *node_from_t(T *t) {
> return reinterpret_cast<Node *>(t);
> }
> int main() {
> Node n;
> assert(node_from_t(&n.t) == &n);
> }

Right. Boost.Intrusive can skip UB using what is called "base hooks", as
value_type is the whole node and the iterator can point to the base
part, which contains the "next" field.

https://www.boost.org/doc/libs/1_74_0/doc/html/intrusive/usage.html#intrusive.usage.usage_base_hook

Something like:

struct Hook {
    Hook *next;
};

struct Node //aka value_type in Intrusive
  : public Hook {
      T t;
};

obtaining a pointer to the hook (which is what a iterator stores is) a
simple upcasting.

However, UB is used with "member hooks" trying to get the inverse
operation of a pointer to data member (given a pointer to a member and a
pointer to data member, obtain a pointer to the parent):

https://www.boost.org/doc/libs/1_74_0/boost/intrusive/parent_from_member.hpp

used here to do the "to_node_ptr" operation, which is the base of
"iterator_to":

https://www.boost.org/doc/libs/1_74_0/boost/intrusive/member_value_traits.hpp

Given some restrictions, (like no supporting virtual inheritance
reversal, which parent_to_member does not support and might be difficult
to implement) I think a language feature to implement
"parent_from_member" legally would be useful in more use-cases than
Boost.Intrusive and "iterator_to".

Best,

Ion

Received on 2020-08-14 10:11:05