1 #ifndef _DEARRAYBUFFER_HPP
2 #define _DEARRAYBUFFER_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements C++ Base Library
5 * -----------------------------
7 * Copyright 2014 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
24 *//*--------------------------------------------------------------------*/
36 void* ArrayBuffer_AlignedMalloc (size_t numBytes, size_t alignment);
37 void ArrayBuffer_AlignedFree (void*);
41 //! Array buffer self-test.
42 void ArrayBuffer_selfTest (void);
44 /*--------------------------------------------------------------------*//*!
45 * \brief Contiguous array that does not initialize its elements.
46 *//*--------------------------------------------------------------------*/
47 template <typename T, size_t Alignment = (sizeof(T) > 4 ? 4 : sizeof(T)), size_t Stride = sizeof(T)>
51 DE_STATIC_ASSERT(Stride >= sizeof(T));
53 ArrayBuffer (void) throw();
54 ArrayBuffer (size_t numElements);
55 ArrayBuffer (const T* ptr, size_t numElements);
56 ArrayBuffer (const ArrayBuffer& other);
57 ~ArrayBuffer (void) throw();
58 ArrayBuffer& operator= (const ArrayBuffer& other);
60 void clear (void) throw();
61 void setStorage (size_t numElements); // !< \note after a succesful call buffer contents are undefined
62 void swap (ArrayBuffer& other) throw();
63 size_t size (void) const throw();
64 bool empty (void) const throw();
66 T* getElementPtr (size_t elementNdx) throw();
67 const T* getElementPtr (size_t elementNdx) const throw();
68 void* getPtr (void) throw();
69 const void* getPtr (void) const throw();
74 } DE_WARN_UNUSED_TYPE;
76 template <typename T, size_t Alignment, size_t Stride>
77 ArrayBuffer<T,Alignment,Stride>::ArrayBuffer (void) throw()
83 template <typename T, size_t Alignment, size_t Stride>
84 ArrayBuffer<T,Alignment,Stride>::ArrayBuffer (size_t numElements)
90 // \note no need to allocate stride for the last element, sizeof(T) is enough. Also handles cases where sizeof(T) > Stride
91 const size_t storageSize = (numElements - 1) * Stride + sizeof(T);
92 void* const ptr = detail::ArrayBuffer_AlignedMalloc(storageSize, Alignment);
95 throw std::bad_alloc();
102 template <typename T, size_t Alignment, size_t Stride>
103 ArrayBuffer<T,Alignment,Stride>::ArrayBuffer (const T* ptr, size_t numElements)
109 // create new buffer of wanted size, copy to it, and swap to it
110 ArrayBuffer<T,Alignment,Stride> tmp(numElements);
112 if (Stride == sizeof(T))
115 const size_t storageSize = sizeof(T) * numElements;
116 deMemcpy(tmp.m_ptr, ptr, (int)storageSize);
121 for (size_t ndx = 0; ndx < numElements; ++ndx)
122 *tmp.getElementPtr(ndx) = ptr[ndx];
129 template <typename T, size_t Alignment, size_t Stride>
130 ArrayBuffer<T,Alignment,Stride>::ArrayBuffer (const ArrayBuffer<T,Alignment,Stride>& other)
136 // copy to temporary and swap to it
138 const size_t storageSize = (other.m_cap - 1) * Stride + sizeof(T);
139 ArrayBuffer tmp (other.m_cap);
141 deMemcpy(tmp.m_ptr, other.m_ptr, (int)storageSize);
146 template <typename T, size_t Alignment, size_t Stride>
147 ArrayBuffer<T,Alignment,Stride>::~ArrayBuffer (void) throw()
152 template <typename T, size_t Alignment, size_t Stride>
153 ArrayBuffer<T,Alignment,Stride>& ArrayBuffer<T,Alignment,Stride>::operator= (const ArrayBuffer& other)
155 ArrayBuffer copied(other);
160 template <typename T, size_t Alignment, size_t Stride>
161 void ArrayBuffer<T,Alignment,Stride>::clear (void) throw()
163 detail::ArrayBuffer_AlignedFree(m_ptr);
169 template <typename T, size_t Alignment, size_t Stride>
170 void ArrayBuffer<T,Alignment,Stride>::setStorage (size_t numElements)
172 // create new buffer of the wanted size, swap to it
173 ArrayBuffer<T,Alignment,Stride> newBuffer(numElements);
177 template <typename T, size_t Alignment, size_t Stride>
178 void ArrayBuffer<T,Alignment,Stride>::swap (ArrayBuffer& other) throw()
180 void* const otherPtr = other.m_ptr;
181 const size_t otherCap = other.m_cap;
189 template <typename T, size_t Alignment, size_t Stride>
190 size_t ArrayBuffer<T,Alignment,Stride>::size (void) const throw()
195 template <typename T, size_t Alignment, size_t Stride>
196 bool ArrayBuffer<T,Alignment,Stride>::empty (void) const throw()
201 template <typename T, size_t Alignment, size_t Stride>
202 T* ArrayBuffer<T,Alignment,Stride>::getElementPtr (size_t elementNdx) throw()
204 return (T*)(((deUint8*)m_ptr) + Stride * elementNdx);
207 template <typename T, size_t Alignment, size_t Stride>
208 const T* ArrayBuffer<T,Alignment,Stride>::getElementPtr (size_t elementNdx) const throw()
210 return (T*)(((deUint8*)m_ptr) + Stride * elementNdx);
213 template <typename T, size_t Alignment, size_t Stride>
214 void* ArrayBuffer<T,Alignment,Stride>::getPtr (void) throw()
219 template <typename T, size_t Alignment, size_t Stride>
220 const void* ArrayBuffer<T,Alignment,Stride>::getPtr (void) const throw()
227 #endif // _DEARRAYBUFFER_HPP