vector.inl - Engine C API Reference

vector.inl
  1. namespace stingray_plugin_foundation {
  2. template <class T> Vector<T>::Vector(Allocator &allocator) : _size(0), _capacity(0), _data(0), _allocator(&allocator)
  3. {
  4. }
  5. template <class T> Vector<T>::Vector(unsigned size, Allocator &allocator) : _size(0), _capacity(0), _data(0), _allocator(&allocator)
  6. {
  7. resize(size);
  8. }
  9. template <class T> Vector<T>::Vector(const NoAllocator &) : _size(0), _capacity(0), _data(0), _allocator(0)
  10. {
  11. }
  12. template <class T> void Vector<T>::set_allocator(Allocator &allocator)
  13. {
  14. _allocator = &allocator;
  15. }
  16. template <class T> Vector<T>::Vector( const Vector<T> &o ) : _size(0), _capacity(0), _data(0), _allocator(o._allocator)
  17. {
  18. set_capacity(o.size());
  19. for (unsigned i=0; i<o.size(); ++i) {
  20. construct(_data + i, IS_ALLOCATOR_AWARE_TYPE(T)());
  21. _data[i] = o[i];
  22. }
  23. _size = o.size();
  24. }
  25. template <class T> void Vector<T>::operator=(const Vector<T> &o)
  26. {
  27. resize(o.size());
  28. for (unsigned i=0; i<_size; ++i)
  29. _data[i] = o[i];
  30. }
  31. template <class T> typename Vector<T>::reference Vector<T>::operator[](unsigned i) {
  32. #if defined(_DEBUG)
  33. XASSERT(i < _size, "Vector index out of bounds %d >= %d", i, _size);
  34. #endif
  35. return _data[i];
  36. }
  37. template <class T> typename Vector<T>::const_reference Vector<T>::operator[](unsigned i) const {
  38. #if defined(_DEBUG)
  39. XASSERT(i < _size, "Vector index out of bounds %d >= %d", i, _size);
  40. #endif
  41. return _data[i];
  42. }
  43. template <class T> void Vector<T>::reserve(unsigned capacity)
  44. {
  45. if (capacity > _capacity)
  46. grow(capacity);
  47. }
  48. template <class T> template <class ASSIGNABLE>
  49. void Vector<T>::push_back(const ASSIGNABLE &item)
  50. {
  51. if (_size + 1 > _capacity)
  52. grow();
  53. construct(_data + _size, IS_ALLOCATOR_AWARE_TYPE(T)());
  54. #pragma warning(push)
  55. #pragma warning(disable:4244) // can't fix cast warning
  56. _data[_size] = item;
  57. #pragma warning(pop)
  58. ++_size;
  59. }
  60. template <class T> void Vector<T>::pop_back()
  61. {
  62. _size--;
  63. _data[_size].~T();
  64. }
  65. template <class T> void Vector<T>::swap(Vector<T> &o)
  66. {
  67. XENSURE(_allocator == o._allocator);
  68. std::swap(_size, o._size);
  69. std::swap(_capacity, o._capacity);
  70. std::swap(_data, o._data);
  71. std::swap(_allocator, o._allocator);
  72. }
  73. template <class T> template <class ASSIGNABLE>
  74. typename Vector<T>::iterator Vector<T>::insert(iterator pos, const ASSIGNABLE& x)
  75. {
  76. if (_size + 1 > _capacity) {
  77. unsigned i = (unsigned)(pos - _data);
  78. grow();
  79. pos = _data + i;
  80. }
  81. move(pos + 1, pos, (_data + _size) - pos);
  82. construct(pos, IS_ALLOCATOR_AWARE_TYPE(T)());
  83. *pos = x;
  84. ++_size;
  85. return pos;
  86. }
  87. template <class T> typename Vector<T>::iterator Vector<T>::insert(iterator pos)
  88. {
  89. if (_size + 1 > _capacity) {
  90. unsigned i = (unsigned)(pos - _data);
  91. grow();
  92. pos = _data + i;
  93. }
  94. move(pos + 1, pos, (_data + _size) - pos);
  95. construct(pos, IS_ALLOCATOR_AWARE_TYPE(T)());
  96. ++_size;
  97. return pos;
  98. }
  99. template <class T> void Vector<T>::insert(iterator pos, const_iterator from, const_iterator to)
  100. {
  101. unsigned add = (unsigned)(to - from);
  102. if (_size + add > _capacity) {
  103. unsigned i = (unsigned)(pos - _data);
  104. grow(_size + add);
  105. pos = _data + i;
  106. }
  107. move(pos + add, pos, (_data + _size) - pos);
  108. while (from < to) {
  109. construct(pos, IS_ALLOCATOR_AWARE_TYPE(T)());
  110. *pos = *from;
  111. ++pos;
  112. ++from;
  113. ++_size;
  114. }
  115. }
  116. template <class T> typename Vector<T>::iterator Vector<T>::erase(iterator pos)
  117. {
  118. #if defined(_DEBUG)
  119. XASSERT(pos >= begin() && pos < end(), "Trying to remove outside vector.");
  120. #endif
  121. pos->~T();
  122. move(pos, pos + 1, (_data + _size) - pos - 1);
  123. --_size;
  124. return pos;
  125. }
  126. template <class T> typename Vector<T>::iterator Vector<T>::erase(iterator first, iterator last)
  127. {
  128. #if defined(_DEBUG)
  129. XASSERT(first <= last, "Trying to remove inverted range from vector.");
  130. XASSERT(first >= begin() && last <= end(), "Trying to remove range outside vector.");
  131. #endif
  132. for (iterator p = first; p < last; ++p)
  133. p->~T();
  134. move(first, last, (_data + _size) - last);
  135. _size -= (unsigned)(last - first);
  136. return first;
  137. }
  138. template <class T> template <typename EQUATABLE> void Vector<T>::erase(const EQUATABLE &item)
  139. {
  140. iterator it = find(item);
  141. #if defined(_DEBUG)
  142. XASSERT(it != end(), "Trying to remove nonexisting value in vector.");
  143. #endif
  144. erase(it);
  145. }
  146. template <class T> void Vector<T>::resize(unsigned size)
  147. {
  148. if (size > _capacity)
  149. grow(size);
  150. while (size > _size) {
  151. construct(_data + _size, IS_ALLOCATOR_AWARE_TYPE(T)());
  152. ++_size;
  153. }
  154. while (_size > size) {
  155. --_size;
  156. _data[_size].~T();
  157. }
  158. }
  159. template <class T> void Vector<T>::set_capacity(unsigned capacity)
  160. {
  161. if (capacity == _capacity)
  162. return;
  163. if (capacity < _size)
  164. resize(capacity);
  165. pointer new_data = 0;
  166. if (capacity > 0) {
  167. new_data = (pointer)_allocator->allocate(sizeof(value_type)*capacity, math::max((int)alignof(value_type), 4));
  168. move(new_data, _data, _size);
  169. }
  170. _allocator->deallocate(_data);
  171. _data = new_data;
  172. _capacity = capacity;
  173. }
  174. template <class T> void Vector<T>::move(pointer to, pointer from, ptrdiff_t n)
  175. {
  176. memmove(to, from, sizeof(T) * n);
  177. }
  178. template <class T>
  179. template <class STREAM> void Vector<T>::serialize(STREAM &stream)
  180. {
  181. unsigned sz = size();
  182. stream & sz;
  183. resize(sz);
  184. for (unsigned i=0; i<sz; ++i)
  185. stream & (*this)[i];
  186. }
  187. template<class T> bool Vector<T>::operator==(const Vector<T> &o) const
  188. {
  189. if (size() != o.size())
  190. return false;
  191. for (unsigned i=0; i<size(); ++i)
  192. if ((*this)[i] != o[i])
  193. return false;
  194. return true;
  195. }
  196. template<class T> bool Vector<T>::operator<(const Vector<T> &o) const
  197. {
  198. if (size() != o.size())
  199. return size() < o.size();
  200. for (unsigned i=0; i<size(); ++i)
  201. if ((*this)[i] != o[i])
  202. return (*this)[i] < o[i];
  203. return false;
  204. }
  205. template <class T> void Vector<T>::grow(unsigned min_capacity)
  206. {
  207. uint64_t new_capacity = (uint64_t)_capacity*2 + 10;
  208. if (new_capacity < min_capacity)
  209. new_capacity = min_capacity;
  210. else if (new_capacity > UINT32_MAX)
  211. new_capacity = UINT32_MAX;
  212. set_capacity((unsigned)new_capacity);
  213. }
  214. }