No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

189 líneas
6.2 KiB

  1. #pragma once
  2. #include <vector>
  3. #include <ecs/config.h>
  4. namespace ecs {
  5. namespace core {
  6. namespace utils {
  7. /**
  8. * vector with ordered elements
  9. */
  10. template<
  11. typename T_value,
  12. typename T_allocator = std::allocator<T_value>,
  13. typename T_compare = std::less<T_value>>
  14. struct ordered_vector
  15. {
  16. public:
  17. using value_type = T_value;
  18. using allocator_type = T_allocator;
  19. using compare_type = T_compare;
  20. using this_type = ordered_vector<value_type, allocator_type, compare_type>;
  21. using vector_type = std::vector<value_type, allocator_type>;
  22. using size_type = typename vector_type::size_type;
  23. using difference_type = typename vector_type::difference_type;
  24. using reference = typename vector_type::reference;
  25. using const_reference = typename vector_type::const_reference;
  26. using pointer = typename vector_type::pointer;
  27. using const_pointer = typename vector_type::const_pointer;
  28. using iterator = typename vector_type::iterator;
  29. using const_iterator = typename vector_type::const_iterator;
  30. using reverse_iterator = typename vector_type::reverse_iterator;
  31. using const_reverse_iterator = typename vector_type::const_reverse_iterator;
  32. private:
  33. vector_type _items;
  34. compare_type _compare;
  35. public:
  36. /* constructor */
  37. ordered_vector() = default;
  38. ordered_vector(const ordered_vector&) = default;
  39. ordered_vector& operator=(const ordered_vector&) = default;
  40. ordered_vector(ordered_vector&&) = default;
  41. ordered_vector& operator=(ordered_vector&&) = default;
  42. template<typename... T_args>
  43. inline ordered_vector(T_args&&... args, const compare_type& p_compare = compare_type())
  44. : _items (std::forward<T_args>(args)...)
  45. , _compare (p_compare)
  46. { }
  47. /* access */
  48. inline reference operator[](size_type pos)
  49. noexcept(noexcept(_items.operator[](pos)))
  50. { return _items[pos]; }
  51. inline const_reference operator[](size_type pos) const
  52. noexcept(noexcept(_items.operator[](pos)))
  53. { return _items[pos]; }
  54. inline reference at(size_type pos)
  55. noexcept(noexcept(_items.at(pos)))
  56. { return _items.at(pos); }
  57. inline const_reference at(size_type pos) const
  58. noexcept(noexcept(_items.at(pos)))
  59. { return _items.at(pos); }
  60. /* iterators */
  61. inline iterator begin()
  62. noexcept(noexcept(_items.begin()))
  63. { return _items.begin(); }
  64. inline const_iterator begin() const
  65. noexcept(noexcept(_items.begin()))
  66. { return _items.begin(); }
  67. inline const_iterator cbegin() const
  68. noexcept(noexcept(_items.cbegin()))
  69. { return _items.cbegin(); }
  70. inline iterator end()
  71. noexcept(noexcept(_items.end()))
  72. { return _items.end(); }
  73. inline const_iterator end() const
  74. noexcept(noexcept(_items.end()))
  75. { return _items.end(); }
  76. inline const_iterator cend() const
  77. noexcept(noexcept(_items.cend()))
  78. { return _items.cend(); }
  79. inline iterator rbegin()
  80. noexcept(noexcept(_items.rbegin()))
  81. { return _items.rbegin(); }
  82. inline const_iterator rbegin() const
  83. noexcept(noexcept(_items.rbegin()))
  84. { return _items.rbegin(); }
  85. inline const_iterator crbegin() const
  86. noexcept(noexcept(_items.crbegin()))
  87. { return _items.crbegin(); }
  88. inline iterator rend()
  89. noexcept(noexcept(_items.rend()))
  90. { return _items.rend(); }
  91. inline const_iterator rend() const
  92. noexcept(noexcept(_items.rend()))
  93. { return _items.rend(); }
  94. inline const_iterator crend() const
  95. noexcept(noexcept(_items.crend()))
  96. { return _items.crend(); }
  97. /* capacity */
  98. inline bool empty() const
  99. noexcept(noexcept(_items.empty()))
  100. { return _items.empty(); }
  101. inline size_type size() const
  102. noexcept(noexcept(_items.size()))
  103. { return _items.size(); }
  104. inline size_type max_size() const
  105. noexcept(noexcept(_items.size()))
  106. { return _items.max_size(); }
  107. inline size_type capacity() const
  108. noexcept(noexcept(_items.capacity()))
  109. { return _items.capacity(); }
  110. inline void reserve(size_type s) const
  111. noexcept(noexcept(_items.reserve(s)))
  112. { _items.reserve(s); }
  113. inline void shrink_to_fit() const
  114. noexcept(noexcept(_items.shrink_to_fit()))
  115. { _items.shrink_to_fit(); }
  116. inline decltype(auto) insert(const value_type& value)
  117. {
  118. auto it = std::lower_bound(begin(), end(), value);
  119. auto is_new = (it != end() && _compare(value, *it));
  120. if (it == end() || is_new)
  121. _items.insert(it, value);
  122. return std::make_pair(it, is_new);
  123. }
  124. inline decltype(auto) insert(value_type&& value)
  125. {
  126. auto it = std::lower_bound(begin(), end(), value, _compare);
  127. auto is_new = (it != end() && _compare(value, *it));
  128. if (it == end() || is_new)
  129. _items.insert(it, std::move(value));
  130. return std::make_pair(it, is_new);
  131. }
  132. inline decltype(auto) find(const value_type& value) const
  133. {
  134. auto it = std::lower_bound(begin(), end(), value, _compare);
  135. return it == end() || _compare(value, *it)
  136. ? end()
  137. : it;
  138. }
  139. inline bool contains(const value_type& value) const
  140. { return find(value) != end(); }
  141. template<typename... T_args>
  142. constexpr decltype(auto) erase(T_args&&... args)
  143. { return _items.erase(std::forward<T_args>(args)...); }
  144. void clear()
  145. { _items.clear(); }
  146. };
  147. } } }