|
Boost : |
From: Gordon Woodhull (gordon_at_[hidden])
Date: 2008-06-26 23:32:00
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.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk