You can use a set to sort keys for you, and encapsulate them in a custom container for a more convenient usability:
class Foo
{
public :
Foo(const std::string & key) : key(key) {}
const std::string & get_key() const { return key; }
private :
std::string key;
};
std::ostream & operator<<(std::ostream & stream, const Foo & foo) { stream << foo.get_key(); return stream; }
class SortedFoo
{
typedef std::set<std::pair<std::string,Foo*> > SortedFoos;
SortedFoos mFoos;
public :
SortedFoo(std::vector<Foo> & foos)
{
const std::vector<Foo>::iterator end = foos.end();
for(std::vector<Foo>::iterator iter = foos.begin(); iter != end; ++iter)
{
mFoos.insert(std::make_pair(boost::algorithm::to_lower_copy(iter->get_key()), &(*iter)));
}
}
class Iterator : public std::iterator<std::forward_iterator_tag, Foo>
{
private:
Iterator(SortedFoos::iterator iter) : mIter(iter) {}
SortedFoos::iterator mIter;
public :
Iterator & operator ++ () { ++mIter; return *this; }
bool operator != (const Iterator & other) const { return mIter != other.mIter; }
Foo & operator * () { return *mIter->second; }
Foo * operator -> () { return mIter->second; }
friend class SortedFoo;
};
typedef Iterator iterator;
iterator begin() { return Iterator(mFoos.begin()); }
iterator end() { return Iterator(mFoos.end()); }
};
int main(int argc, const char** argv)
{
std::vector<Foo> foos;
foos.push_back(Foo("def"));
foos.push_back(Foo("Jkl"));
foos.push_back(Foo("yz "));
foos.push_back(Foo("pqr"));
foos.push_back(Foo("Mno"));
foos.push_back(Foo("ghi"));
foos.push_back(Foo("vwx"));
foos.push_back(Foo("Abc"));
foos.push_back(Foo("stu"));
SortedFoo sorted(foos);
std::copy(sorted.begin(), sorted.end(), std::ostream_iterator<Foo>(std::cout, " "));
return 0;
}
If you have duplicate keys, you can't use a set. You can replace it by a vector with only a few modifications:
typedef std::vector<std::pair<std::string,Foo*> > SortedFoos;
//...
SortedFoo(std::vector<Foo> & foos)
{
const std::vector<Foo>::iterator end = foos.end();
for(std::vector<Foo>::iterator iter = foos.begin(); iter != end; ++iter)
{
mFoos.push_back(std::make_pair(boost::algorithm::to_lower_copy(iter->get_key()), &(*iter)));
}
std::sort(mFoos.begin(), mFoos.end());
}
//...