#ifndef _STD_VECTOR #define _STD_VECTOR #include #include #include #include #include #include #include #define TAG_UNK 0 // from key decomp namespace std { template class __vector_common { public: static void throw_length_error(); }; template class __vec_deleter_helper; template class __vec_deleter { public: typedef typename Metrowerks::compressed_pair::second_param allocator_param; typedef T value_type; typedef Allocator allocator_type; typedef size_t size_type; typedef value_type &reference; typedef const value_type &const_reference; typedef T *iterator; typedef const T *const_iterator; typedef T *pointer; typedef const pointer const_pointer; __vec_deleter() : data_(nullptr), size_(0), capacity_(0) {} explicit __vec_deleter(allocator_param a) : data_(nullptr), size_(0), capacity_(0, a) {} ~__vec_deleter(); reference operator[](size_t n) { return data_[n]; } const_reference operator[](size_t n) const { return data_[n]; } pointer data() { return data_; } iterator begin() { return data_; } iterator end() { return data_ + size_; } reference front() { return data_[0]; } const_reference front() const { return data_[0]; } reference back() { return data_[size_ - 1]; } const_reference back() const { return data_[size_ - 1]; } void throw_length_error(); #if DONT_INLINE_STD void clear() { bool _b[4]; size_t size = size_; _b[0] = false; erase_at_end(size, _b[0]); } void erase_at_end(size_t, bool &); #else void erase_at_end(const size_t n) { // erase_at_end(n, Metrowerks::int2type()); size_ -= n; } void clear() { erase_at_end(size()); } #endif // void erase_at_end(size_t n, Metrowerks::int2type) DONT_INLINE_CLASS { // T* e = end(); // size_ -= n; // while (n != 0) { // e--; // e->~T(); // n--; // } // } size_t &cap() { return capacity_.first(); } Allocator alloc() const { return capacity_.second(); } iterator erase(iterator __first, iterator __last, UnkMSLStruct1); void sub_push_back(const_reference x, Metrowerks::int2type); void sub_push_back(const_reference x, Metrowerks::int2type); void sub_push_back(const_reference x) { sub_push_back(x, Metrowerks::int2type::value && Metrowerks::has_trivial_assignment::value>()); } void push_back(const_reference x, Metrowerks::int2type) { if (size_ < cap()) { alloc().construct(end(), x); size_++; } else { sub_push_back(x); } } void push_back(const_reference x, Metrowerks::int2type) { if (size_ < cap()) { size_++; back() = x; } else { sub_push_back(x); } } void push_back(const_reference x) { push_back(x, Metrowerks::int2type::value && Metrowerks::has_trivial_assignment::value>()); } void allocate(size_t min, size_t max) { allocate(min, max, Metrowerks::int2type()); } void allocate(size_t min, size_t max, Metrowerks::int2type t) { allocate(max, t); } void allocate(size_t n) { allocate(n, Metrowerks::int2type()); } void allocate(size_t n, Metrowerks::int2type t); void optimize_after_moved_from() { optimize_after_moved_from(Metrowerks::int2type()); } void optimize_after_moved_from(Metrowerks::int2type) { size_ = 0; } bool expand_by(size_t n) { size_t max_cap = 0; return expand_by(n, max_cap, Metrowerks::int2type()); } bool expand_by(size_t n, size_t &max_cap, Metrowerks::int2type) { max_cap = grow_by(n); return false; } size_t grow_by(size_t n); void append_realloc(size_t n, const_reference x); size_t max_size() const { return alloc().max_size(); } size_t capacity() const { return capacity_.first(); } volatile size_t size() { return size_; } void resize(size_t n) { size_ = n; } void move_construct_to_end(iterator begin, iterator end); void reallocate_copy(size_t n) { __vec_deleter tmp(alloc()); tmp.allocate(n); tmp.move_construct_to_end(begin(), end()); optimize_after_moved_from(); swap(cap(), tmp.cap()); swap(data_, tmp.data_); swap(size_, tmp.size_); } void reserve(size_t n) { if (n > cap()) { reallocate_copy(n); } } bool empty() const { return size_ == 0; } public: T *data_; size_t size_; Metrowerks::compressed_pair capacity_; }; template __vec_deleter::~__vec_deleter() { UnkMSLStruct1 unk = UnkMSLStruct1(); // somehow needed if (data_ != nullptr) { clear(); alloc().deallocate(data_, cap()); } } template size_t __vec_deleter::grow_by(size_t n) { size_t max = max_size(); size_t c = cap(); if (n > max - c) { __vector_common::throw_length_error(); } size_t a = max / 3; if (c < a) { return c + std::max((c + 1) * 3 / 5, n); } else if (c < a * 2) { return c + std::max((c + 1) / 2, n); } return max; } template void __vec_deleter::allocate(size_t n, Metrowerks::int2type t) { size_t max = max_size(); if (max < n) { __vector_common::throw_length_error(); } data_ = alloc().allocate(n); cap() = n; } // https://decomp.me/scratch/Yw4fn template void __vec_deleter::append_realloc(size_t n, const_reference x) { __vec_deleter_helper tmp(alloc()); size_t max = tmp.grow_by((size_ + n) - cap()); tmp.allocate(size_ + n, max); tmp.start_ = size_; tmp.construct_at_end(n, x); tmp.move_construct_to_begin(begin(), end()); optimize_after_moved_from(); std::swap(cap(), tmp.cap()); std::swap(data_, tmp.data_); std::swap(size_, tmp.size_); } template void __vec_deleter::sub_push_back(const_reference x, Metrowerks::int2type) { if (expand_by(1)) { size_++; back() = x; } else { append_realloc(1, x); } } template void __vec_deleter::sub_push_back(const_reference x, Metrowerks::int2type) { if (expand_by(1)) { size_++; back() = x; } else { append_realloc(1, x); } } template __vec_deleter::iterator __vec_deleter::erase(iterator __first, iterator __last, UnkMSLStruct1) { // adapted from https://github.com/matta/sgi-stl/blob/635eaeef4533214ec140fb17411558ad441d2996/stl/stl_vector.h#L420 if (__first != __last) { std::memmove(__first, __last, (end() - __last) * sizeof(value_type)); this->size_ -= __last - __first; } return __first; } template class __vec_deleter_helper : public __vec_deleter { protected: typedef __vec_deleter _Base; typedef _Base::allocator_param allocator_param; typedef _Base::value_type value_type; typedef _Base::allocator_type allocator_type; typedef _Base::size_type size_type; typedef _Base::reference reference; typedef _Base::const_reference const_reference; typedef _Base::pointer pointer; typedef _Base::const_pointer const_pointer; typedef _Base::iterator iterator; typedef _Base::const_iterator const_iterator; public: __vec_deleter_helper(allocator_param a) : _Base(a), start_(0) {} ~__vec_deleter_helper(); void construct_at_end(size_t n, const_reference x) { construct_at_end(n, x, Metrowerks::int2type::value>()); } void construct_at_end(size_t n, const_reference x, Metrowerks::int2type) { for (pointer p = _Base::data_ + _Base::size_; n; n--, p++, _Base::size_++) { _Base::alloc().construct(p, x); } } void construct_at_end(size_t n, const_reference x, Metrowerks::int2type) { std::fill_n(_Base::data_ + start_ + _Base::size_, n, x); _Base::size_ += n; } void move_construct_to_begin(pointer first, pointer last) { move_construct_to_begin(first, last, Metrowerks::int2type::value ? 2 : 0>()); } void move_construct_to_begin(pointer first, pointer last, Metrowerks::int2type) { for (pointer ptr = _Base::data_ + start_; first < last; start_--, _Base::size_++) { _Base::alloc().construct(--ptr, std::move(*--last)); } } void move_construct_to_begin(pointer first, pointer last, Metrowerks::int2type<2>) { size_t n = last - first; start_ -= n; memcpy(_Base::data_ + start_, first, n * sizeof(value_type)); memset(first, 0, n * sizeof(value_type)); _Base::size_ += n; } size_t start_; }; template __vec_deleter_helper::~__vec_deleter_helper() { T *start = _Base::data_ + start_; T *end = start + _Base::size_; while (start < end) { _Base::alloc().destroy(end); end--; } _Base::size_ = 0; } template class __vec_constructor : public __vec_deleter { protected: typedef __vec_deleter _Base; typedef _Base::allocator_param allocator_param; typedef _Base::value_type value_type; typedef _Base::allocator_type allocator_type; typedef _Base::size_type size_type; typedef _Base::reference reference; typedef _Base::const_reference const_reference; typedef _Base::pointer pointer; typedef _Base::const_pointer const_pointer; typedef _Base::iterator iterator; typedef _Base::const_iterator const_iterator; public: __vec_constructor() {} // ~__vec_constructor(); }; template class __vec_constructor : public __vec_constructor { protected: typedef __vec_deleter _Deleter; typedef __vec_constructor _Constructor; typedef _Constructor::allocator_param allocator_param; typedef _Constructor::value_type value_type; typedef _Constructor::allocator_type allocator_type; typedef _Constructor::size_type size_type; typedef _Constructor::reference reference; typedef _Constructor::const_reference const_reference; typedef _Constructor::pointer pointer; typedef _Constructor::const_pointer const_pointer; typedef _Constructor::iterator iterator; typedef _Constructor::const_iterator const_iterator; __vec_constructor() {} // ~__vec_constructor() { } public: void push_back(const_reference x) { _Constructor::push_back(x); } reference operator[](size_t n) { return _Deleter::operator[](n); } const_reference operator[](size_t n) const { return _Deleter::operator[](n); } }; // clang-format off template > class vector : public __vec_constructor { // clang-format on protected: typedef __vec_constructor _Constructor; typedef __vec_deleter _Deleter; typedef _Constructor::allocator_param allocator_param; typedef _Constructor::value_type value_type; typedef _Constructor::allocator_type allocator_type; typedef _Constructor::size_type size_type; typedef _Constructor::reference reference; typedef _Constructor::const_reference const_reference; typedef _Constructor::pointer pointer; typedef _Constructor::const_pointer const_pointer; public: typedef _Constructor::iterator iterator; typedef _Constructor::const_iterator const_iterator; vector() {} ~vector() { } void push_back(const_reference x) { _Constructor::push_back(x); } void clear() { _Deleter::clear(); } reference operator[](size_t n) { return _Deleter::operator[](n); } const_reference operator[](size_t n) const { return _Deleter::operator[](n); } iterator erase(iterator __first, iterator __last) { return _Deleter::erase(__first, __last, UnkMSLStruct1()); } }; } // namespace std template class CustomVector : public std::vector { public: protected: typedef std::vector _Vector; typedef _Vector::allocator_param allocator_param; typedef _Vector::value_type value_type; typedef _Vector::allocator_type allocator_type; typedef _Vector::size_type size_type; typedef _Vector::reference reference; typedef _Vector::const_reference const_reference; typedef _Vector::pointer pointer; typedef _Vector::const_pointer const_pointer; public: typedef _Vector::iterator iterator; typedef _Vector::const_iterator const_iterator; ~CustomVector(); iterator unk_action2(iterator begin, iterator end, UnkMSLStruct1) { iterator it = begin; while (it != end) { T *ptr = (T *) *it; if (ptr != NULL) { if (*((u8 *) ptr + 4)) { ::operator delete(ptr); } *it = NULL; } it++; begin = this->begin(); end = this->end(); } return std::remove(begin, end, (T) NULL); } void unk_action1() { this->erase(this->unk_action2(this->begin(), this->end(), UnkMSLStruct1()), this->end()); this->clear(); } }; template CustomVector::~CustomVector() { UnkMSLStruct1 unk = UnkMSLStruct1(); // somehow needed if (_Vector::begin() != nullptr) { _Vector::clear(); _Vector::alloc().deallocate(_Vector::begin(), _Vector::cap()); } } #endif