2022-10-09 05:13:17 +00:00
|
|
|
#ifndef _RSTL_VECTOR
|
|
|
|
#define _RSTL_VECTOR
|
2022-04-10 00:17:06 +00:00
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
|
2024-09-23 05:56:21 +00:00
|
|
|
#include "rstl/iterator.hpp"
|
2022-08-09 23:03:51 +00:00
|
|
|
#include "rstl/pointer_iterator.hpp"
|
|
|
|
#include "rstl/rmemory_allocator.hpp"
|
2022-04-10 00:17:06 +00:00
|
|
|
|
2022-10-09 16:34:58 +00:00
|
|
|
class CInputStream;
|
|
|
|
|
2022-04-10 00:17:06 +00:00
|
|
|
namespace rstl {
|
2022-09-13 04:26:54 +00:00
|
|
|
// template < typename T, typename Alloc >
|
|
|
|
// struct allocator_auto_ptr {
|
|
|
|
// allocator_auto_ptr(T* ptr, Alloc* alloc) : ptr(ptr) {}
|
|
|
|
// ~allocator_auto_ptr() {
|
|
|
|
// if (ptr != nullptr) {
|
|
|
|
// Alloc::deallocate(ptr);
|
|
|
|
// ptr = nullptr;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// T* release() { T* v = ptr; ptr = nullptr; return v; }
|
|
|
|
|
|
|
|
// private:
|
|
|
|
// T* ptr;
|
|
|
|
// };
|
|
|
|
|
2022-04-10 00:17:06 +00:00
|
|
|
template < typename T, typename Alloc = rmemory_allocator >
|
|
|
|
class vector {
|
2022-10-04 00:00:46 +00:00
|
|
|
protected:
|
2022-04-10 00:17:06 +00:00
|
|
|
Alloc x0_allocator;
|
2022-09-05 04:01:13 +00:00
|
|
|
int x4_count;
|
|
|
|
int x8_capacity;
|
2022-04-10 00:17:06 +00:00
|
|
|
T* xc_items;
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef pointer_iterator< T, vector< T, Alloc >, Alloc > iterator;
|
|
|
|
typedef const_pointer_iterator< T, vector< T, Alloc >, Alloc > const_iterator;
|
2022-12-05 21:35:31 +00:00
|
|
|
typedef T value_type;
|
2022-04-10 00:17:06 +00:00
|
|
|
|
2022-10-15 05:22:32 +00:00
|
|
|
iterator begin() { return iterator(xc_items); }
|
|
|
|
const_iterator begin() const { return const_iterator(xc_items); }
|
|
|
|
iterator end() { return iterator(xc_items + x4_count); }
|
|
|
|
const_iterator end() const { return const_iterator(xc_items + x4_count); }
|
2023-10-12 21:52:29 +00:00
|
|
|
vector(const Alloc& alloc = Alloc())
|
|
|
|
: x0_allocator(alloc), x4_count(0), x8_capacity(0), xc_items(nullptr) {}
|
2022-10-15 05:22:32 +00:00
|
|
|
vector(int count) : x4_count(0), x8_capacity(0), xc_items(0) { reserve(count); }
|
2022-10-01 08:32:56 +00:00
|
|
|
vector(int count, const T& v) : x4_count(count), x8_capacity(count) {
|
2022-10-04 00:00:46 +00:00
|
|
|
x0_allocator.allocate(xc_items, x4_count);
|
2022-10-01 19:00:38 +00:00
|
|
|
uninitialized_fill_n(xc_items, count, v);
|
2022-10-01 08:32:56 +00:00
|
|
|
}
|
2022-11-14 02:18:45 +00:00
|
|
|
vector(int count, const T& v, const Alloc& alloc);
|
2022-11-17 15:46:10 +00:00
|
|
|
|
2022-10-04 00:00:46 +00:00
|
|
|
vector(const vector& other) : x4_count(other.x4_count), x8_capacity(other.x8_capacity) {
|
2022-08-09 23:03:51 +00:00
|
|
|
if (other.x4_count == 0 && other.x8_capacity == 0) {
|
2022-10-04 00:00:46 +00:00
|
|
|
xc_items = nullptr;
|
2022-04-10 00:17:06 +00:00
|
|
|
} else {
|
2022-10-04 00:00:46 +00:00
|
|
|
x0_allocator.allocate(xc_items, x8_capacity);
|
|
|
|
uninitialized_copy_n(other.xc_items, x4_count, xc_items);
|
2022-04-10 00:17:06 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-15 05:22:32 +00:00
|
|
|
vector(CInputStream& in, const Alloc& alloc = Alloc());
|
2022-04-10 00:17:06 +00:00
|
|
|
~vector() {
|
2022-10-04 00:00:46 +00:00
|
|
|
destroy(begin(), end());
|
2022-04-11 22:42:08 +00:00
|
|
|
x0_allocator.deallocate(xc_items);
|
2022-04-10 00:17:06 +00:00
|
|
|
}
|
|
|
|
|
2022-09-05 04:01:13 +00:00
|
|
|
void reserve(int size);
|
2022-10-02 21:45:14 +00:00
|
|
|
void resize(int size, const T& in);
|
2022-11-17 15:46:10 +00:00
|
|
|
iterator insert(iterator it, const T& value);
|
|
|
|
|
2022-10-04 00:00:46 +00:00
|
|
|
template < typename from_iterator >
|
|
|
|
iterator insert(iterator it, from_iterator begin, from_iterator end);
|
2022-11-10 10:55:04 +00:00
|
|
|
|
2022-09-19 04:19:46 +00:00
|
|
|
iterator erase(iterator it);
|
2022-11-10 10:55:04 +00:00
|
|
|
iterator erase(iterator first, iterator last);
|
2022-04-15 19:24:52 +00:00
|
|
|
|
2022-04-10 00:17:06 +00:00
|
|
|
void push_back(const T& in) {
|
|
|
|
if (x4_count >= x8_capacity) {
|
|
|
|
reserve(x8_capacity != 0 ? x8_capacity * 2 : 4);
|
|
|
|
}
|
2023-10-17 21:36:08 +00:00
|
|
|
rstl::construct(xc_items + x4_count, in);
|
2022-04-10 00:17:06 +00:00
|
|
|
++x4_count;
|
|
|
|
}
|
|
|
|
|
2022-10-31 20:30:15 +00:00
|
|
|
vector& operator=(const vector& other);
|
2022-04-15 19:24:52 +00:00
|
|
|
|
|
|
|
void clear() {
|
2022-10-04 00:00:46 +00:00
|
|
|
destroy(begin(), end());
|
2022-04-15 19:24:52 +00:00
|
|
|
x4_count = 0;
|
|
|
|
}
|
|
|
|
|
2022-10-15 05:22:32 +00:00
|
|
|
T* data() { return xc_items; }
|
|
|
|
const T* data() const { return xc_items; }
|
|
|
|
int size() const { return x4_count; }
|
|
|
|
bool empty() const { return x4_count == 0; }
|
|
|
|
int capacity() const { return x8_capacity; }
|
|
|
|
T& at(int idx) { return xc_items[idx]; }
|
|
|
|
const T& at(int idx) const { return xc_items[idx]; }
|
|
|
|
T& front() { return at(0); }
|
|
|
|
const T& front() const { return at(0); }
|
|
|
|
T& back() { return at(x4_count - 1); }
|
|
|
|
const T& back() const { return at(x4_count - 1); }
|
|
|
|
T& operator[](int idx) { return xc_items[idx]; }
|
|
|
|
const T& operator[](int idx) const { return xc_items[idx]; }
|
2022-10-04 00:00:46 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
template < typename In >
|
2022-11-17 15:46:10 +00:00
|
|
|
iterator insert_into(iterator at, int n, In in);
|
2022-04-10 00:17:06 +00:00
|
|
|
};
|
2022-04-15 19:24:52 +00:00
|
|
|
|
2022-10-02 21:45:14 +00:00
|
|
|
template < typename T, typename Alloc >
|
|
|
|
void vector< T, Alloc >::resize(int size, const T& in) {
|
|
|
|
if (x4_count != size) {
|
|
|
|
if (size > x4_count) {
|
|
|
|
reserve(size);
|
|
|
|
uninitialized_fill_n(xc_items + x4_count, size - x4_count, in);
|
|
|
|
} else {
|
|
|
|
destroy(begin() + size, end());
|
|
|
|
}
|
|
|
|
x4_count = size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-15 19:24:52 +00:00
|
|
|
template < typename T, typename Alloc >
|
2022-10-04 00:00:46 +00:00
|
|
|
void vector< T, Alloc >::reserve(int newSize) {
|
|
|
|
if (newSize <= x8_capacity) {
|
2022-04-15 19:24:52 +00:00
|
|
|
return;
|
|
|
|
}
|
2023-10-12 21:52:29 +00:00
|
|
|
T* newData;
|
|
|
|
x0_allocator.allocate(newData, newSize);
|
2022-10-04 00:00:46 +00:00
|
|
|
uninitialized_copy(begin(), end(), newData);
|
|
|
|
destroy(xc_items, xc_items + x4_count);
|
2022-04-15 19:24:52 +00:00
|
|
|
x0_allocator.deallocate(xc_items);
|
|
|
|
xc_items = newData;
|
2022-10-04 00:00:46 +00:00
|
|
|
x8_capacity = newSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
template < typename T, typename Alloc >
|
|
|
|
typename vector< T, Alloc >::iterator vector< T, Alloc >::insert(iterator it, const T& value) {
|
2022-10-21 01:32:04 +00:00
|
|
|
typename iterator::difference_type diff = it - begin(); // distance(begin(), it);
|
2022-11-21 22:54:14 +00:00
|
|
|
|
|
|
|
// // TODO: implement
|
|
|
|
// const_counting_iterator< T > in(&value, 0);
|
|
|
|
// insert_into(it, 1, in);
|
|
|
|
|
2022-10-04 00:00:46 +00:00
|
|
|
return begin() + diff;
|
2022-04-15 19:24:52 +00:00
|
|
|
}
|
2022-08-13 01:26:00 +00:00
|
|
|
|
2022-11-17 15:46:10 +00:00
|
|
|
template < typename T, typename Alloc >
|
|
|
|
template < typename from_iterator >
|
|
|
|
typename vector< T, Alloc >::iterator vector< T, Alloc >::insert(iterator it, from_iterator begin,
|
|
|
|
from_iterator end) {
|
|
|
|
return insert_into(it, rstl::distance(begin, end), begin);
|
|
|
|
}
|
|
|
|
|
|
|
|
template < typename T, typename Alloc >
|
|
|
|
template < typename In >
|
|
|
|
typename vector< T, Alloc >::iterator vector< T, Alloc >::insert_into(iterator at, int n, In in) {
|
|
|
|
// TODO: correct
|
|
|
|
// An implementation can be found in CAnimationDatabaseGame.o
|
|
|
|
int newCount = x4_count + n;
|
|
|
|
if (newCount <= x8_capacity) {
|
|
|
|
int diffFromAt = at - begin();
|
|
|
|
int diff = x4_count - diffFromAt - 1;
|
|
|
|
|
|
|
|
for (int i = diff; 0 <= diff; --i) {
|
|
|
|
construct(xc_items + (diffFromAt + i), xc_items[i]);
|
|
|
|
destroy(data() + i);
|
|
|
|
}
|
|
|
|
|
|
|
|
uninitialized_copy_n(in, n, begin() + diffFromAt);
|
2022-11-21 22:54:14 +00:00
|
|
|
|
2022-11-17 15:46:10 +00:00
|
|
|
x4_count += n;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
int newCapacity = x8_capacity != 0 ? x8_capacity * 2 : 4;
|
2022-11-21 22:54:14 +00:00
|
|
|
for (; newCapacity < newCount; newCapacity *= 2)
|
|
|
|
;
|
2022-11-17 15:46:10 +00:00
|
|
|
T* newData;
|
|
|
|
x0_allocator.allocate(newData, newCapacity);
|
2022-11-21 22:54:14 +00:00
|
|
|
|
2022-11-17 15:46:10 +00:00
|
|
|
int diffFromAt = at - begin();
|
|
|
|
uninitialized_copy_n(begin(), diffFromAt, newData);
|
|
|
|
uninitialized_copy_n(in, n, newData + diffFromAt);
|
|
|
|
uninitialized_copy_n(begin() + diffFromAt, x4_count - diffFromAt, newData + diffFromAt + n);
|
|
|
|
destroy(xc_items, xc_items + x4_count);
|
|
|
|
x0_allocator.deallocate(xc_items);
|
|
|
|
xc_items = newData;
|
|
|
|
x8_capacity = newCapacity;
|
|
|
|
x4_count += n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-31 20:30:15 +00:00
|
|
|
template < typename T, typename Alloc >
|
|
|
|
vector< T, Alloc >& vector< T, Alloc >::operator=(const vector< T, Alloc >& other) {
|
|
|
|
if (this == &other)
|
|
|
|
return *this;
|
|
|
|
clear();
|
|
|
|
if (other.size() == 0) {
|
|
|
|
x0_allocator.deallocate(xc_items);
|
|
|
|
x4_count = 0;
|
|
|
|
x8_capacity = 0;
|
|
|
|
xc_items = nullptr;
|
|
|
|
} else {
|
|
|
|
reserve(other.size());
|
|
|
|
uninitialized_copy(other.data(), other.data() + other.size(), data());
|
|
|
|
x4_count = other.x4_count;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2022-11-10 10:55:04 +00:00
|
|
|
template < typename T, typename Alloc >
|
|
|
|
typename vector< T, Alloc >::iterator vector< T, Alloc >::erase(iterator it) {
|
|
|
|
return erase(it, it + 1);
|
|
|
|
}
|
|
|
|
|
2024-09-23 05:56:21 +00:00
|
|
|
// TODO nonmatching (CCameraManager::RemoveCinemaCamera)
|
2022-11-10 10:55:04 +00:00
|
|
|
template < typename T, typename Alloc >
|
|
|
|
typename vector< T, Alloc >::iterator vector< T, Alloc >::erase(iterator first, iterator last) {
|
|
|
|
destroy(first, last);
|
2024-09-23 05:56:21 +00:00
|
|
|
|
2022-11-10 10:55:04 +00:00
|
|
|
iterator start = begin();
|
2024-09-23 05:56:21 +00:00
|
|
|
int newCount = start - first;
|
2022-11-17 15:46:10 +00:00
|
|
|
|
2022-11-10 10:55:04 +00:00
|
|
|
iterator moved = start + newCount;
|
2024-09-23 05:56:21 +00:00
|
|
|
for (iterator it = last; it != end(); ++moved, ++newCount, ++it) {
|
2022-11-10 10:55:04 +00:00
|
|
|
construct(&*moved, *it);
|
|
|
|
}
|
|
|
|
x4_count = newCount;
|
|
|
|
|
|
|
|
return first;
|
|
|
|
}
|
2022-10-31 20:30:15 +00:00
|
|
|
|
2024-10-12 22:58:00 +00:00
|
|
|
typedef vector< int > unk_vector;
|
2022-08-13 01:26:00 +00:00
|
|
|
CHECK_SIZEOF(unk_vector, 0x10)
|
2022-04-10 00:17:06 +00:00
|
|
|
} // namespace rstl
|
|
|
|
|
2022-10-09 05:13:17 +00:00
|
|
|
#endif // _RSTL_VECTOR
|