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
>
> 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