Vector.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /******************************************************************************
  2. * Spine Runtimes Software License v2.5
  3. *
  4. * Copyright (c) 2013-2016, Esoteric Software
  5. * All rights reserved.
  6. *
  7. * You are granted a perpetual, non-exclusive, non-sublicensable, and
  8. * non-transferable license to use, install, execute, and perform the Spine
  9. * Runtimes software and derivative works solely for personal or internal
  10. * use. Without the written permission of Esoteric Software (see Section 2 of
  11. * the Spine Software License Agreement), you may not (a) modify, translate,
  12. * adapt, or develop new applications using the Spine Runtimes or otherwise
  13. * create derivative works or improvements of the Spine Runtimes or (b) remove,
  14. * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
  15. * or other intellectual property or proprietary rights notices on or in the
  16. * Software, including any copy thereof. Redistributions in binary or source
  17. * form must include this license and terms.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
  20. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  22. * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
  25. * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  26. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. * POSSIBILITY OF SUCH DAMAGE.
  29. *****************************************************************************/
  30. #ifndef Spine_Vector_h
  31. #define Spine_Vector_h
  32. #include <spine/Extension.h>
  33. #include <stdlib.h>
  34. #include <memory>
  35. #include <assert.h>
  36. #include <spine/SpineObject.h>
  37. #include <spine/Extension.h>
  38. namespace Spine {
  39. template <typename T>
  40. class Vector : public SpineObject {
  41. public:
  42. Vector() : _size(0), _capacity(0), _buffer(NULL) {
  43. // Empty
  44. }
  45. Vector(const Vector& inVector) : _size(inVector._size), _capacity(inVector._capacity), _buffer(NULL) {
  46. if (_capacity > 0) {
  47. _buffer = allocate(_capacity);
  48. for (size_t i = 0; i < _size; ++i) {
  49. construct(_buffer + i, inVector._buffer[i]);
  50. }
  51. }
  52. }
  53. Vector& operator=(Vector& inVector) {
  54. if (this != &inVector) {
  55. clear();
  56. deallocate(_buffer);
  57. _buffer = NULL;
  58. _size = inVector._size;
  59. _capacity = inVector._capacity;
  60. if (_capacity > 0) {
  61. _buffer = allocate(_capacity);
  62. for (size_t i = 0; i < _size; ++i) {
  63. construct(_buffer + i, inVector._buffer[i]);
  64. }
  65. }
  66. }
  67. return *this;
  68. }
  69. ~Vector() {
  70. clear();
  71. deallocate(_buffer);
  72. }
  73. bool contains(const T& inValue) {
  74. for (size_t i = 0; i < _size; ++i) {
  75. if (_buffer[i] == inValue) {
  76. return true;
  77. }
  78. }
  79. return false;
  80. }
  81. int indexOf(const T& inValue) {
  82. for (size_t i = 0; i < _size; ++i) {
  83. if (_buffer[i] == inValue) {
  84. return static_cast<int>(i);
  85. }
  86. }
  87. return -1;
  88. }
  89. void push_back(const T& inValue) {
  90. if (_size == _capacity) {
  91. reserve();
  92. }
  93. construct(_buffer + _size++, inValue);
  94. }
  95. void insert(size_t inIndex, const T& inValue) {
  96. assert(inIndex < _size);
  97. if (_size == _capacity) {
  98. reserve();
  99. }
  100. for (size_t i = ++_size - 1; i > inIndex; --i) {
  101. construct(_buffer + i, _buffer[i - 1]);
  102. destroy(_buffer + (i - 1));
  103. }
  104. construct(_buffer + inIndex, inValue);
  105. }
  106. void erase(size_t inIndex) {
  107. assert(inIndex < _size);
  108. --_size;
  109. if (inIndex != _size) {
  110. for (size_t i = inIndex; i < _size; ++i) {
  111. std::swap(_buffer[i], _buffer[i + 1]);
  112. }
  113. }
  114. destroy(_buffer + _size);
  115. }
  116. void clear() {
  117. for (size_t i = 0; i < _size; ++i) {
  118. destroy(_buffer + (_size - 1 - i));
  119. }
  120. _size = 0;
  121. }
  122. size_t size() const {
  123. return _size;
  124. }
  125. T& operator[](size_t inIndex) {
  126. assert(inIndex < _size);
  127. return _buffer[inIndex];
  128. }
  129. void reserve(size_t inCapacity = 0) {
  130. size_t newCapacity = inCapacity > 0 ? inCapacity : _capacity > 0 ? _capacity * 2 : 1;
  131. if (newCapacity > _capacity) {
  132. _buffer = SpineExtension::realloc<T>(_buffer, newCapacity, __FILE__, __LINE__);
  133. _capacity = newCapacity;
  134. }
  135. }
  136. void setSize(size_t inValue) {
  137. assert(inValue <= _capacity);
  138. _size = inValue;
  139. }
  140. T* begin() {
  141. return &_buffer[0];
  142. }
  143. T* end() {
  144. return &_buffer[_size];
  145. }
  146. friend bool operator==(Vector<T>& lhs, Vector<T>& rhs) {
  147. if (lhs.size() != rhs.size()) {
  148. return false;
  149. }
  150. for (int i = 0, n = static_cast<int>(lhs.size()); i < n; ++i) {
  151. if (lhs[i] != rhs[i]) {
  152. return false;
  153. }
  154. }
  155. return true;
  156. }
  157. friend bool operator!=(Vector<T>& lhs, Vector<T>& rhs) {
  158. return !(lhs == rhs);
  159. }
  160. private:
  161. size_t _size;
  162. size_t _capacity;
  163. T* _buffer;
  164. T* allocate(size_t n) {
  165. assert(n > 0);
  166. T* ptr = SpineExtension::alloc<T>(n, __FILE__, __LINE__);
  167. assert(ptr);
  168. return ptr;
  169. }
  170. void deallocate(T* buffer) {
  171. if (_buffer) {
  172. SpineExtension::free(buffer, __FILE__, __LINE__);
  173. }
  174. }
  175. void construct(T* buffer, const T& val) {
  176. /// This is a placement new operator
  177. /// which basically means we are contructing a new object
  178. /// using pre-allocated memory
  179. new (buffer) T(val);
  180. }
  181. void destroy(T* buffer) {
  182. buffer->~T();
  183. }
  184. };
  185. }
  186. #endif /* Spine_Vector_h */