My container system is practically done (for now.) I've added a bunch of stuff and left some stuff out (because I've never used them; I'll add them when the time comes.)
Anyway, to the point of the post. I'm really sick of all of these for() loops that look horrid and are a pain to read through, so I made a simpler system. I kept my old dfg::Vector and dfg::Dictionary and added dfg::EnumerableVector and dfg::EnumerableDictionary (just in case I'm overlooking a major problem in the design.) I also added a base class named Enumerable:
template class Enumerable{public: Enumerable() { } virtual ~Enumerable() { } virtual void Reset() = 0; virtual bool MoveNext() = 0; virtual TYPE GetCurrent() = 0;};
And this is what my new containers look like:
template class EnumerableVector : public dfg::Enumerable, public dfg::Vector{ typename dfg::Vector::Iterator Current;public: EnumerableVector() { Current = 0; } void Reset() { Current = 0; } bool MoveNext() { if(Current == 0) Current = this->Begin(); else ++Current; if(Current == this->End()) { Current = 0; return false; } return true; } TYPE GetCurrent() { if(Current == 0) throw dfg::NullException(__FILE__, __LINE__, "EnumerableVector::Current has not been set. Try calling Reset() and then MoveNext() before GetCurrent()."); return (*Current); }};
And:
template class EnumerableDictionary : public dfg::Enumerable, public dfg::Dictionary{ typename dfg::Dictionary::Iterator Current;public: EnumerableDictionary() { Current = 0; } void Reset() { Current = 0; } bool MoveNext() { if(Current == 0) Current = this->Begin(); else ++Current; if(Current == this->End()) { Current = 0; return false; } return true; } KEY GetCurrentKey() { if(Current == 0) throw dfg::NullException(__FILE__, __LINE__, "EnumerableDictionary::Current has not been set. Try calling Reset() and then MoveNext() before GetCurrentKey()."); return (*Current).first; } TYPE GetCurrent() { if(Current == 0) throw dfg::NullException(__FILE__, __LINE__, "EnumerableDictionary::Current has not been set. Try calling Reset() and then MoveNext() before GetCurrent()."); return (*Current).second; }};
And some test code:
dfg::EnumerableDictionary Words;int main(){ for(int Index = 0; Index < 10; ++Index) Words.Add(dfg::String::Format("%i", Index), dfg::String::Format("String number %i", Index + 1)); while(Words.MoveNext()) std::cout<") "
}
Questions, comments, and/or suggestions are always welcome! If I don't find anything that's deathly wrong with it, I'll be releasing the whole library sometime this week/early next week.
Check out OpenXNA, we're going to be hosting open-source libraries, projects, tutorials, and games all about XNA. Methinks the first thing on my list is going to be a GUI for XNA. Hopefully Raymond doesn't read that... >_> <_<
I hope this isn't taken as criticism but I was just wondering what would happen if you were halfway through a MoveNext() sequence and called a function that, within that, had to run through the WordDictionary seperately?
I had a problem with a list of game objects once that provided an interface like yours with a position marker internal to the list class. During one of the iterations, it called another function that also had to iterate through the list and it all went a bit mad.