[fusion] how to implement fusion_map_from_element for [intrusive]?

Hello, I am hoping to contribute an extension for intrusive to handle fusion containers, so that an intrusive hook can be an element in a fusion container and a fusion container can be an item in an intrusive container. To state more clearly: the adapter will allow fusion containers to "carry membership" in intrusive containers. (like an aclu card ;-) In order to do this, intrusive needs some way to get a pointer to a fusion container from a pointer to a fusion container element. My strategy is to write functions e.g. intrusive::detail::fusion_map_from_element, fusion_vector_from_element, etc., with template parameters for the fusion container type and the index or key, and use/adapt the functions in boost/intrusive/detail/parent_from_member.hpp which hide all the scary pointer arithmetic and compiler-specific stuff. I'll then need to sum up the offsets in a chain of pointers to members, as I explain next. I've attached a first attempt. vector_pointer_to_member successfully fetches a pointer to member for fusion::vector##<>, without having to make any changes to fusion. It's not pretty or good practice, but it works. With this I would be able to write the adapter for vector##<>, as shown partly in fusion_container_from_element.hpp, but this doesn't work for fusion::vector<> itself, never mind fusion::map, because vector## is a private member of vector<> which is a private member of map<>, as it should be. I think I will need to make a change to fusion itself to return a chain of pointers-to-members, and I'm wondering what's the best way to do this. 0. Am I overlooking a simpler solution? 1. I'd like to add this functionality to fusion without changing the public interface. Does this sound reasonable? There would have to be a few unadvertised member {meta}functions, and then perhaps a few free functions in fusion::detail with ugly long names such as chain_of_pointers_to_members_of_element_in_map. Rationale for hidden interface: I can't think of any other legitimate reason why anyone would want pointer/offset-to-member, it totally breaks the nice fusion abstraction, and it is only going to be safe in situations where you know for sure that the element is contained in the container you claim it's in. Intrusive can guarantee safety here because you always insert the full object; it only needs to cast from part to whole internally; and clients are usually unaware of the weird casts. 2. The chain of pointers to members is an oddity I haven't seen before - does anybody know of any implementations? I am thinking to use an mpl sequence of types to generate a sequence one shorter of pointer-to- member types. I hope to also put the pointer-to-member _values_ in an mpl sequence and calculate offsets at compile time. An alternative implementation, simpler in some ways, is to calculate the offset recursively and not use a chain of pointers to members, but I don't like it because offsets are gross and everyone would have to call offset_from_pointer_to_member. OTOH, I don't know of any other use for a chain of pointers to members except for finding offsets! 3. As with parent_from_member, map_from_element isn't specific to intrusive, but I don't know of any other uses and it's slightly dangerous, so it should probably stay in boost::intrusive::detail. Any ideas? Thanks, Gordon P.S. Obviously this technique will only work for contiguous fusion containers, not views.

Gordon Woodhull wrote:
Hello,
I am hoping to contribute an extension for intrusive to handle fusion containers, so that an intrusive hook can be an element in a fusion container and a fusion container can be an item in an intrusive container.
I have no idea about fusion, but you propose adding fusion_container_from_element to Intrusive, right? Correct me if I'm wrong, but I understand from the code that you first obtain the an iterator to an ElementKey (a type) of the map and then obtain a pointer to member to that element type inside the fusion container. Then you use offset_from_pointer_to_member function of Intrusive to obtain a pointer to the map. I was thinking if offset_from_pointer_to_member could be pushed to somewhere more Boost libraries can use (to boost/detail perhaps?) and avoid having fusion<->intrusive dependencies. Then we can add fusion_container_from_element to Fusion.
Thanks, Gordon
Regards, Ion

On Jun 29, 2008, at 5:03 AM, Ion Gaztañaga wrote:
Gordon Woodhull wrote:
Hello, I am hoping to contribute an extension for intrusive to handle fusion containers, so that an intrusive hook can be an element in a fusion container and a fusion container can be an item in an intrusive container.
I have no idea about fusion, but you propose adding fusion_container_from_element to Intrusive, right? Correct me if I'm wrong, but I understand from the code that you first obtain the an iterator to an ElementKey (a type) of the map and then obtain a pointer to member to that element type inside the fusion container. Then you use offset_from_pointer_to_member function of Intrusive to obtain a pointer to the map.
Yes - that's what this code almost implements, except that the class template for which I'm able to get pointer-to-member is buried as private members a couple of layers deep, so it doesn't quite work.
I was thinking if offset_from_pointer_to_member could be pushed to somewhere more Boost libraries can use (to boost/detail perhaps?) and avoid having fusion<->intrusive dependencies. Then we can add fusion_container_from_element to Fusion.
That makes lots of sense to me - there are a few other uses for parent_from_member and container_from_member that definitely "ignore" C ++'s nice abstraction facilities but are nonetheless useful. "Overloading fields" with get/set methods on the parent class with zero overhead, for example. Black arts that can be made safe with some metaprogramming. (Doesn't necessarily make them always a good idea.) I'll just keep an image of changed/added files from intrusive, fusion, and detail in sandbox/metagraph since this is for that. And I'll post again when there's something for people to look at. Cheers, Gordon
participants (2)
-
Gordon Woodhull
-
Ion Gaztañaga