22 #include "lfVectorIterator.h" 26 template <
class T,
int32_t nSlots>
30 setZero(slots_, nSlots *
sizeof(T*));
33 template <
class T,
int32_t nSlots>
38 setZero(slots_, nSlots *
sizeof(T*));
40 for (int32_t i = 0; i <= s; ++i)
41 slots_[i] =
new T[1 << i];
44 template <
class T,
int32_t nSlots>
49 setZero(slots_, nSlots *
sizeof(T*));
51 for (
size_t i = 0; i <= size_t(s); ++i)
53 const size_t sz = 1 << i;
54 slots_[i] =
new T[sz];
55 for (
size_t j = 0; size_ < n && j < sz; ++j)
61 LBASSERTINFO(size_ == n, size_ <<
" != " << n);
64 template <
class T,
int32_t nSlots>
72 template <
class T,
int32_t nSlots>
73 template <
int32_t fromSlots>
81 template <
class T,
int32_t nSlots>
84 for (
size_t i = 0; i < nSlots; ++i)
88 template <
class T,
int32_t nSlots>
95 ScopedWrite mutex1(lock_);
96 ScopedWrite mutex2(from.lock_);
98 for (
size_t i = 0; i < size_t(nSlots); ++i)
102 const size_t sz = 1 << i;
104 slots_[i] =
new T[sz];
106 for (
size_t j = 0; size_ < from.size_ && j < sz; ++j)
108 slots_[i][j] = from.slots_[i][j];
119 LBASSERTINFO(size_ == from.size_, size_ <<
" != " << from.size_);
123 template <
class T,
int32_t nSlots>
134 for (; it !=
end() && rhsIt !=
end(); ++it, ++rhsIt)
143 #ifdef LB_GCC_4_6_OR_LATER // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51721 144 #ifndef LB_GCC_4_8 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56824 145 #pragma GCC diagnostic push 147 #pragma GCC diagnostic ignored "-Warray-bounds" 150 template <
class T,
int32_t nSlots>
154 LBASSERTINFO(size_ >= i, size_ <<
" < " << i);
157 const size_t index = i ^ (size_t(1) << slot);
159 LBASSERTINFO(slot >= 0 && slot < nSlots, slot);
160 LBASSERT(slots_[slot]);
161 LBASSERT(index < (1ull << slot));
162 return slots_[slot][index];
165 template <
class T,
int32_t nSlots>
168 LBASSERTINFO(size_ > i, size_ <<
" <= " << i);
171 const size_t index = i ^ (size_t(1) << slot);
173 LBASSERTINFO(slot >= 0 && slot < nSlots, slot);
174 LBASSERT(slots_[slot]);
175 LBASSERT(index < (1ull << slot));
176 return slots_[slot][index];
179 #ifdef LB_GCC_4_6_OR_LATER 181 #pragma GCC diagnostic pop 185 template <
class T,
int32_t nSlots>
192 template <
class T,
int32_t nSlots>
196 return (*
this)[size_ - 1];
199 template <
class T,
int32_t nSlots>
202 ScopedWrite mutex(lock_);
203 while (newSize >
size())
204 push_back_unlocked_(item);
207 template <
class T,
int32_t nSlots>
212 ScopedWrite mutex(lock_);
213 push_back_unlocked_(item);
216 push_back_unlocked_(item);
219 template <
class T,
int32_t nSlots>
222 ScopedWrite mutex(lock_);
226 (*this)[size_] = T();
230 template <
class T,
int32_t nSlots>
233 ScopedWrite mutex(lock_);
239 (*this)[size_] = T();
244 template <
class T,
int32_t nSlots>
248 LBASSERT(pos.container_ ==
this);
249 if (pos.container_ !=
this || pos.i_ >= size_)
252 ScopedWrite mutex(lock_);
254 #pragma warning(push) 255 #pragma warning(disable : 4996) // unchecked iterators 256 std::copy(pos + 1,
end() + 1, pos);
258 (*this)[size_] = T();
263 template <
class T,
int32_t nSlots>
267 ScopedWrite mutex(lock_);
268 for (
size_t i = size_; i != 0; --i)
270 if ((*
this)[i - 1] == element)
274 #pragma warning(push) 275 #pragma warning(disable : 4996) // unchecked iterators 276 std::copy(pos + 1,
end() + 1, pos);
286 template <
class T,
int32_t nSlots>
289 ScopedWrite mutex(lock_);
290 while (size_ > newSize)
293 (*this)[size_] = T();
297 while (size_ < newSize)
298 push_back_unlocked_(value);
301 template <
class T,
int32_t nSlots>
304 ScopedWrite mutex(lock_);
308 (*this)[size_] = T();
310 for (int32_t i = 0; i < nSlots; ++i)
317 template <
class T,
int32_t nSlots>
321 return {lock_, std::adopt_lock};
324 template <
class T,
int32_t nSlots>
325 template <
int32_t fromSlots>
328 setZero(slots_, nSlots *
sizeof(T*));
330 ScopedWrite mutex(from.lock_);
331 for (int32_t i = 0; i < nSlots; ++i)
333 if (i >= fromSlots || !from.slots_[i])
335 LBASSERTINFO(size_ == from.size_, size_ <<
" != " << from.size_);
339 const int32_t sz = 1 << i;
340 slots_[i] =
new T[sz];
341 for (int32_t j = 0; size_ < from.size_ && j < sz; ++j)
343 slots_[i][j] = from.slots_[i][j];
349 template <
class T,
int32_t nSlots>
352 const size_t i = size_ + 1;
354 if (slot < 0 || slot >= nSlots)
356 LBASSERTINFO(slot >= 0 && slot < nSlots, slot);
357 LBTHROW(std::runtime_error(
"LFVector full"));
360 const size_t sz = (size_t(1) << slot);
363 slots_[slot] =
new T[sz];
365 const ssize_t index = i ^ sz;
366 slots_[slot][index] = item;
370 template <
class T,
int32_t nSlots>
374 if (nextSlot < nSlots && slots_[nextSlot])
376 delete[] slots_[nextSlot];
377 slots_[nextSlot] = 0;
381 template <
class T,
int32_t nSlots>
388 template <
class T,
int32_t nSlots>
395 template <
class T,
int32_t nSlots>
401 template <
class T,
int32_t nSlots>
408 template <
class T,
int32_t nSlots>
409 template <
class Archive>
411 const unsigned int )
const 414 for (
size_t i = 0; i < size_; ++i)
418 template <
class T,
int32_t nSlots>
419 template <
class Archive>
426 LBASSERT(size_ == newSize);
428 for (
size_t i = 0; i < size_; ++i)
434 std::ostream& operator<<(std::ostream& os, const LFVector<T>& v)
436 os <<
className(&v) <<
" size " << v.size() <<
" [ ";
439 if (i.getPosition() > 255)
446 return os <<
']' << std::endl;
std::string className(const T &object)
Print the RTTI name of the given class.
An iterator for LFVector.
void set()
Acquire the lock exclusively.
STL-like vector implementation providing certain thread-safety guarantees.
int32_t getIndexOfLastBit(T value)
LFVector & operator=(const LFVector &from)
void push_back(const T &item, bool lock=true)
Add an element to the vector.
ScopedWrite getWriteLock()
LFVectorIterator< LFVector< T, nSlots >, T > iterator
Iterator over the vector elements.
static void setZero(void *ptr, const size_t size)
OS-independent call to bzero(3).
LFVectorIterator< const LFVector< T, nSlots >, const T > const_iterator
Iterator over the const vector elements.
bool operator==(const LFVector &rhs) const
void pop_back()
Remove the last element (STL version).
void clear()
Clear the vector and all storage.
const_iterator end() const
Abstraction layer and common utilities for multi-threaded programming.
void resize(const size_t size, const T &value=T())
Resize the vector.
#define LBTHROW(exc)
Log a std::exception if topic LOG_EXCEPTION is set before throwing exception.
void expand(const size_t newSize, const T &item=T())
Resize the vector to at least the given size.
const_iterator begin() const
iterator erase(typename LFVector< T, nSlots >::iterator pos)
Remove an element.