1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4// --------------------------------------------------------------------------------
5// SArray.h
6// --------------------------------------------------------------------------------
7
8
9#ifndef _SARRAY_H_
10#define _SARRAY_H_
11
12#include "sbuffer.h"
13
14// --------------------------------------------------------------------------------
15// SArray is a typed array wrapper around an SBuffer. It manages individual
16// constructors and destructors of array elements if avaiable, as well as providing
17// typed access.
18// --------------------------------------------------------------------------------
19
20template <typename ELEMENT, BOOL BITWISE_COPY = TRUE>
21class SArray
22{
23 private:
24
25 SBuffer m_buffer;
26
27 static COUNT_T VerifySizeRange(ELEMENT * begin, ELEMENT * end);
28
29 public:
30
31 class Iterator;
32 friend class Iterator;
33
34 SArray();
35 SArray(COUNT_T count);
36 SArray(ELEMENT * begin, ELEMENT * end);
37 ~SArray();
38
39 void Clear();
40 void Set(const SArray<ELEMENT, BITWISE_COPY> &array);
41
42 COUNT_T GetCount() const;
43 BOOL IsEmpty() const;
44
45 void SetCount(COUNT_T count);
46
47 COUNT_T GetAllocation() const;
48
49 void Preallocate(int count) const;
50 void Trim() const;
51
52 void Copy(const Iterator &to, const Iterator &from, COUNT_T size);
53 void Move(const Iterator &to, const Iterator &from, COUNT_T size);
54
55 void Copy(const Iterator &i, const ELEMENT *source, COUNT_T size);
56 void Copy(void *dest, const Iterator &i, COUNT_T size);
57
58 Iterator Append()
59 {
60 WRAPPER_NO_CONTRACT;
61
62 COUNT_T count = GetCount();
63 if ( GetAllocation() == count )
64 Preallocate( 2 * count );
65
66 Iterator i = End();
67 Insert(i);
68 return i;
69 }
70
71 void Append(ELEMENT elem)
72 {
73 WRAPPER_NO_CONTRACT;
74 *Append() = elem;
75 }
76
77 ELEMENT AppendEx(ELEMENT elem)
78 {
79 WRAPPER_NO_CONTRACT;
80
81 *Append() = elem;
82 return elem;
83 }
84
85 void Insert(const Iterator &i);
86 void Delete(const Iterator &i);
87
88 void Insert(const Iterator &i, COUNT_T count);
89 void Delete(const Iterator &i, COUNT_T count);
90
91 void Replace(const Iterator &i, COUNT_T deleteCount, COUNT_T insertCount);
92
93 ELEMENT *OpenRawBuffer(COUNT_T maxElementCount);
94 ELEMENT *OpenRawBuffer();
95 void CloseRawBuffer(COUNT_T actualElementCount);
96 void CloseRawBuffer();
97
98 Iterator Begin()
99 {
100 WRAPPER_NO_CONTRACT;
101 return Iterator(this, 0);
102 }
103
104 Iterator End()
105 {
106 WRAPPER_NO_CONTRACT;
107 return Iterator(this, GetCount());
108 }
109
110 Iterator operator+(COUNT_T index)
111 {
112 return Iterator(this, index);
113 }
114
115 ELEMENT & operator[] (int index);
116 const ELEMENT & operator[] (int index) const;
117
118 ELEMENT & operator[] (COUNT_T index);
119 const ELEMENT & operator[] (COUNT_T index) const;
120
121 protected:
122 SArray(void *prealloc, COUNT_T size);
123
124 public:
125
126 class Iterator : public CheckedIteratorBase<SArray<ELEMENT, BITWISE_COPY> >,
127 public Indexer<ELEMENT, Iterator>
128 {
129 friend class SArray;
130 friend class Indexer<ELEMENT, Iterator>;
131
132 SBuffer::Iterator m_i;
133
134 public:
135
136 Iterator(SArray *array, SCOUNT_T index)
137 : CheckedIteratorBase<SArray<ELEMENT, BITWISE_COPY> >(array)
138 {
139 WRAPPER_NO_CONTRACT;
140 m_i = array->m_buffer.Begin() + index*sizeof(ELEMENT);
141 }
142
143 protected:
144
145 ELEMENT &GetAt(SCOUNT_T delta) const
146 {
147 LIMITED_METHOD_CONTRACT;
148 return * (ELEMENT *) &m_i[delta*sizeof(ELEMENT)];
149 }
150
151 void Skip(SCOUNT_T delta)
152 {
153 LIMITED_METHOD_CONTRACT;
154 m_i += delta*sizeof(ELEMENT);
155 }
156
157 COUNT_T Subtract(const Iterator &i) const
158 {
159 LIMITED_METHOD_CONTRACT;
160 return (m_i - i.m_i)/sizeof(ELEMENT);
161 }
162
163 CHECK DoCheck(SCOUNT_T delta) const
164 {
165 WRAPPER_NO_CONTRACT;
166 return m_i.CheckIndex(delta*sizeof(ELEMENT));
167 }
168
169 public:
170
171 CHECK Check() const
172 {
173 WRAPPER_NO_CONTRACT;
174 return m_i.Check();
175 }
176 };
177
178 ELEMENT *GetElements() const;
179
180 private:
181
182 //--------------------------------------------------------------------
183 // Routines for managing the buffer content.
184 //--------------------------------------------------------------------
185
186 void ConstructBuffer(const Iterator &i, COUNT_T size);
187 void CopyConstructBuffer(const Iterator &i, COUNT_T size, const ELEMENT *from);
188 void DestructBuffer(const Iterator &i, COUNT_T size);
189};
190
191// ================================================================================
192// InlineSArray : Tempate for an SArray with preallocated element space
193// ================================================================================
194
195template <typename ELEMENT, COUNT_T SIZE, BOOL BITWISE_COPY = TRUE>
196class InlineSArray : public SArray<ELEMENT, BITWISE_COPY>
197{
198 private:
199#ifdef _MSC_VER
200#pragma warning(push)
201#pragma warning(disable:4200) // zero sized array
202#pragma warning(disable:4324) // don't complain if DECLSPEC_ALIGN actually pads
203 DECLSPEC_ALIGN(BUFFER_ALIGNMENT) BYTE m_prealloc[SIZE*sizeof(ELEMENT)];
204#pragma warning(pop)
205#else
206 // use UINT64 to get maximum alignment of the memory
207 UINT64 m_prealloc[ALIGN(SIZE*sizeof(ELEMENT),sizeof(UINT64))/sizeof(UINT64)];
208#endif // _MSC_VER
209
210 public:
211 InlineSArray();
212};
213
214// ================================================================================
215// StackSArray : SArray with relatively large preallocated buffer for stack use
216// ================================================================================
217
218template <typename ELEMENT, BOOL BITWISE_COPY = TRUE>
219class StackSArray : public InlineSArray<ELEMENT, STACK_ALLOC/sizeof(ELEMENT), BITWISE_COPY>
220{
221};
222
223// ================================================================================
224// Inline definitions
225// ================================================================================
226
227#include "sarray.inl"
228
229#endif // _SARRAY_H_
230