Я попытался реализовать циклический буфер следующего вида.
Для простоты я предполагаю, что циклический буфер - это просто адаптер контейнера (например, std::stack
) для контейнеров, имеющих RandomAccessIterator . Контейнер изменял размер / заполнял значения каким-либо образом, затем вставлял в адаптер. После этого размер нижележащего контейнера не должен изменяться.
Очевидно c.begin() == c.end()
для циклического буфера. Некоторые алгоритмы (скажем, диапазон на основе l oop) не работают должным образом для циклического буфера (вместо for (;;)
можно использовать assert(!c.empty()); auto beg = std::begin(c), it = beg; do { f(it); } while (++it != beg);
для обхода циклического буфера).
Основная проблема возникла, когда я Попробуйте отсортировать циклический буфер, используя std::sort
. Наследование категории итераторов из нижележащего контейнера не справедливо для циклических буферных итераторов. Итератор циклического буфера должен быть почти RandomAccessIterator , но не строго по порядку (<
, >
, <=
, >=
не определены). Реализация std::sort
может использовать operator <
внутри (и делает).
Я не могу определить свою собственную категорию итераторов (скажем, ModularIterator ) и вставить ее между существующими категориями (например, что std::is_base_of_v<std::bidirectional_iterator_tag, my_iterator_tag>
и std::is_base_of_v<my_iterator_tag, std::random_access_iterator_tag>
). Также алгоритмы не являются точками настройки.
Я не хочу устанавливать iterator_category
в std::bidirectional_iterator_tag
, потому что std::equal_range
не будет работать в логарифмическом c времени.
строгое общее упорядочение RandomAccessIterator действительно необходимо где-то в алгоритмах или его можно избежать?
Есть ли способ заставить <algorithm>
s работать для циклического буфера?
в Стандарте упущено, что не существует категории итераторов, подходящей для неупорядоченных итераторов, которая может быть продвинута для любого шага для O(1)
?
Пример: https://wandbox.org/permlink/GH1JF4WK2IUUCRHg