Files
tp/include/JSystem/JGadget/std-vector.h
T

225 lines
6.2 KiB
C++
Raw Normal View History

2021-03-28 22:49:05 +02:00
#ifndef STD_VECTOR_H
#define STD_VECTOR_H
2026-01-10 13:39:15 -08:00
#include "JSystem/JGadget/define.h"
2024-11-29 08:24:26 -08:00
#include "JSystem/JGadget/std-memory.h"
#include <algorithm>
#include <memory>
#include <stdint>
2024-11-29 08:24:26 -08:00
namespace JGadget {
namespace vector {
2025-11-30 14:23:42 -08:00
u32 extend_default(u32, u32, u32);
2024-11-29 08:24:26 -08:00
};
typedef u32 (*extendFunc)(u32, u32, u32);
template <typename T, typename Allocator = JGadget::TAllocator<T> >
struct TVector {
struct TDestructed_deallocate_ {
TDestructed_deallocate_(JGadget::TAllocator<T>& allocator, T* ptr) {
mAllocator = &allocator;
mPtr = ptr;
}
~TDestructed_deallocate_() { mAllocator->deallocate(mPtr, 0); }
void set(T* ptr) { mPtr = ptr; }
Allocator* mAllocator;
T* mPtr;
};
2025-12-15 20:00:16 -05:00
typedef T* iterator;
typedef const T* const_iterator;
2024-11-29 08:24:26 -08:00
TVector(Allocator const& allocator) {
2026-01-10 13:39:15 -08:00
#if PLATFORM_GCN
2024-11-29 08:24:26 -08:00
mAllocator = allocator;
2026-01-10 13:39:15 -08:00
#endif
2024-11-29 08:24:26 -08:00
pBegin_ = NULL;
pEnd_ = pBegin_;
mCapacity = 0;
pfnExtend_ = JGadget::vector::extend_default;
}
~TVector() {
2026-01-10 13:39:15 -08:00
#if DEBUG
Confirm();
#endif
2024-11-29 08:24:26 -08:00
clear();
2026-01-10 13:39:15 -08:00
JGADGET_ASSERTWARN(250, size()==0);
2024-11-29 08:24:26 -08:00
mAllocator.deallocate(pBegin_, 0);
}
void insert(T* pos, u32 count, const T& val) {
2026-01-10 13:39:15 -08:00
if (count == 0) {
return;
}
T* ptr = Insert_raw(pos, count);
if (ptr == end()) {
JGADGET_WARNMSG(321, "can't allocate memory");
} else {
std::uninitialized_fill_n(ptr, count, val);
2024-11-29 08:24:26 -08:00
}
}
2026-01-10 13:39:15 -08:00
T* Insert_raw(T* pFirst, u32 pCount) {
T* const pIt = pFirst;
JUT_ASSERT(446, (pBegin_<=pIt)&&(pIt<=pEnd_));
2024-11-29 08:24:26 -08:00
if (pCount == 0) {
2026-01-10 13:39:15 -08:00
return pFirst;
2024-11-29 08:24:26 -08:00
}
if (pCount + size() <= mCapacity) {
2026-01-10 13:39:15 -08:00
void** newEnd = pIt + pCount;
2024-11-29 08:24:26 -08:00
if (newEnd < pEnd_) {
void** pOverwrittenValues = pEnd_ - pCount;
std::uninitialized_copy(pOverwrittenValues, pEnd_, pEnd_);
2026-01-10 13:39:15 -08:00
std::copy_backward(pIt, pOverwrittenValues, pEnd_);
DestroyElement_(pIt, newEnd);
2024-11-29 08:24:26 -08:00
pEnd_ += pCount;
2026-01-10 13:39:15 -08:00
return pFirst;
2024-11-29 08:24:26 -08:00
} else {
2026-01-10 13:39:15 -08:00
std::uninitialized_copy(pIt, pEnd_, newEnd);
DestroyElement_(pIt, pEnd_);
2024-11-29 08:24:26 -08:00
pEnd_ += pCount;
2026-01-10 13:39:15 -08:00
return pFirst;
2024-11-29 08:24:26 -08:00
}
}
u32 newSize = GetSize_extend_(pCount);
void** newDataPointer = mAllocator.allocate(newSize, 0);
if (!newDataPointer) {
return end();
}
TDestructed_deallocate_ destructionDeallocator(mAllocator, newDataPointer);
2026-01-10 13:39:15 -08:00
void** const endOfCopy = std::uninitialized_copy(pBegin_, pIt, newDataPointer);
std::uninitialized_copy(pIt, pEnd_, endOfCopy + pCount);
2024-11-29 08:24:26 -08:00
DestroyElement_all_();
destructionDeallocator.set(pBegin_);
pEnd_ = newDataPointer + (pEnd_ - pBegin_ + pCount);
pBegin_ = newDataPointer;
mCapacity = newSize;
return endOfCopy;
}
2025-04-09 16:45:30 -04:00
T* insert(T* pos, const T& val) {
2025-09-04 07:56:59 -07:00
u32 diff = (int)((uintptr_t)pos - (uintptr_t)begin()) / 4;
2025-04-09 16:45:30 -04:00
insert(pos, 1, val);
return pBegin_ + diff;
}
2024-11-29 08:24:26 -08:00
2025-12-15 20:00:16 -05:00
iterator begin() { return pBegin_; }
const_iterator begin() const { return pBegin_; }
iterator end() { return pEnd_; }
const_iterator end() const { return pEnd_; }
2025-04-09 16:45:30 -04:00
u32 size() const {
2024-11-29 08:24:26 -08:00
if (pBegin_ == 0) {
return 0;
}
2025-09-04 07:56:59 -07:00
return (int)((uintptr_t)pEnd_ - (uintptr_t)pBegin_) / 4;
2024-11-29 08:24:26 -08:00
}
2026-01-10 13:39:15 -08:00
u32 capacity() const { return mCapacity; }
2024-11-29 08:24:26 -08:00
2026-01-10 13:39:15 -08:00
bool Confirm() const {
if (size() > mCapacity) {
JGADGET_WARNMSG(507, "illegal size");
return false;
}
return true;
}
u32 GetSize_extend_(u32 count) const {
JUT_ASSERT(555, pfnExtend_!=NULL);
2024-11-29 08:24:26 -08:00
u32 oldSize = size();
u32 neededNewSpace = oldSize + count;
u32 extendedSize = pfnExtend_(capacity(), oldSize, count);
return neededNewSpace > extendedSize ? neededNewSpace : extendedSize;
}
2026-01-10 13:39:15 -08:00
void DestroyElement_(T* pFirst, T* pLast) {
JUT_ASSERT(536, (pBegin_<=pFirst)&&(pFirst<=pEnd_));
JUT_ASSERT(537, (pBegin_<=pLast)&&(pLast<=pEnd_));
T* it = pFirst;
for (; it != pLast; it++) {
mAllocator.destroy(it);
2024-11-29 08:24:26 -08:00
}
}
void DestroyElement_all_() { DestroyElement_(pBegin_, pEnd_); }
2026-01-10 13:39:15 -08:00
T* erase(T* pFirst, T* pLast) {
iterator pItFirst = pFirst;
iterator pItLast = pLast;
JUT_ASSERT(347, (pBegin_<=pItFirst)&&(pItFirst<=pEnd_))
JUT_ASSERT(348, (pBegin_<=pItLast)&&(pItLast<=pEnd_));
JUT_ASSERT(349, pItFirst<=pItLast);
T* vectorEnd = pEnd_; // DEBUG NONMATCHING
T* ppvVar3 = std::copy(pItLast, vectorEnd, pItFirst);
2024-11-29 08:24:26 -08:00
DestroyElement_(ppvVar3, pEnd_);
pEnd_ = ppvVar3;
2026-01-10 13:39:15 -08:00
return pFirst;
2024-11-29 08:24:26 -08:00
}
void clear() { erase(begin(), end()); }
/* 0x00 */ Allocator mAllocator;
/* 0x04 */ T* pBegin_;
/* 0x08 */ T* pEnd_;
/* 0x0C */ u32 mCapacity;
/* 0x10 */ extendFunc pfnExtend_;
};
struct TVector_pointer_void : public TVector<void*, TAllocator<void*> > {
TVector_pointer_void(const JGadget::TAllocator<void*>& allocator);
TVector_pointer_void(u32, void* const&,
const JGadget::TAllocator<void*>& allocator);
~TVector_pointer_void();
void insert(void**, void* const&);
void** erase(void**, void**);
void clear() { erase(begin(), end()); }
2025-11-19 04:13:35 +02:00
void push_back(void* const& value) { insert(end(), (void* const&)value); }
2024-11-29 08:24:26 -08:00
};
2025-04-09 16:45:30 -04:00
template <typename T>
struct TVector_pointer : TVector_pointer_void {
TVector_pointer(const TAllocator<void*>& allocator) : TVector_pointer_void(allocator) {}
~TVector_pointer() {}
2025-12-15 20:00:16 -05:00
typedef T* iterator;
typedef const T* const_iterator;
2025-04-09 16:45:30 -04:00
const T* begin() const { return (const T*)TVector_pointer_void::begin(); }
T* begin() { return (T*)TVector_pointer_void::begin(); }
const T* end() const { return (const T*)TVector_pointer_void::end(); }
T* end() { return (T*)TVector_pointer_void::end(); }
void push_back(const T& ref) {
2025-11-19 04:13:35 +02:00
static_cast<TVector_pointer_void*>(this)->push_back((void* const&)ref);
2025-04-09 16:45:30 -04:00
}
};
2024-11-29 08:24:26 -08:00
} // namespace JGadget
2021-03-28 22:49:05 +02:00
#endif /* STD_VECTOR_H */