|
- #pragma once
-
- #include <vector>
- #include <ecs/config.h>
-
- namespace ecs {
- namespace core {
- namespace utils {
-
- /**
- * vector with ordered elements
- */
- template<
- typename T_value,
- typename T_allocator = std::allocator<T_value>,
- typename T_compare = std::less<T_value>>
- struct ordered_vector
- {
- public:
- using value_type = T_value;
- using allocator_type = T_allocator;
- using compare_type = T_compare;
- using this_type = ordered_vector<value_type, allocator_type, compare_type>;
- using vector_type = std::vector<value_type, allocator_type>;
- using size_type = typename vector_type::size_type;
- using difference_type = typename vector_type::difference_type;
- using reference = typename vector_type::reference;
- using const_reference = typename vector_type::const_reference;
- using pointer = typename vector_type::pointer;
- using const_pointer = typename vector_type::const_pointer;
- using iterator = typename vector_type::iterator;
- using const_iterator = typename vector_type::const_iterator;
- using reverse_iterator = typename vector_type::reverse_iterator;
- using const_reverse_iterator = typename vector_type::const_reverse_iterator;
-
- private:
- vector_type _items;
- compare_type _compare;
-
- public:
-
- /* constructor */
-
- ordered_vector() = default;
-
- ordered_vector(const ordered_vector&) = default;
- ordered_vector& operator=(const ordered_vector&) = default;
-
- ordered_vector(ordered_vector&&) = default;
- ordered_vector& operator=(ordered_vector&&) = default;
-
- template<typename... T_args>
- inline ordered_vector(T_args&&... args, const compare_type& p_compare = compare_type())
- : _items (std::forward<T_args>(args)...)
- , _compare (p_compare)
- { }
-
- /* access */
-
- inline reference operator[](size_type pos)
- noexcept(noexcept(_items.operator[](pos)))
- { return _items[pos]; }
-
- inline const_reference operator[](size_type pos) const
- noexcept(noexcept(_items.operator[](pos)))
- { return _items[pos]; }
-
- inline reference at(size_type pos)
- noexcept(noexcept(_items.at(pos)))
- { return _items.at(pos); }
-
- inline const_reference at(size_type pos) const
- noexcept(noexcept(_items.at(pos)))
- { return _items.at(pos); }
-
- /* iterators */
-
- inline iterator begin()
- noexcept(noexcept(_items.begin()))
- { return _items.begin(); }
-
- inline const_iterator begin() const
- noexcept(noexcept(_items.begin()))
- { return _items.begin(); }
-
- inline const_iterator cbegin() const
- noexcept(noexcept(_items.cbegin()))
- { return _items.cbegin(); }
-
- inline iterator end()
- noexcept(noexcept(_items.end()))
- { return _items.end(); }
-
- inline const_iterator end() const
- noexcept(noexcept(_items.end()))
- { return _items.end(); }
-
- inline const_iterator cend() const
- noexcept(noexcept(_items.cend()))
- { return _items.cend(); }
-
- inline iterator rbegin()
- noexcept(noexcept(_items.rbegin()))
- { return _items.rbegin(); }
-
- inline const_iterator rbegin() const
- noexcept(noexcept(_items.rbegin()))
- { return _items.rbegin(); }
-
- inline const_iterator crbegin() const
- noexcept(noexcept(_items.crbegin()))
- { return _items.crbegin(); }
-
- inline iterator rend()
- noexcept(noexcept(_items.rend()))
- { return _items.rend(); }
-
- inline const_iterator rend() const
- noexcept(noexcept(_items.rend()))
- { return _items.rend(); }
-
- inline const_iterator crend() const
- noexcept(noexcept(_items.crend()))
- { return _items.crend(); }
-
- /* capacity */
-
- inline bool empty() const
- noexcept(noexcept(_items.empty()))
- { return _items.empty(); }
-
- inline size_type size() const
- noexcept(noexcept(_items.size()))
- { return _items.size(); }
-
- inline size_type max_size() const
- noexcept(noexcept(_items.size()))
- { return _items.max_size(); }
-
- inline size_type capacity() const
- noexcept(noexcept(_items.capacity()))
- { return _items.capacity(); }
-
- inline void reserve(size_type s) const
- noexcept(noexcept(_items.reserve(s)))
- { _items.reserve(s); }
-
- inline void shrink_to_fit() const
- noexcept(noexcept(_items.shrink_to_fit()))
- { _items.shrink_to_fit(); }
-
- inline decltype(auto) insert(const value_type& value)
- {
- auto it = std::lower_bound(begin(), end(), value);
- auto is_new = (it != end() && _compare(value, *it));
- if (it == end() || is_new)
- _items.insert(it, value);
- return std::make_pair(it, is_new);
- }
-
- inline decltype(auto) insert(value_type&& value)
- {
- auto it = std::lower_bound(begin(), end(), value, _compare);
- auto is_new = (it != end() && _compare(value, *it));
- if (it == end() || is_new)
- _items.insert(it, std::move(value));
- return std::make_pair(it, is_new);
- }
-
- inline decltype(auto) find(const value_type& value) const
- {
- auto it = std::lower_bound(begin(), end(), value, _compare);
- return it == end() || _compare(value, *it)
- ? end()
- : it;
- }
-
- inline bool contains(const value_type& value) const
- { return find(value) != end(); }
-
- template<typename... T_args>
- constexpr decltype(auto) erase(T_args&&... args)
- { return _items.erase(std::forward<T_args>(args)...); }
-
- void clear()
- { _items.clear(); }
- };
-
- } } }
|