3 #ifndef VISR_LIBEFL_ALIGNED_ARRAY_HPP_INCLUDED 4 #define VISR_LIBEFL_ALIGNED_ARRAY_HPP_INCLUDED 32 template<
typename ElementType >
57 explicit AlignedArray( std::size_t length, std::size_t alignmentElements );
78 void resize( std::size_t newLength );
91 std::size_t
size()
const {
return mLength; }
108 ElementType*
data() {
return mAlignedStorage; }
113 ElementType
const *
data( )
const {
return mAlignedStorage; }
119 ElementType&
operator[]( std::size_t index ) {
return mAlignedStorage[index]; }
125 ElementType
const &
operator[]( std::size_t index )
const {
return mAlignedStorage[index]; }
133 ElementType&
at( std::size_t index )
135 if( index >= mLength )
137 throw std::out_of_range(
"Array index exceeded" );
148 ElementType
const &
at( std::size_t index )
const 150 if( index >= mLength ) {
151 throw std::out_of_range(
"Array index exceeded" );
153 return (*
this)[index];
170 void allocate( std::size_t length );
181 const std::size_t mAlignment;
193 ElementType* mRawStorage;
200 ElementType* mAlignedStorage;
203 template<
typename ElementType>
205 : mAlignment( alignmentElements == 0 ? 1 : alignmentElements )
207 , mRawStorage( nullptr )
208 , mAlignedStorage( nullptr )
212 throw std::invalid_argument(
"AlignedArray: alignment values must be integer powers of 2" );
216 template<
typename ElementType>
227 mRawStorage =
nullptr;
228 mAlignedStorage =
nullptr;
232 template<
typename ElementType>
239 template<
typename ElementType>
242 if( mAlignment != rhs.mAlignment )
244 throw std::logic_error(
"AlignedArray:: objects in move assignment must have the same alignment." );
251 template<
typename ElementType>
257 template<
typename ElementType>
263 allocate( newLength );
273 template<
typename ElementType>
276 if( mAlignment != rhs.mAlignment )
278 throw std::logic_error(
"AlignedArray::swap(): objects to be swapped must have the same alignment." );
280 std::swap( mLength, rhs.mLength );
281 std::swap( mRawStorage, rhs.mRawStorage );
282 std::swap( mAlignedStorage, rhs.mAlignedStorage );
292 static inline void *alignWorkaround( std::size_t alignment, std::size_t size,
293 void *&ptr, std::size_t &space )
295 std::uintptr_t pn =
reinterpret_cast< std::uintptr_t
>(ptr);
296 std::uintptr_t aligned = (pn + alignment - 1) & -alignment;
297 std::size_t padding = aligned - pn;
298 if( space < size + padding )
return nullptr;
300 return ptr =
reinterpret_cast< void *
>(aligned);
304 template<
typename ElementType>
307 const std::size_t worstCaseLengthElements( length + mAlignment - 1 );
308 mRawStorage =
new ElementType[worstCaseLengthElements];
309 void* retPtr =
static_cast<void*
>(mRawStorage);
310 std::size_t space = worstCaseLengthElements*
sizeof(ElementType);
313 alignWorkaround( mAlignment*
sizeof(ElementType), length*
sizeof(ElementType), retPtr, space );
315 std::align( mAlignment*
sizeof(ElementType), length*
sizeof(ElementType), retPtr, space );
317 if( retPtr ==
nullptr )
320 throw std::bad_alloc();
323 mAlignedStorage =
static_cast<ElementType*
>(retPtr);
327 template<
typename ElementType>
330 delete[] mRawStorage;
331 mRawStorage =
nullptr;
332 mAlignedStorage =
nullptr;
339 #endif // #ifndef VISR_LIBEFL_ALIGNED_ARRAY_HPP_INCLUDED ElementType * data()
Definition: aligned_array.hpp:108
bool alignmentIsPowerOfTwo(std::size_t alignmentVal)
Definition: alignment.hpp:27
std::size_t size() const
Definition: aligned_array.hpp:91
ElementType & operator[](std::size_t index)
Definition: aligned_array.hpp:119
ElementType const & at(std::size_t index) const
Definition: aligned_array.hpp:148
void resize(std::size_t newLength)
Definition: aligned_array.hpp:258
std::size_t alignmentBytes() const
Definition: aligned_array.hpp:103
Definition: options.cpp:10
ElementType & at(std::size_t index)
Definition: aligned_array.hpp:133
ElementType const * data() const
Definition: aligned_array.hpp:113
std::size_t alignmentElements() const
Definition: aligned_array.hpp:97
~AlignedArray()
Definition: aligned_array.hpp:252
void swap(AlignedArray< ElementType > &rhs)
Definition: aligned_array.hpp:274
Definition: aligned_array.hpp:33
AlignedArray< ElementType > & operator=(AlignedArray< ElementType > &&rhs)
Definition: aligned_array.hpp:240
ElementType const & operator[](std::size_t index) const
Definition: aligned_array.hpp:125