summaryrefslogtreecommitdiff
path: root/src/inc/sarray.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/sarray.h')
-rw-r--r--src/inc/sarray.h229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/inc/sarray.h b/src/inc/sarray.h
new file mode 100644
index 0000000000..ac361cf401
--- /dev/null
+++ b/src/inc/sarray.h
@@ -0,0 +1,229 @@
+// 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.h
+// --------------------------------------------------------------------------------
+
+
+#ifndef _SARRAY_H_
+#define _SARRAY_H_
+
+#include "sbuffer.h"
+
+// --------------------------------------------------------------------------------
+// SArray is a typed array wrapper around an SBuffer. It manages individual
+// constructors and destructors of array elements if avaiable, as well as providing
+// typed access.
+// --------------------------------------------------------------------------------
+
+template <typename ELEMENT, BOOL BITWISE_COPY = TRUE>
+class SArray
+{
+ private:
+
+ SBuffer m_buffer;
+
+ static COUNT_T VerifySizeRange(ELEMENT * begin, ELEMENT * end);
+
+ public:
+
+ class Iterator;
+ friend class Iterator;
+
+ SArray();
+ SArray(COUNT_T count);
+ SArray(ELEMENT * begin, ELEMENT * end);
+ ~SArray();
+
+ void Clear();
+ void Set(const SArray<ELEMENT, BITWISE_COPY> &array);
+
+ COUNT_T GetCount() const;
+ BOOL IsEmpty() const;
+
+ void SetCount(COUNT_T count);
+
+ COUNT_T GetAllocation() const;
+
+ void Preallocate(int count) const;
+ void Trim() const;
+
+ void Copy(const Iterator &to, const Iterator &from, COUNT_T size);
+ void Move(const Iterator &to, const Iterator &from, COUNT_T size);
+
+ void Copy(const Iterator &i, const ELEMENT *source, COUNT_T size);
+ void Copy(void *dest, const Iterator &i, COUNT_T size);
+
+ Iterator Append()
+ {
+ WRAPPER_NO_CONTRACT;
+
+ COUNT_T count = GetCount();
+ if ( GetAllocation() == count )
+ Preallocate( 2 * count );
+
+ Iterator i = End();
+ Insert(i);
+ return i;
+ }
+
+ void Append(ELEMENT elem)
+ {
+ WRAPPER_NO_CONTRACT;
+ *Append() = elem;
+ }
+
+ ELEMENT AppendEx(ELEMENT elem)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ *Append() = elem;
+ return elem;
+ }
+
+ void Insert(const Iterator &i);
+ void Delete(const Iterator &i);
+
+ void Insert(const Iterator &i, COUNT_T count);
+ void Delete(const Iterator &i, COUNT_T count);
+
+ void Replace(const Iterator &i, COUNT_T deleteCount, COUNT_T insertCount);
+
+ ELEMENT *OpenRawBuffer(COUNT_T maxElementCount);
+ ELEMENT *OpenRawBuffer();
+ void CloseRawBuffer(COUNT_T actualElementCount);
+ void CloseRawBuffer();
+
+ Iterator Begin()
+ {
+ WRAPPER_NO_CONTRACT;
+ return Iterator(this, 0);
+ }
+
+ Iterator End()
+ {
+ WRAPPER_NO_CONTRACT;
+ return Iterator(this, GetCount());
+ }
+
+ Iterator operator+(COUNT_T index)
+ {
+ return Iterator(this, index);
+ }
+
+ ELEMENT & operator[] (int index);
+ const ELEMENT & operator[] (int index) const;
+
+ ELEMENT & operator[] (COUNT_T index);
+ const ELEMENT & operator[] (COUNT_T index) const;
+
+ protected:
+ SArray(void *prealloc, COUNT_T size);
+
+ public:
+
+ class Iterator : public CheckedIteratorBase<SArray<ELEMENT, BITWISE_COPY> >,
+ public Indexer<ELEMENT, Iterator>
+ {
+ friend class SArray;
+ friend class Indexer<ELEMENT, Iterator>;
+
+ SBuffer::Iterator m_i;
+
+ public:
+
+ Iterator(SArray *array, SCOUNT_T index)
+ : CheckedIteratorBase<SArray<ELEMENT, BITWISE_COPY> >(array)
+ {
+ WRAPPER_NO_CONTRACT;
+ m_i = array->m_buffer.Begin() + index*sizeof(ELEMENT);
+ }
+
+ protected:
+
+ ELEMENT &GetAt(SCOUNT_T delta) const
+ {
+ LIMITED_METHOD_CONTRACT;
+ return * (ELEMENT *) &m_i[delta*sizeof(ELEMENT)];
+ }
+
+ void Skip(SCOUNT_T delta)
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_i += delta*sizeof(ELEMENT);
+ }
+
+ COUNT_T Subtract(const Iterator &i) const
+ {
+ LIMITED_METHOD_CONTRACT;
+ return (m_i - i.m_i)/sizeof(ELEMENT);
+ }
+
+ CHECK DoCheck(SCOUNT_T delta) const
+ {
+ WRAPPER_NO_CONTRACT;
+ return m_i.CheckIndex(delta*sizeof(ELEMENT));
+ }
+
+ public:
+
+ CHECK Check() const
+ {
+ WRAPPER_NO_CONTRACT;
+ return m_i.Check();
+ }
+ };
+
+ ELEMENT *GetElements() const;
+
+ private:
+
+ //--------------------------------------------------------------------
+ // Routines for managing the buffer content.
+ //--------------------------------------------------------------------
+
+ void ConstructBuffer(const Iterator &i, COUNT_T size);
+ void CopyConstructBuffer(const Iterator &i, COUNT_T size, const ELEMENT *from);
+ void DestructBuffer(const Iterator &i, COUNT_T size);
+};
+
+// ================================================================================
+// InlineSArray : Tempate for an SArray with preallocated element space
+// ================================================================================
+
+template <typename ELEMENT, COUNT_T SIZE, BOOL BITWISE_COPY = TRUE>
+class InlineSArray : public SArray<ELEMENT, BITWISE_COPY>
+{
+ private:
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4200) // zero sized array
+#pragma warning(disable:4324) // don't complain if DECLSPEC_ALIGN actually pads
+ DECLSPEC_ALIGN(BUFFER_ALIGNMENT) BYTE m_prealloc[SIZE*sizeof(ELEMENT)];
+#pragma warning(pop)
+#else
+ // use UINT64 to get maximum alignment of the memory
+ UINT64 m_prealloc[ALIGN(SIZE*sizeof(ELEMENT),sizeof(UINT64))/sizeof(UINT64)];
+#endif // _MSC_VER
+
+ public:
+ InlineSArray();
+};
+
+// ================================================================================
+// StackSArray : SArray with relatively large preallocated buffer for stack use
+// ================================================================================
+
+template <typename ELEMENT, BOOL BITWISE_COPY = TRUE>
+class StackSArray : public InlineSArray<ELEMENT, STACK_ALLOC/sizeof(ELEMENT), BITWISE_COPY>
+{
+};
+
+// ================================================================================
+// Inline definitions
+// ================================================================================
+
+#include "sarray.inl"
+
+#endif // _SARRAY_H_