1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #ifndef _micxx_array_h
26 #define _micxx_array_h
27
28 #include <new>
29 #include "atomic.h"
30 #include "memory.h"
31 #include "arraytraits.h"
32
33 MI_BEGIN_NAMESPACE
34
35 template<class TYPE>
36 class Array
37 {
38 public:
39
40 Array();
41
42 Array(const Array<TYPE>& x);
43 mike 1.1
44 Array(const TYPE* data, MI_Uint32 size);
45
46 ~Array();
47
48 Array& operator=(const Array<TYPE>& x);
49
50 MI_Uint32 GetSize() const;
51
52 const TYPE* GetData() const;
53
54 TYPE* GetWritableData();
55
56 const TYPE& operator[](MI_Uint32 index) const;
57
58 TYPE& operator[](MI_Uint32 index);
59
60 void Clear();
61
62 void Resize(MI_Uint32 size, const TYPE& item = TYPE());
63
64 mike 1.1 /* ATTN: Can we rename of "Remove" */
65 void Delete(MI_Uint32 index);
66
67 /* ATTN: Can we rename of "PushBack" */
68 void PushBack(const TYPE& item);
69
70 private:
71
72 void cow();
73
74 struct Header
75 {
76 AtomicType m_refCounter;
77 MI_Uint32 m_capacity;
78 };
79
80 static Header* GetHeader(TYPE* buf)
81 {
82 return reinterpret_cast<Header*>(
83 reinterpret_cast<char*>(buf) - sizeof(Header));
84 }
85 mike 1.1
86 static const ArrayTraits* traits()
87 {
88 return GetArrayTraits<TYPE>();
89 }
90
91 // for compatability with "C", it must have only one pointer and a size
92 // field - NO CHANGES ALLOWED!
93 TYPE* m_data;
94 MI_Uint32 m_size;
95 };
96
97 MI_EXTERN_C MICXX_LINKAGE void __ArrayCopyCtor(void* v_this,
98 const ArrayTraits* v_traits, const void* v_obj, MI_Uint32 size);
99
100 MI_EXTERN_C MICXX_LINKAGE void __ArrayAssign(void* v_this,
101 const ArrayTraits* v_traits, const void* v_other);
102
103 MI_EXTERN_C MICXX_LINKAGE void __ArrayCOW(void* v_this,
104 const ArrayTraits* v_traits);
105
106 mike 1.1 MI_EXTERN_C MICXX_LINKAGE void __ArrayResize(void* v_this,
107 const ArrayTraits* v_traits, const void* v_obj, MI_Uint32 new_size);
108
109 MI_EXTERN_C MICXX_LINKAGE void __ArrayDelete(void* v_this,
110 const ArrayTraits* v_traits, MI_Uint32 index);
111
112 template<class TYPE>
113 inline Array<TYPE>::Array() : m_data(0), m_size(0)
114 {
115 }
116
117 template<class TYPE>
118 inline MI_Uint32 Array<TYPE>::GetSize() const
119 {
120 return m_size;
121 }
122
123 template<class TYPE>
124 inline const TYPE* Array<TYPE>::GetData() const
125 {
126 return m_data;
127 mike 1.1 }
128
129 template<class TYPE>
130 inline TYPE* Array<TYPE>::GetWritableData()
131 {
132 cow();
133 return m_data;
134 }
135
136 template<class TYPE>
137 inline const TYPE& Array<TYPE>::operator[](MI_Uint32 index) const
138 {
139 return m_data[index];
140 }
141
142 template<class TYPE>
143 inline TYPE& Array<TYPE>::operator[](MI_Uint32 index)
144 {
145 cow();
146 return m_data[index];
147 }
148 mike 1.1
149 template<class TYPE>
150 inline void Array<TYPE>::Clear()
151 {
152 __ArrayAssign(this,traits(),0);
153 m_data = 0;
154 m_size = 0;
155 }
156
157 template<class TYPE>
158 inline Array<TYPE>::Array(const TYPE* data, MI_Uint32 size)
159 {
160 if (!size)
161 {
162 m_data = 0;
163 m_size = 0;
164 }
165 else
166 {
167 __ArrayCopyCtor(this, traits(), data, size);
168 }
169 mike 1.1 }
170
171 template<class TYPE>
172 inline Array<TYPE>::~Array()
173 {
174 __ArrayAssign(this,traits(),0);
175 }
176
177 template<class TYPE>
178 inline Array<TYPE>::Array(const Array<TYPE>& x): m_data(0), m_size(0)
179 {
180 *this = x;
181 }
182
183 template<class TYPE>
184 inline Array<TYPE>& Array<TYPE>::operator=(const Array<TYPE>& x)
185 {
186 if (m_data != x.m_data)
187 {
188 __ArrayAssign(this,traits(),&x);
189 }
190 mike 1.1 return *this;
191 }
192
193 template<class TYPE>
194 inline void Array<TYPE>::cow()
195 {
196 if ( m_data && AtomicGet(GetHeader(m_data)->m_refCounter) != 1 )
197 __ArrayCOW(this,traits());
198 }
199
200 template<class TYPE>
201 inline void Array<TYPE>::PushBack(const TYPE& item)
202 {
203 Resize(GetSize() + 1, item);
204 }
205
206 template<class TYPE>
207 inline void Array<TYPE>::Resize(MI_Uint32 size, const TYPE& item)
208 {
209 if (GetSize() == size)
210 return;
211 mike 1.1
212 __ArrayResize(this, traits(), &item, size);
213
214 }
215
216 template<class TYPE>
217 inline void Array<TYPE>::Delete(MI_Uint32 index)
218 {
219 /* ATTN: what does this do? */
220 if (GetSize() == 1)
221 {
222 Clear();
223 return;
224 }
225
226 __ArrayDelete(this, traits(), index);
227 }
228
229 MI_END_NAMESPACE
230
231 #endif /* _micxx_array_h */
|