Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef VECTOR_H
- #define VECTOR_H
- /**
- * @class Vector
- * Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use Vector for large arrays.
- */
- #include "core/error/error_macros.h"
- #include "core/templates/cowdata.h"
- #include <algorithm>
- #include <initializer_list>
- #include <numeric>
- template <class T>
- class Vector {
- public:
- using Iterator = T *;
- using ConstIterator = const T *;
- using ReverseIterator = std::reverse_iterator<Iterator>;
- using ConstReverseIterator = std::reverse_iterator<ConstIterator>;
- private:
- CowData<T> _cowdata;
- template <class Begin, class End>
- _NO_DISCARD_ static int _find(const Begin beginIter, const End endIter, const T &p_value) {
- const auto iter = std::find(beginIter, endIter, p_value);
- return iter == endIter ? -1 : static_cast<int>(std::distance(beginIter, iter));
- }
- public:
- Vector() = default;
- explicit Vector(const int p_size) {
- _cowdata.resize(p_size);
- }
- Vector(const int p_size, const T &p_value) :
- Vector(p_size) {
- fill(p_value);
- }
- Vector(std::initializer_list<T> p_init) {
- const Error err = _cowdata.resize(p_init.size());
- ERR_FAIL_COND(err);
- std::copy(std::begin(p_init), std::end(p_init), begin());
- }
- Vector(Vector &p_from) :
- _cowdata{ p_from._cowdata } {
- }
- Vector(const Vector &p_from) = delete;
- Vector &operator=(Vector &p_from) {
- _cowdata = p_from._cowdata;
- return *this;
- }
- Vector &operator=(const Vector &p_from) = delete;
- ~Vector() = default;
- _NO_DISCARD_ bool operator==(const Vector<T> &p_arr) const {
- return std::equal(begin(), end(), p_arr.begin(), p_arr.end());
- }
- _NO_DISCARD_ bool operator!=(const Vector<T> &p_arr) const {
- return !(*this == p_arr);
- }
- _NO_DISCARD_ Vector<T> duplicate() {
- return *this;
- }
- _NO_DISCARD_ Iterator begin() { return _cowdata.ptrw(); }
- _NO_DISCARD_ Iterator end() { return _cowdata.ptrw() + _cowdata.size(); }
- _NO_DISCARD_ ConstIterator begin() const { return _cowdata.ptr(); }
- _NO_DISCARD_ ConstIterator end() const { return _cowdata.ptr() + _cowdata.size(); }
- _NO_DISCARD_ ConstIterator cbegin() const { return begin(); }
- _NO_DISCARD_ ConstIterator cend() const { return end(); }
- _NO_DISCARD_ ReverseIterator rbegin() { return std::reverse_iterator{ end() }; }
- _NO_DISCARD_ ReverseIterator rend() { return std::reverse_iterator{ begin() }; }
- _NO_DISCARD_ ConstReverseIterator rbegin() const { return std::reverse_iterator{ end() }; }
- _NO_DISCARD_ ConstReverseIterator rend() const { return std::reverse_iterator{ begin() }; }
- _NO_DISCARD_ ConstReverseIterator crbegin() const { return rbegin(); }
- _NO_DISCARD_ ConstReverseIterator crend() const { return rend(); }
- _NO_DISCARD_ T *ptrw() { return _cowdata.ptrw(); }
- _NO_DISCARD_ const T *ptr() const { return _cowdata.ptr(); }
- _NO_DISCARD_ const T &get(const int p_index) const {
- return _cowdata.get(p_index);
- }
- _NO_DISCARD_ void set(const int p_index, const T &p_elem) {
- _cowdata.set(p_index, p_elem);
- }
- _NO_DISCARD_ int size() const {
- return _cowdata.size();
- }
- _NO_DISCARD_ bool is_empty() const {
- return _cowdata.is_empty();
- }
- bool append(const T &p_elem) {
- const Error err = resize(size() + 1);
- ERR_FAIL_COND_V(err, true);
- set(size() - 1, p_elem);
- return false;
- }
- bool append(Vector<T> p_other) {
- const int ds = p_other.size();
- if (ds == 0) {
- return;
- }
- const int bs = size();
- resize(bs + ds);
- if (p_other._cowdata._get_refcount()->get() == 1) {
- std::move(p_other.begin(), p_other.end(), begin() + bs);
- } else {
- std::copy(p_other.cbegin(), p_other.cend(), begin() + bs);
- }
- }
- Error insert(const int p_pos, const T &p_val) {
- return _cowdata.insert(p_pos, p_val);
- }
- void ordered_insert(const T &p_val) {
- const auto iter = std::find_if(begin(), end(), [&](const T &p_other) { return p_val < p_other; });
- insert(static_cast<int>(std::distance(begin(), iter)), p_val);
- }
- void remove_at(const int p_index) {
- _cowdata.remove_at(p_index);
- }
- void erase(const T &p_val) {
- const ConstIterator beginIter = cbegin();
- const ConstIterator endIter = cend();
- const auto iter = std::find(beginIter, endIter, p_val);
- if (iter != endIter) {
- remove_at(static_cast<int>(std::distance(beginIter, iter)));
- }
- }
- void clear() {
- _cowdata.resize(0);
- }
- Error resize(const int p_size) {
- return _cowdata.resize(p_size);
- }
- void fill(const T &p_elem) {
- std::fill(begin(), end(), p_elem);
- }
- void reverse() {
- std::reverse(begin(), end());
- }
- _NO_DISCARD_ int find(const T &p_value, const int p_from = 0) const {
- return _find(begin() + p_from, end(), p_value);
- }
- _NO_DISCARD_ int rfind(const T &p_value, const int p_from = 0) const {
- return _find(rbegin() + p_from, rend(), p_value);
- }
- _NO_DISCARD_ int count(const T &p_val) const {
- return std::count(begin(), end(), p_val);
- }
- _NO_DISCARD_ bool has(const T &p_value) const {
- const auto endItr = end();
- return std::find(begin(), endItr, p_value) != endItr;
- }
- void sort() {
- sort_custom<std::less<>>();
- }
- template <class Comparator, class... Args>
- void sort_custom(Args &&...args) {
- std::sort(begin(), end(), Comparator{ std::forward<Args>(args)... });
- }
- _NO_DISCARD_ int bsearch(const T &p_value, bool p_before) const {
- return bsearch_custom<std::less<>>(p_value, p_before);
- }
- template <class Comparator, class Value, class... Args>
- _NO_DISCARD_ int bsearch_custom(const Value &p_value, bool p_before, Args &&...args) const {
- const ConstIterator beginIter = begin();
- const ConstIterator endIter = end();
- const ConstIterator iter = p_before
- ? std::lower_bound(beginIter, endIter, p_value, Comparator{ std::forward<Args>(args)... })
- : std::upper_bound(beginIter, endIter, p_value, Comparator{ std::forward<Args>(args)... });
- return iter == endIter ? -1 : static_cast<int>(std::distance(beginIter, iter));
- }
- _NO_DISCARD_ Vector<uint8_t> to_byte_array() const {
- if (is_empty()) {
- return {};
- }
- const int ret_size = size() * sizeof(T);
- Vector<uint8_t> ret(ret_size);
- memcpy(ret.ptrw(), ptr(), ret_size);
- return ret;
- }
- _NO_DISCARD_ Vector<T> slice(const int p_begin, const int p_end = std::numeric_limits<int>::max()) const {
- const int s = size();
- int begin_index = CLAMP(p_begin, -s, s);
- if (begin_index < 0) {
- begin_index += s;
- }
- int end_index = CLAMP(p_end, -s, s);
- if (end_index < 0) {
- end_index += s;
- }
- Vector<T> result;
- ERR_FAIL_COND_V(begin_index > end_index, result);
- const int result_size = end_index - begin_index;
- result.resize(result_size);
- const ConstIterator beginIter = begin() + begin_index;
- std::copy(beginIter,beginIter + result_size,result.begin());
- return result;
- }
- };
- #endif // VECTOR_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement