Hooks for "smart" elements - c++

Is there any simple/elegant way in C++11, via STL or boost, to make an element-type "smart" so that an instance of it always knows which container it belongs to and has member functions for a sort of "auto-removal" which also takes care of updating the container it is part of?
The real case is that I have a callback C-function (from a C library) being called after a given request has been completed. This function accepts a raw pointer to the element which has been processed. Now what I want is to remove this element from the list it belongs to and move it to another list.
I know I could store a pointer to the container in the element itself and when the callback is called I could iterate over that container until I find the element, then remove it and call newlist.push_back(object). Given that one element must live in one container (and only one), I wonder if there's something more elegant.

Boost's intrusive containers implement that functionality.
This requires specific containers as well as objects specifically designed to work with the containers, however.

Related

Deleting STL-container element via iterator only

Is there a way to delete an element from an STL container (be it list, vector, ...) only via an iterator pointing to the element to be deleted, but without providing the container object it resides in (i.e. without directly using the container memberfunction container<T>::iterator container<T>.erase(container<T>::iterator)?
(Follow-up to this question)
No, this is not possible.
Imagine what would have to happen in order for the standard to provide a way to do this. std::vector<T>::iterator could not be a simple T*. Instead it would have to contain enough information for the library to be able to "find" the vector to which it belongs, such as a pointer to the vector itself. Thus, if the standard imposed a requirement to make it possible to delete an element given only an iterator, it would force the standard library to add overhead that would slow down all users of the container.

Confusion about one element in more boost::intrusive containers

I don't quite understand how it is possible that the same elements can appear in different intrusive containers while preserving the performance and memory usage guarantees that the boost::intrusive documentation states.
The documentation says that:
an intrusive container does not store copies of passed objects, but it
stores the objects themselves. The additional data needed to insert
the object in the container must be provided by the object itself. For
example, to insert MyClass in an intrusive container that implements a
linked list, MyClass must contain the needed next and previous
pointers:
class MyClass
{
MyClass *next;
MyClass *previous;
// ...
};
When underlining the differences between STL and boost::intrusive containers, the documentation also says:
A non-intrusive container has some limitations:
An object can only belong to one container: If you want to share an object between two containers, you either have to store multiple
copies of those objects or you need to use containers of pointers:
std::list<Object*>.
Makes sense, an element can't be in two std::lists. Okay. But how can one instance of type MyClass be inserted in two different boost::intrusive::list 's, for example, considering that such an element can only have one pointer to the next element and one to the previous element. If I am not wrong, this only works if you assume that modifying one container might also modify the other one and vice-versa.
The Boost.Intrusive library doesn't litterally ask you to define prev and next pointers -- in that part of the documentation, the presence of prev and next pointers is merely a conceptual illustration of how intrusive containers work.
The actual of defining intrusive containers is to include a hook through inheritance or as a member that contains the prev and next pointers. By including several hooks (tagged with different static types), you can include the same object in several differnet intrusive containers (each tagged with different static types).
See http://www.boost.org/doc/libs/1_38_0/doc/html/intrusive/usage.html to see how the hooks work. See this StackOverflow answer for an example of how to do this with multiple intrusive contianers.
This has some limitations -- you can't include your objects in an arbitrary set of multiple intrusive containers defined at runtime -- you have to know what containers you want to use when you're coding them initially, and build knowledge of each one into your objects.

container to zip other containers

I need a container, that wraps other containers and makes them traversible like a zip_iterator, but also wraps their other functions (like push_back(), size(), ...). Is there something like this in the stdlib or boost?
Background:
I have a class that stores a polymorphic base class in a boost::ptr_list<BaseClass> but needs some more information to be stored alongside this. With an normal std::list I would just do std::list<std:pair<BaseClass, OtherInformation> > and am done, but I want the pointer management of boost::ptr_list.
The obvious solution I came up with is: Have two containers boost::ptr_list<BaseClass> and std::list<OtherInformation>. This solves the problem but leaves me with always handling two containers instead of one (which also invites inconsistencies between the containers).
So I am searching for a wrapper that will wrap two (or an arbitrary number of) containers and makes them accessible like one, that stores a tuple of the data.
To summarize:
Either I need a container that does this, then I would like to know if there is already one or if I have to implement it my self (which I would consider some fun :).
Or the solution I thought of is the wrong way to go, then please tell me the alternatives.

Changing a Container while using Visitor

I implemented the Visitor pattern in C++ using a STL-like iterator for storing the Visitor's current position in the container. Now I would like to change the container while I iterate over it, and I'm especially interested in deleting items from the container, even the one I'm currently visiting.
Now obviously this will invalidate the Visitors internal iterator, because it was pointing to exactly this item. Currently, I store a list of all iterators in the container and update them, as soon as anything is added to or removed from the list. So in a way this is similar to the Observer pattern applied to the iterator (as Observer) and the list (as Observable).
Alternatively I considered having the visitor() methods return some hint to the Visitor about what happend to the current item and how to proceed iterating, but that doesn't sound like such a good idea either, because the visit() implementation shouldn't really care about finding the next item.
So, my question is: What's the best way to keep a visitor working, even when items are added to the container or removed from it.
Regards,
Florian
Update: There's one visitor running over the container, but inside of the visit() method any number of additional iterators might be used on the same container. I want the visitor to continue with the remaining items in the container, even after we returned from a call to visit() in which any one of the items in the container got deleted.
When mutating the container during traversal, iterators are hazardous, at best. It is safest to use an index and walk backwards.
I think your (first) implementation is pretty good if there are not so many iterators and delete operations. If this would be the case I would use a mark and sweep like algorithm like Eddy recommended. Also, I think the latter is easier and thus less error prone. Don't forget to skip nodes which are marked for deletion.
On the other hand, if there are cases besides 'delete' where your iterators need to be updated, stick to your current implementation.
In these cases, if copying my container is not expensive, I just copy it and iterate on the copy. The original container holds objects by shared_ptr while the copy just holds weak_ptr.

Implementing std::list item read/write events

I'm new to c++ but have set my mind on a specific task that needs me to enable adding a specific chunk of code to be execute whenever any list item is attempted to be changed or read.
The resulting list should behave and look as much as as possible to std::list except for this small exception that would enable me to execute a specific tasks whenever this list is about to be read/written to.
From what i have found out so far, all i could think of is deriving a class from list::iterator and overloading it's operator* and operator= to implement these specific tasks.
Then i should derive a class from std::list and make it use my new iterator type by overloading begin() and end() methods. Or is there a better way of making it use a custom iterator?
That would handle the iterator access but I can see lists can even return pointers to it's members. I guess there is nothing i can do about them and will have to remove this feature from my new list class.
I would appreciate your oppinion on this subject.
Deriving from std::list is almost certainly not the answer. The collections in stl are simply not meant to be derived from and doing so will cause you problems down the road.
The classic example of why is the destructor problem. The destructors in stl collections are not virtual. This will break any logic you place in your derived class destructor if an object is deleted via a reference to the std::list. For example
std::list* pList = new YourNewListClass();
delet pList; // runs std::list::~list()
You'd also need to override much more than the methods on the iterator. It would require changing every method which can possibly mutate the collection.
A more stable approach would be to implement your own std::list style class which follows the standard stl container behavior. You could then include use this list in the places you wanted events without running into the problems with deriving from std::list.
Look at the way that std::deque implements it's functionality as an adaptor of another standard collection. This is the way to go -- use composition not inheritance and wrap the underlying collection to provide your new facilities. For bonus points template your implementation on the underlying collection. For many uses a std::vector will outperform a std::list and your additions should be able to work equally well with whichever of these the user chooses.
First things first..NEVER derive a class from STL containers as they are not meant to be derived. For starters their destructor is not virtual.
The easiest way would be contain a std::list in your own class and providing list like interfaces. In these list like interfaces you can provide any additional tasks you want to perform before/updating the list.
Also, take a look at this design pattern: Decorator
Take a look at boost::transform_iterator<>. It seems to be close to what you're looking for. It calls a functor whenever the operator*() function of the transform_iterator<> is called. The intended use is to transform the object the iterators points to, but there's nothing that says the functor can't do something else and simply return the original value of the pointed to object.
Even if it's not quite what you want, it will probably provide ideas to how you might approach your problem.