25 #ifndef XAPIAN_INCLUDED_SMALLVECTOR_H
26 #define XAPIAN_INCLUDED_SMALLVECTOR_H
29 # error config.h must be included first in each C++ source file
35 #include <type_traits>
56 bool UNIQUEPTR =
false,
57 typename =
typename std::enable_if_t<
58 (std::is_trivially_copyable_v<T> &&
59 (!(COW && UNIQUEPTR)) &&
60 (!UNIQUEPTR || std::is_pointer_v<T>) &&
61 (!COW || std::is_integral_v<T>))>>
66 static constexpr std::size_t INTERNAL_CAPACITY = 2 *
sizeof(T*) /
sizeof(T);
69 T v[INTERNAL_CAPACITY];
111 template<
bool ENABLE = !UNIQUEPTR>
136 return is_external() ? u.p.e - u.p.b : c;
140 return is_external() ? c : INTERNAL_CAPACITY;
144 return is_external() ? u.p.b == u.p.e : c == 0;
148 if (n > capacity()) {
154 return is_external() ? u.p.b : u.v;
158 return is_external() ? u.p.e : u.v + c;
174 if (is_external() && u.p.b[-1] > 0) {
178 return is_external() ? u.p.b : u.v;
183 if (is_external() && u.p.b[-1] > 0) {
187 return is_external() ? u.p.e : u.v + c;
191 auto cap = capacity();
195 if (c >= INTERNAL_CAPACITY) {
220 if constexpr(UNIQUEPTR) {
231 if (is_external() && u.p.b[-1] > 0) {
237 if constexpr(UNIQUEPTR) {
240 T*
p =
const_cast<T*
>(it);
241 std::memmove(
p,
p + 1, (end() - it - 1) *
sizeof(T));
250 auto n_erased = e - b;
251 if (n_erased == 0)
return;
253 if (is_external() && u.p.b[-1] > 0) {
260 if constexpr(UNIQUEPTR) {
264 std::memmove(
const_cast<T*
>(b),
const_cast<T*
>(e),
265 (end() - e) *
sizeof(T));
276 auto cap = capacity();
278 if (n == cap || (COW && is_external() && u.p.b[-1] > 0)) {
282 if (
rare(COW ? cap < c : cap <= c))
283 throw std::bad_alloc();
285 blk =
new T[cap + COW];
295 std::copy(b,
pos, blk);
298 db = (is_external() ? u.p.b : u.v);
301 std::copy_backward(
pos, e, db + n + 1);
313 }
else if (is_external()) {
326 if (is_external() && u.p.b[-1] > 0) {
330 return const_cast<T&
>(begin()[idx]);
342 template<
bool ENABLE = !UNIQUEPTR>
346 std::swap(r, begin()[idx]);
356 delete [] (u.p.b - 1);
364 if (
rare(COW ? n < c : n <= c))
365 throw std::bad_alloc();
366 T* blk =
new T[n + COW];
370 u.p.e = std::copy(u.p.b, u.p.e, blk);
373 u.p.e = std::copy(u.v, u.v + c, blk);
380 T* blk =
new T[c + 1];
382 u.p.e = std::copy(u.p.b, u.p.e, blk);
391 }
else if constexpr(COW) {
396 u.p.e = std::copy(o.
u.
p.b, o.
u.
p.e, blk);
403 return c > INTERNAL_CAPACITY;
430 std::memcpy(
p, o.p,
sizeof(
p));
441 void *
const * b =
static_cast<void *
const *
>(
p[0]);
442 void *
const * e =
static_cast<void *
const *
>(
p[1]);
477 return is_external() ?
static_cast<void *
const *
>(
p[0]) :
p;
490 void ** e =
static_cast<void **
>(
p[1]);
492 p[1] =
static_cast<void*
>(e);
510 template<
typename TI>
539 if ((*i) && --(*i)->_refs == 0)
548 do_push_back(
const_cast<void*
>(
static_cast<const void*
>(elt)));
609 template<
typename I,
typename = std::enable_if_t<std::is_
integral_v<I>>>
612 template<
typename I,
typename = std::enable_if_t<std::is_
integral_v<I>>>
Vector of Xapian PIMPL internal objects.
const_iterator end() const
TI *const * const_iterator
const_iterator begin() const
TI * operator[](size_type idx) const
SmallVectorI(size_type n)
SmallVectorI(SmallVectorI &&o) noexcept
bool operator==(const const_iterator &o) const
const_iterator operator++(int)
T operator[](size_type idx) const
const_iterator(typename super::const_iterator ptr_)
const_iterator operator+(I n)
super::const_iterator ptr
bool operator!=(const const_iterator &o) const
const_iterator operator-(I n)
const_iterator & operator++()
void do_push_back(void *elt)
SmallVector_(std::size_t n)
std::size_t capacity() const
void * p[INTERNAL_CAPACITY]
SmallVector_(const SmallVector_ &)=delete
void operator=(const SmallVector_ &)=delete
static constexpr std::size_t INTERNAL_CAPACITY
void *const * do_end() const
void reserve(std::size_t n)
void do_reserve(std::size_t n)
void *const * do_begin() const
SmallVector_(SmallVector_ &&o) noexcept
bool is_external() const
Return true if storage is external to the object.
Vector of Xapian PIMPL objects.
SmallVectorI< typename T::Internal > super
T operator[](size_type idx) const
const_iterator begin() const
const_iterator end() const
void push_back(const T &elt)
Suitable for "simple" type T.
const_iterator end() const
auto copy() const -> typename std::enable_if_t< ENABLE, Vec_to_copy >
bool is_external() const noexcept
Return true if storage is external to the object.
struct Xapian::Vec::@1::@2 p
T release_at(size_type idx)
void reserve(size_type n)
void erase(const_iterator it)
void erase(const_iterator b, const_iterator e)
void do_copy_from(const Vec &o)
void insert(const_iterator pos, const T &elt)
void operator=(const Vec_to_copy &o)
Vec(const Vec_to_copy &o)
size_type capacity() const
T & operator[](size_type idx)
const_iterator begin() const
const_iterator cend() const
const_iterator cbegin() const
const T & operator[](size_type idx) const
void do_reserve(size_type n)
void operator=(const Vec &)=delete
The Xapian namespace contains public interfaces for the Xapian library.
Vec_to_copy(const Vec &o)