Quote:Original post by Wiggin
I guess the lesson here is not to oversimplify ones problem when asking for help.
I think I'm beginning to see the light... almost.
So when I add a partition with no moving object, I append it, and when I add a partition with, I prepend it, and the iterator firstWithoutMovingObjects will remain valid, right?
Using a std::list, yes. Of course, redoing the partition()ing makes that irrelevant.
Then again, I wrote that with the assumption that a given Partition's hasMovingObjects() might change over time. If not, then of course you'd just need to make two separate lists :)
Quote:What about when I, due to objects moving out of the area, need to delete some smaller partitions and replace them with a bigger one?
You can 'remove' the partitions that compose the new one (assuming you have a function that can identify them), and then just insert the new one:
// The std algorithms expect a "predicate" with a specific set of arguments.// In our case, we don't have a way to specify which Partition we're looking// "within" directly from the algorithm. However, we're not just limited to// function pointers: we can use functors, i.e. structs/classes which implement// the operator() with an appropriate argument list and return type.// Then we construct one which "holds onto" a Partition, and refers to it when// doing its calculations.struct isWithin { Partition* container; // non-owning pointer; don't delete! // That should really be a reference, but I tend to mess up using references // as data members... // We'll just make a constructor and the operator overload. isWithin(const Partition& container): container(&container) {} bool operator() (const Partition& p) { return p.isWithin(*container); }};//...// These functions are also in <algorithm>.std::erase(std::remove_if(partitions.begin(), partitions.end(), isWithin(theBigOne)), partitions.end());
Alternatively, set up the predicate so that it directly recognizes which things you want to remove, and partition the list into the about-to-be-removed ones and the rest. Then you can use the "range" of about-to-be-removed ones to construct the big partition, erase() that range, and insert the new one.
// Example of constructing big partition from the range.template <typename ForwardIterator>Partition::Partition(ForwardIterator begin, ForwardIterator end) { doBasicConstruction(); for (ForwardIterator component = begin; component != end; ++component) { union(*component); // "add" each component in turn to self. }}// Now you can pass in two iterators - for example, begin() and the result of // the partition() call (or the call result and end(), depending on the sense// of the partitioning.