[intrusive] list compatibility with existing application-defined intrusive lists

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[intrusive] list compatibility with existing application-defined intrusive lists

Boost - Users mailing list
Hi all,

boost::intrusive lists can be easily customized to be compatible with an existing doubly-linked intrusive list implementation, such as the one used in the linux kernel (struct list_head). Indeed, I have been able to declare and use a boost::intrusive::list of my own with custom traits that uses struct list_head as the underlying representation, enabling me to simply use .end().pointed_node() to get access to the list head and pass it to legacy C code that expects a struct list_head*. However, I can't think of a way to achieve interoperability in the opposite direction.

For example, I have an existing function (to be precise, a callback that I pass to legacy C code), that accepts a struct list_head* that is expected to contain a list of elements of a certain type. I want some way to "wrap" this raw pointer in a type-safe intrusive list type that I use as naturally as a boost::intrusive::list (iteration, modification, etc.). I see no way to achieve this.

The way I see it, what I need is a boost::intrusive::list_ptr, a container that doesn't actually own the list head, but rather, points to a list head stored elsewhere. It would have the same interface as a list, allowing me to push_back, clear, etc., but behaves as a pointer when it comes to moves and copies. Additionally, there should also be a boost::intrusive::const_list_ptr, which will not allow me to modify the list, but still allows iteration and other non-modifying operations.

Unless, of course, there are already existing mechanisms to achieve this. If anyone has any ideas, please let me know.

Thanks.


_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [intrusive] list compatibility with existing application-defined intrusive lists

Boost - Users mailing list

Hi,


maybe it's possible to "creatively" use the three-argument version of circular_list_algorithms::transfer. Create an empty intrusive::list, and use transfer on the "other" list as the source. It's a constant-time operation that will relink the nodes from the "other" list to the empty intrusive::list. When you're done with the list, use transfer to perform the inverse operation.


Of course, this temporarily changes the original list. If this is a no-go, I see no other way than either just using circular_list_algorithms directly (poorer interface than list) or writing your own wrapper.




From: Boost-users <[hidden email]> on behalf of Rahul Ramadas via Boost-users <[hidden email]>
Sent: Saturday, February 3, 2018 9:42 PM
To: [hidden email]
Cc: Rahul Ramadas
Subject: [Boost-users] [intrusive] list compatibility with existing application-defined intrusive lists
 
Hi all,

boost::intrusive lists can be easily customized to be compatible with an existing doubly-linked intrusive list implementation, such as the one used in the linux kernel (struct list_head). Indeed, I have been able to declare and use a boost::intrusive::list of my own with custom traits that uses struct list_head as the underlying representation, enabling me to simply use .end().pointed_node() to get access to the list head and pass it to legacy C code that expects a struct list_head*. However, I can't think of a way to achieve interoperability in the opposite direction.

For example, I have an existing function (to be precise, a callback that I pass to legacy C code), that accepts a struct list_head* that is expected to contain a list of elements of a certain type. I want some way to "wrap" this raw pointer in a type-safe intrusive list type that I use as naturally as a boost::intrusive::list (iteration, modification, etc.). I see no way to achieve this.

The way I see it, what I need is a boost::intrusive::list_ptr, a container that doesn't actually own the list head, but rather, points to a list head stored elsewhere. It would have the same interface as a list, allowing me to push_back, clear, etc., but behaves as a pointer when it comes to moves and copies. Additionally, there should also be a boost::intrusive::const_list_ptr, which will not allow me to modify the list, but still allows iteration and other non-modifying operations.

Unless, of course, there are already existing mechanisms to achieve this. If anyone has any ideas, please let me know.

Thanks.


_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [intrusive] list compatibility with existing application-defined intrusive lists

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On 03/02/2018 21:42, Rahul Ramadas via Boost-users wrote:

> For example, I have an existing function (to be precise, a callback that
> I pass to legacy C code), that accepts a struct list_head* that is
> expected to contain a list of elements of a certain type. I want some
> way to "wrap" this raw pointer in a type-safe intrusive list type that I
> use as naturally as a boost::intrusive::list (iteration, modification,
> etc.). I see no way to achieve this.
>
> The way I see it, what I need is a boost::intrusive::list_ptr, a
> container that doesn't actually own the list head, but rather, points to
> a list head stored elsewhere. It would have the same interface as a
> list, allowing me to push_back, clear, etc., but behaves as a pointer
> when it comes to moves and copies. Additionally, there should also be a
> boost::intrusive::const_list_ptr, which will not allow me to modify the
> list, but still allows iteration and other non-modifying operations.
>
> Unless, of course, there are already existing mechanisms to achieve
> this. If anyone has any ideas, please let me know.

There is no way to do it with containers, you could use node algorithms
directly. On the other hand there is some undocumented support to have a
different header holding policy (header_holder_type), but it assumes the
the header holder internally holds the header node (allocating it
dynamically or by any other mechanism). There is no interface to modify
this header holder to, say, set the a pointer to the header node.

In any case, I think having the possibility to hold the header node
externally it's a useful extension to Boost.Intrusive.

Best,

Ion
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users