В нескольких моих проектах мне все чаще приходилось иметь дело с непрерывными последовательностями битов в памяти - эффективно (*). До сих пор я написал кучу встраиваемых автономных функций, основанных на выборе типа «контейнера битов» (например, uint32_t
), для получения и установки битов, применения «или» и «и» к их значениям, нахождения контейнер, преобразование длины в битах в размеры в байтах или длины в контейнерах и т. д. ... похоже, пришло время написания класса.
Я знаю, что стандартная библиотека С++ имеет специализацию std::vector<bool>
, что многие считают недостатком дизайна, поскольку ее итераторы не выставляют фактические bool
, а скорее прокси-объекты. Является ли это хорошей или плохой идеей для специализации, я определенно обдумываю это — явный битовый прокси-класс, который, надеюсь, будет «всегда» оптимизирован (с хорошей смазкой с помощью constexpr
, noexcept
и inline
) . Итак, я подумал о возможной адаптации кода std::vector
из одной из реализаций стандартной библиотеки.
С другой стороны, мой предполагаемый класс:
- Никогда не будет владеть данными / битами - он получит адрес начального битового контейнера (при условии выравнивания) и длину в битах и не будет выделять или освобождать.
- Он не сможет динамически или иным образом изменять размер данных - даже при сохранении того же объема пространства, что и std::vector::resize(); его длина будет фиксированной в течение срока его службы/области действия.
- Он ничего не должен знать о куче (и работать, когда кучи нет)
В этом смысле это больше похоже на класс span для битов. Тогда, может быть, начать с диапазона? Не знаю, пролеты еще не стандартные; а в спэнах нет прокси...
Итак, что было бы хорошей основой (изменить: НЕ базовый класс) для моей реализации? std::vector<bool>
? std::span
? Оба? Никто? Или - может я изобретаю велосипед и это уже решаемая проблема?
Заметки:
- Длина последовательности битов известна во время выполнения, а не во время компиляции; в противном случае, как предполагает @SomeProgrammerDude, я мог бы использовать
std::bitset
. - Моему классу не нужно "быть" span или "be-a" вектором, поэтому я не думаю о специализации ни одного из них.
(*) - Пока неэффективно SIMD, но это может появиться позже. Кроме того, это может использоваться в коде CUDA, где мы не используем SIMDize, а притворяемся, что дорожки являются правильными потоками.
std::bitset
? И я действительно не рекомендую специализироваться наstd::vector
, так как тогда вы, по сути, просто переделаетеstd::vector<bool>
. Вместо этого вы можете создать свой собственный класс, который лучше соответствует вашим требованиям и может быть достаточно открытым, чтобы включать ваши планы на будущее. - person Some programmer dude   schedule 14.06.2018std::span
, которую можно найти в Интернете, и позаимствовал бы битовый прокси уvector<bool>
. - person Drew Dormann   schedule 14.06.2018uint64_t
- или он более сложный?) - так что кажется, что у вас уже есть свое решение? По сути, вы просто хотите переместить эти автономные функции внутрь класса, который поддерживает указатель на массив битовых контейнеров? Вы также спрашиваете, должны лиstd::vector
илиstd::span
служить основой для вашего класса, но что здесь означает основа? Вы говорите об использовании одного... - person BeeOnRope   schedule 14.06.2018std::vector<bool>
отсутствует с точки зрения фактической реализации, поскольку он владеет своим хранилищем: тогда как вам ясно, что вы хотите что-то похожее на span/view. Я думаю, что более четкий вопрос покажет функции, которые у вас уже есть, и спросит о конкретном решении, например, относительно дизайна итератора (если вы вообще хотите, чтобы итераторы) или использования прокси-объектов для представления одного бита. - person BeeOnRope   schedule 14.06.2018vector
илиspan
- но в любом случае, если вы хотите начать с нуля, а не использовать свои методы, я попытался ответить. - person BeeOnRope   schedule 15.06.2018std::bitset
предоставляет прокси-объект для побитовой модификации, поэтому я думаю, что это отличный кандидат. - person BeeOnRope   schedule 15.06.2018std::span
; в основном обертка вокруг ряда объектов. Даже если он не войдет в окончательный вариант стандарта,std::span
, по крайней мере, был проверен комитетом как действительно хорошая идея, настолько, что, вероятно, он останется в стандартной версии для C++20. - person AndyG   schedule 18.06.2018