I have a need for a “container” that acts like the following. It has 2 subcontainers, called A and B, and I need to be able to iterate over just A, just B, and A and B combined. I don’t want to use extra space for redundant data, so I thought of making my own iterator to iterate over A and B combined. What is the easiest way to make your own iterator? Or, what is another way to do this?
EDIT Ultimately, I don’t think it was good design. I have redesigned the entire class heirarchy. +1 for refactoring. However, I did solve this problem sufficiently. Here’s an abbreviated version of what I did, for reference; it uses boost::filter_iterator. Let T be the type in the container.
enum Flag
{
A_flag,
B_flag
};
class T_proxy
{
public:
T_proxy(const T& t, Flag f) : t_(t), flag_(f) {}
operator T() const {return t_;}
Flag flag() const {return flag_;}
class Compare
{
public:
Compare(Flag f) : matchFlag_(f) {}
operator() (const T_proxy& tp) {return tp.flag() == matchFlag_;}
private:
Flag matchFlag_;
};
private:
T t_;
Flag flag_;
};
class AB_list
{
public:
typedef T_proxy::Compare Compare;
typedef vector<T_proxy>::iterator iterator;
typedef boost::filter_iterator<Compare, iterator> sub_iterator;
void insert(const T& val, Flag f) {data_.insert(T_proxy(val, f));}
// other methods...
// whole sequence
iterator begin() {return data_.begin();}
iterator end() {return data_.end();}
// just A
sub_iterator begin_A() {return sub_iterator(Compare(A_flag), begin(), end());
sub_iterator end_A() {return sub_iterator(Compare(A_flag), end(), end());
// just B is basically the same
private:
vector<T_proxy> data_;
};
// usage
AB_list mylist;
mylist.insert(T(), A_flag);
for (AB_list::sub_iterator it = mylist.begin_A(); it != mylist.end_A(); ++it)
{
T temp = *it; // T_proxy is convertible to T
cout << temp;
}
I will repost my answer to a similar question. I think this will do what you want.
Use a library like Boost.MultiIndex to do what you want. It scales well and there is a lot less boiler plate code if you want to add new indexes. It is also usually more space and time efficient
If you are iterating over one index, you can switch to another index by using the iterator projection concept in the library.