namespace stingray_plugin_foundation { template Vector::Vector(Allocator &allocator) : _size(0), _capacity(0), _data(0), _allocator(&allocator) { } template Vector::Vector(unsigned size, Allocator &allocator) : _size(0), _capacity(0), _data(0), _allocator(&allocator) { resize(size); } template Vector::Vector(const NoAllocator &) : _size(0), _capacity(0), _data(0), _allocator(0) { } template void Vector::set_allocator(Allocator &allocator) { _allocator = &allocator; } template Vector::Vector( const Vector &o ) : _size(0), _capacity(0), _data(0), _allocator(o._allocator) { set_capacity(o.size()); for (unsigned i=0; i void Vector::operator=(const Vector &o) { resize(o.size()); for (unsigned i=0; i<_size; ++i) _data[i] = o[i]; } template typename Vector::reference Vector::operator[](unsigned i) { #if defined(_DEBUG) XASSERT(i < _size, "Vector index out of bounds %d >= %d", i, _size); #endif return _data[i]; } template typename Vector::const_reference Vector::operator[](unsigned i) const { #if defined(_DEBUG) XASSERT(i < _size, "Vector index out of bounds %d >= %d", i, _size); #endif return _data[i]; } template void Vector::reserve(unsigned capacity) { if (capacity > _capacity) grow(capacity); } template template void Vector::push_back(const ASSIGNABLE &item) { if (_size + 1 > _capacity) grow(); construct(_data + _size, IS_ALLOCATOR_AWARE_TYPE(T)()); _data[_size] = item; ++_size; } template void Vector::pop_back() { _size--; _data[_size].~T(); } template void Vector::swap(Vector &o) { XENSURE(_allocator == o._allocator); std::swap(_size, o._size); std::swap(_capacity, o._capacity); std::swap(_data, o._data); std::swap(_allocator, o._allocator); } template template typename Vector::iterator Vector::insert(iterator pos, const ASSIGNABLE& x) { if (_size + 1 > _capacity) { unsigned i = (unsigned)(pos - _data); grow(); pos = _data + i; } move(pos + 1, pos, (_data + _size) - pos); construct(pos, IS_ALLOCATOR_AWARE_TYPE(T)()); *pos = x; ++_size; return pos; } template typename Vector::iterator Vector::insert(iterator pos) { if (_size + 1 > _capacity) { unsigned i = (unsigned)(pos - _data); grow(); pos = _data + i; } move(pos + 1, pos, (_data + _size) - pos); construct(pos, IS_ALLOCATOR_AWARE_TYPE(T)()); ++_size; return pos; } template void Vector::insert(iterator pos, const_iterator from, const_iterator to) { unsigned add = (unsigned)(to - from); if (_size + add > _capacity) { unsigned i = (unsigned)(pos - _data); grow(_size + add); pos = _data + i; } move(pos + add, pos, (_data + _size) - pos); while (from < to) { construct(pos, IS_ALLOCATOR_AWARE_TYPE(T)()); *pos = *from; ++pos; ++from; ++_size; } } template typename Vector::iterator Vector::erase(iterator pos) { #if defined(_DEBUG) XASSERT(pos >= begin() && pos < end(), "Trying to remove outside vector."); #endif pos->~T(); move(pos, pos + 1, (_data + _size) - pos - 1); --_size; return pos; } template typename Vector::iterator Vector::erase(iterator first, iterator last) { #if defined(_DEBUG) XASSERT(first <= last, "Trying to remove inverted range from vector."); XASSERT(first >= begin() && last <= end(), "Trying to remove range outside vector."); #endif for (iterator p = first; p < last; ++p) p->~T(); move(first, last, (_data + _size) - last); _size -= (unsigned)(last - first); return first; } template template void Vector::erase(const EQUATABLE &item) { iterator it = find(item); #if defined(_DEBUG) XASSERT(it != end(), "Trying to remove nonexisting value in vector."); #endif erase(it); } template void Vector::resize(unsigned size) { if (size > _capacity) grow(size); while (size > _size) { construct(_data + _size, IS_ALLOCATOR_AWARE_TYPE(T)()); ++_size; } while (_size > size) { --_size; _data[_size].~T(); } } template void Vector::set_capacity(unsigned capacity) { if (capacity == _capacity) return; if (capacity < _size) resize(capacity); pointer new_data = 0; if (capacity > 0) { new_data = (pointer)_allocator->allocate(sizeof(value_type)*capacity, math::max((int)alignof(value_type), 4)); move(new_data, _data, _size); } _allocator->deallocate(_data); _data = new_data; _capacity = capacity; } template void Vector::move(pointer to, pointer from, ptrdiff_t n) { memmove(to, from, sizeof(T) * n); } template template void Vector::serialize(STREAM &stream) { unsigned sz = size(); stream & sz; resize(sz); for (unsigned i=0; i bool Vector::operator==(const Vector &o) const { if (size() != o.size()) return false; for (unsigned i=0; i bool Vector::operator<(const Vector &o) const { if (size() != o.size()) return size() < o.size(); for (unsigned i=0; i void Vector::grow(unsigned min_capacity) { uint64_t new_capacity = (uint64_t)_capacity*2 + 10; if (new_capacity < min_capacity) new_capacity = min_capacity; else if (new_capacity > UINT32_MAX) new_capacity = UINT32_MAX; set_capacity((unsigned)new_capacity); } }