Ваш код проходит по списку дважды, а не один раз.
Так что это может помочь определить итератор, который возвращает адреса, так что все делается за один проход:
struct blocks {
void *current;
size_t increment;
blocks(void* start, size_t size = 0) : current(start), increment(size) {}
bool operator==(const blocks &rhs) const { return current == rhs.current; }
bool operator!=(const blocks &rhs) const { return current != rhs.current; }
void *operator*() const { return current; }
blocks &operator++() {
current = (void*)( (char*)current + increment );
return *this;
}
};
std::list<void*> memory(blocks(begin, block_size), blocks(max_size));
(Код не тестировался, и я упустил некоторые вещи, которые вам нужны для того, чтобы быть подходящим итератором - для этого нужны теги, если ничего другого, и постинкремент обычно приветствуется.)
В настоящее время это просто ForwardIterator (или был бы, если бы он был помечен). Вы можете легко сделать это RandomAccessIterator, но вам нужно будет дать конечному итератору правильный размер. Если бы вы использовали контейнер char(*)[block_size]
вместо контейнера void*
, то я думаю, что вы могли бы просто использовать boost::counting_iterator<char(*)[block_size]>
для его заполнения.
В принципе, std::list
умеренно медленный в этом. Если вы не собираетесь делать вставку / удаление в середине (что кажется ненужным для списка свободных пулов памяти - если все блоки имеют одинаковый размер, вы всегда сможете добавлять и удалять в конце), вы могли бы сделать лучше с вектором или deque, или, по крайней мере, с навязчивым связанным списком.