06 апреля 2008

Accessing old-school APIs as C++ containers

Часто API и библиотеки предоставляют доступ к набору объектов в следующем виде:
size_t GetItemCount();
value GetItem(size_t Index);
Особенно это относится к библиотекам на C. Оказалось, очень просто преобразовать такой интерфейс к более стандартному для C++ виду - итераторам:
class iterator : public boost::iterator_facade<iterator, value,
std::random_access_iterator_tag, value, size_t>
{
public:
iterator(size_t Index) : Index_(Index) { }

// implementation
public:
reference dereference() const { return GetItem(Index_); }
void increment() { ++Index_; }
void decrement() { --Index_; }
bool equal(const iterator& It) const { return Index_ == It.Index_; }

private:
size_t Index_;
};
Теперь можно делать STL-way:
std::copy(iterator(0), iterator(GetItemCount()), ...);
Или даже так:
BOOST_FOREACH(value v, make_iterator_range(iterator(0), iterator(GetItemCount())))
...;

2 комментария:

Анонимный комментирует...

+ сюда идеально вписывается proxy класс-обертка для чтения/записи элементов

Raider комментирует...

Кстати да. Если, конечно, элементы изменяемы