Подтвердить что ты не робот

Почему llvm:: SmallVector разделяет его хранилище?

Реализация llvm::SmallVector<T,N> разделяется между многими типами:

  • llvm::SmallVectorBase содержит 3 void* для начала, конца и емкости.
  • llvm::SmallVectorTemplateCommon<T> содержит первый элемент небольшого хранилища, как соответствующий размерный и размерный массив char.
  • llvm::SmallVector<T,N> содержит следующие элементы N-1 для небольшого хранилища в виде массива подходящих выровненных и размерных массивов char.

Почему разделение хранилища между двумя шаблонами классов, в отличие от самого производного класса (SmallVector<T,N>), просто хранит все элементы N и передает указатели на это хранилище до базового класса? То есть, где в настоящее время конструктор по умолчанию делает:

SmallVector() : SmallVectorImpl<T>(N) { }

Возможна гипотетическая различная реализация:

SmallVector() : SmallVectorImpl<T>(&Storage, T * sizeof(N)) { }

и SmallVectorTemplateCommon не будет иметь член FirstEl. В чем преимущество реализации в ее нынешнем виде?

4b9b3361

Ответ 1

Разделение хранилища позволяет избежать сохранения встроенной емкости (или бит "маленький" ) в типе "размер-стертый" SmallVectorImpl.

SmallVectorImpl<T> может использоваться для ссылки на любой SmallVector<T, N> и поддерживает все векторные операции над ним. Когда базовое хранилище растет, указатель не может быть передан в free, если он использует встроенную емкость. Сравнение текущего адреса памяти с первым элементом встроенной емкости удобно и сохраняет бит памяти в SmallVector.