| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- // Contains a class which will provide a uint32 array which can grow dynamically
- // It behaves almost same as regex::List<> except it has less members, is customized for being used in SmallSpanSequence of FunctionBody
- #pragma once
- #ifdef DIAG_MEM
- extern int listFreeAmount;
- #endif
- namespace JsUtil
- {
- template <class ValueType, class TAllocator>
- class GrowingArray
- {
- public:
- typedef Field(ValueType, TAllocator) TValue;
- typedef typename AllocatorInfo<TAllocator, TValue>::AllocatorType AllocatorType;
- static GrowingArray* Create(uint32 _length);
- GrowingArray(AllocatorType* allocator, uint32 _length)
- : buffer(nullptr),
- alloc(allocator),
- count(0),
- length(_length)
- {
- EnsureArray();
- }
- ~GrowingArray()
- {
- if (buffer != nullptr)
- {
- AllocatorFree(alloc, (TypeAllocatorFunc<TAllocator, int>::GetFreeFunc()), buffer, UInt32Math::Mul(length, sizeof(TValue)));
- }
- }
- TValue ItemInBuffer(uint32 index) const
- {
- if (index >= count)
- {
- return (TValue)0;
- }
- return buffer[index];
- }
- void ItemInBuffer(uint32 index, TValue item)
- {
- EnsureArray();
- Assert(index < count);
- buffer[index] = item;
- }
- void Add(TValue item)
- {
- EnsureArray();
- buffer[count] = item;
- count++;
- }
- uint32 Count() const { return count; }
- void SetCount(uint32 _count) { count = _count; }
- uint32 GetLength() const { return length; }
- TValue* GetBuffer() const { return buffer; }
- GrowingArray * Clone()
- {
- GrowingArray * pNewArray = AllocatorNew(AllocatorType, alloc, GrowingArray, alloc, length);
- pNewArray->count = count;
- if (buffer)
- {
- pNewArray->buffer = AllocateArray<AllocatorType, TValue, false>(
- TRACK_ALLOC_INFO(alloc, TValue, AllocatorType, 0, length),
- TypeAllocatorFunc<TAllocator, TValue>::GetAllocFunc(),
- length);
- CopyArray<TValue, TValue, TAllocator>(pNewArray->buffer, length, buffer, length);
- }
- return pNewArray;
- }
- private:
- Field(TValue*, TAllocator) buffer;
- Field(uint32) count;
- Field(uint32) length;
- FieldNoBarrier(AllocatorType*) alloc;
- void EnsureArray()
- {
- if (buffer == nullptr)
- {
- buffer = AllocateArray<AllocatorType, TValue, false>(
- TRACK_ALLOC_INFO(alloc, TValue, AllocatorType, 0, length),
- TypeAllocatorFunc<TAllocator, TValue>::GetAllocFunc(),
- length);
- count = 0;
- }
- else if (count == length)
- {
- uint32 newLength = UInt32Math::AddMul<1, 2>(length);
- TValue * newbuffer = AllocateArray<AllocatorType, TValue, false>(
- TRACK_ALLOC_INFO(alloc, TValue, AllocatorType, 0, newLength),
- TypeAllocatorFunc<TAllocator, TValue>::GetAllocFunc(),
- newLength);
- CopyArray<TValue, TValue, TAllocator>(newbuffer, newLength, buffer, length);
- #ifdef DIAG_MEM
- listFreeAmount += length;
- #endif
- if (length != 0)
- {
- const size_t lengthByteSize = UInt32Math::Mul(length, sizeof(TValue));
- AllocatorFree(alloc, (TypeAllocatorFunc<TAllocator, int>::GetFreeFunc()), buffer, lengthByteSize);
- }
- length = newLength;
- buffer = newbuffer;
- }
- }
- };
- typedef GrowingArray<uint32, HeapAllocator> GrowingUint32HeapArray;
- }
|