diff options
Diffstat (limited to 'src/inc/sarray.inl')
-rw-r--r-- | src/inc/sarray.inl | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/src/inc/sarray.inl b/src/inc/sarray.inl new file mode 100644 index 0000000000..d7e396c9ba --- /dev/null +++ b/src/inc/sarray.inl @@ -0,0 +1,377 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// -------------------------------------------------------------------------------- +// SArray.inl +// -------------------------------------------------------------------------------- + +#ifndef _SARRAY_INL_ +#define _SARRAY_INL_ + +#include "sarray.h" + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline SArray<ELEMENT, BITWISE_COPY>::SArray() + : m_buffer() +{ + LIMITED_METHOD_CONTRACT; +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline SArray<ELEMENT, BITWISE_COPY>::SArray(COUNT_T count) + : m_buffer(count * sizeof(ELEMENT)) +{ + WRAPPER_NO_CONTRACT; + ConstructBuffer(Begin(), count); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline COUNT_T SArray<ELEMENT, BITWISE_COPY>::VerifySizeRange(ELEMENT * begin, ELEMENT *end) +{ + WRAPPER_NO_CONTRACT; + + if (end < begin) + ThrowHR(COR_E_OVERFLOW); + + SIZE_T bufferSize = (end - begin) * sizeof(ELEMENT); + if (!FitsIn<COUNT_T>(bufferSize)) + ThrowHR(COR_E_OVERFLOW); + + return static_cast<COUNT_T>(bufferSize); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline SArray<ELEMENT, BITWISE_COPY>::SArray(ELEMENT * begin, ELEMENT * end) + : m_buffer(VerifySizeRange(begin, end)) +{ + WRAPPER_NO_CONTRACT; + + CopyConstructBuffer(Begin(), static_cast<COUNT_T>(end - begin), begin); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline SArray<ELEMENT, BITWISE_COPY>::SArray(void *prealloc, COUNT_T count) + : m_buffer(SBuffer::Prealloc, prealloc, count*sizeof(ELEMENT)) +{ + LIMITED_METHOD_CONTRACT; +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +SArray<ELEMENT, BITWISE_COPY>::~SArray() +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + GC_NOTRIGGER; + } + CONTRACTL_END; + + // Cannot call Clear because DestructBuffer has THROWS in its contract + if (!BITWISE_COPY) + { + COUNT_T elementCount = GetCount(); + for (COUNT_T i = 0; i < elementCount; i++) + { + (&((*this)[i]))->~ELEMENT(); + } + } +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Clear() +{ + WRAPPER_NO_CONTRACT; + DestructBuffer(Begin(), GetCount()); + m_buffer.Clear(); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline ELEMENT* SArray<ELEMENT, BITWISE_COPY>::OpenRawBuffer(COUNT_T elementCount) +{ + WRAPPER_NO_CONTRACT; + return (ELEMENT*)m_buffer.OpenRawBuffer(elementCount * sizeof(ELEMENT)); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline ELEMENT* SArray<ELEMENT, BITWISE_COPY>::OpenRawBuffer() +{ + WRAPPER_NO_CONTRACT; + return (ELEMENT*)m_buffer.OpenRawBuffer(GetCount() * sizeof(ELEMENT)); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::CloseRawBuffer(COUNT_T finalElementCount) +{ + WRAPPER_NO_CONTRACT; + m_buffer.CloseRawBuffer(finalElementCount * sizeof(ELEMENT)); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::CloseRawBuffer() +{ + WRAPPER_NO_CONTRACT; + m_buffer.CloseRawBuffer(); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Set(const SArray<ELEMENT, BITWISE_COPY> &array) +{ + WRAPPER_NO_CONTRACT; + if (BITWISE_COPY) + { + m_buffer.Set(array.m_buffer); + } + else + { + DestructBuffer(Begin(), GetCount()); + m_buffer.SetSize(0); + m_buffer.SetSize(array.m_buffer.GetSize()); + CopyConstructBuffer(Begin(), GetCount(), array.GetElements()); + } +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline COUNT_T SArray<ELEMENT, BITWISE_COPY>::GetCount() const +{ + WRAPPER_NO_CONTRACT; + return m_buffer.GetSize()/sizeof(ELEMENT); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline BOOL SArray<ELEMENT, BITWISE_COPY>::IsEmpty() const +{ + WRAPPER_NO_CONTRACT; + return GetCount() == 0; +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::SetCount(COUNT_T count) +{ + WRAPPER_NO_CONTRACT; + COUNT_T oldCount = GetCount(); + if (count > oldCount) + ConstructBuffer(Begin() + oldCount, count - oldCount); + + m_buffer.SetSize(count*sizeof(ELEMENT)); + + if (oldCount > count) + DestructBuffer(Begin() + count, oldCount - count); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline COUNT_T SArray<ELEMENT, BITWISE_COPY>::GetAllocation() const +{ + WRAPPER_NO_CONTRACT; + return m_buffer.GetAllocation() / sizeof(ELEMENT); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Preallocate(int count) const +{ + WRAPPER_NO_CONTRACT; + m_buffer.Preallocate(count * sizeof(ELEMENT)); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Trim() const +{ + WRAPPER_NO_CONTRACT; + m_buffer.Trim(); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Copy(const Iterator &to, const Iterator &from, COUNT_T size) +{ + WRAPPER_NO_CONTRACT; + // @todo: destruction/construction semantics are broken on overlapping copies + + DestructBuffer(to, size); + + CopyConstructBuffer(to, size, from); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Move(const Iterator &to, const Iterator &from, COUNT_T size) +{ + // @todo: destruction/construction semantics are broken on overlapping moves + + DestructBuffer(to, size); + + m_buffer.Move(to, from, size*sizeof(ELEMENT)); + + ConstructBuffer(from, size); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Copy(const Iterator &i, const ELEMENT *source, COUNT_T size) +{ + WRAPPER_NO_CONTRACT; + DestructBuffer(i, size); + + CopyConstructBuffer(i, size, source); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Copy(void *dest, const Iterator &i, COUNT_T size) +{ + WRAPPER_NO_CONTRACT; + // @todo: destruction/construction semantics are unclear + + m_buffer.Copy(dest, i.m_i, size*sizeof(ELEMENT)); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Insert(const Iterator &i) +{ + WRAPPER_NO_CONTRACT; + Replace(i, 0, 1); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Delete(const Iterator &i) +{ + WRAPPER_NO_CONTRACT; + Replace(i, 1, 0); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Insert(const Iterator &i, COUNT_T count) +{ + WRAPPER_NO_CONTRACT; + Replace(i, 0, count); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::Delete(const Iterator &i, COUNT_T count) +{ + Delete(i, 0, count); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>:: Replace(const Iterator &i, COUNT_T deleteCount, COUNT_T insertCount) +{ + WRAPPER_NO_CONTRACT; + DestructBuffer(i, deleteCount); + + m_buffer.Replace(i.m_i, deleteCount*sizeof(ELEMENT), insertCount*sizeof(ELEMENT)); + + ConstructBuffer(i, insertCount); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline ELEMENT &SArray<ELEMENT, BITWISE_COPY>::operator[](int index) +{ + WRAPPER_NO_CONTRACT; + return *(GetElements() + index); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline const ELEMENT &SArray<ELEMENT, BITWISE_COPY>::operator[](int index) const +{ + WRAPPER_NO_CONTRACT; + return *(GetElements() + index); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline ELEMENT &SArray<ELEMENT, BITWISE_COPY>::operator[](COUNT_T index) +{ + WRAPPER_NO_CONTRACT; + return *(GetElements() + index); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline const ELEMENT &SArray<ELEMENT, BITWISE_COPY>::operator[](COUNT_T index) const +{ + return *(GetElements() + index); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline ELEMENT *SArray<ELEMENT, BITWISE_COPY>::GetElements() const +{ + LIMITED_METHOD_CONTRACT; + return (ELEMENT *) (const BYTE *) m_buffer; +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::ConstructBuffer(const Iterator &i, COUNT_T size) +{ + CONTRACTL + { + THROWS; + GC_NOTRIGGER; + } + CONTRACTL_END; + + if (!BITWISE_COPY) + { + ELEMENT *start = GetElements() + (i - Begin()); + ELEMENT *end = start + size; + + while (start < end) + { + new (start) ELEMENT(); + start++; + } + } +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::CopyConstructBuffer(const Iterator &i, COUNT_T size, const ELEMENT *from) +{ + ptrdiff_t start_offset = i - Begin(); + ELEMENT *p = (ELEMENT *) m_buffer.OpenRawBuffer(m_buffer.GetSize()) + start_offset; + + if (BITWISE_COPY) + { + memmove(p, from, size * sizeof(ELEMENT)); + } + else + { + ELEMENT *start = (ELEMENT *) p; + ELEMENT *end = (ELEMENT *) (p + size); + + while (start < end) + { + new (start) ELEMENT(*from); + + start++; + from++; + } + } + + m_buffer.CloseRawBuffer(); +} + +template <typename ELEMENT, BOOL BITWISE_COPY> +inline void SArray<ELEMENT, BITWISE_COPY>::DestructBuffer(const Iterator &i, COUNT_T size) +{ + CONTRACTL + { + THROWS; + GC_NOTRIGGER; + } + CONTRACTL_END; + + if (!BITWISE_COPY) + { + ELEMENT *start = GetElements() + (i - Begin()); + ELEMENT *end = start + size; + + while (start < end) + { + start->ELEMENT::~ELEMENT(); + + start++; + } + } +} + +template <typename ELEMENT, COUNT_T SIZE, BOOL BITWISE_COPY> +inline InlineSArray<ELEMENT, SIZE, BITWISE_COPY>::InlineSArray() + : SArray<ELEMENT, BITWISE_COPY>((void*)m_prealloc, SIZE) +{ + LIMITED_METHOD_CONTRACT; +} + +#endif // _SARRAY_INL_ |