Move the alignment-aware allocator and vector to headers
This commit is contained in:
+1
-32
@@ -104,37 +104,6 @@ ALsizei GetACNIndex(const BFChannelConfig *chans, ALsizei numchans, ALsizei acn)
|
||||
}
|
||||
#define GetChannelForACN(b, a) GetACNIndex((b).Ambi.Map, (b).NumChannels, (a))
|
||||
|
||||
|
||||
template<typename T, size_t alignment>
|
||||
class aligned_allocator : public std::allocator<T> {
|
||||
public:
|
||||
using size_type = size_t;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
using other = aligned_allocator<U, alignment>;
|
||||
};
|
||||
|
||||
pointer allocate(size_type n, const void* = nullptr)
|
||||
{ return reinterpret_cast<T*>(al_malloc(alignment, n*sizeof(T))); }
|
||||
|
||||
void deallocate(pointer p, size_type)
|
||||
{ al_free(p); }
|
||||
|
||||
aligned_allocator() : std::allocator<T>() { }
|
||||
aligned_allocator(const aligned_allocator &a) : std::allocator<T>(a) { }
|
||||
template<class U>
|
||||
aligned_allocator(const aligned_allocator<U,alignment> &a)
|
||||
: std::allocator<T>(a)
|
||||
{ }
|
||||
~aligned_allocator() { }
|
||||
};
|
||||
|
||||
template<typename T, size_t alignment>
|
||||
using aligned_vector = std::vector<T, aligned_allocator<T, alignment>>;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -149,7 +118,7 @@ struct BFormatDec {
|
||||
|
||||
BandSplitter XOver[MAX_AMBI_COEFFS];
|
||||
|
||||
aligned_vector<std::array<ALfloat,BUFFERSIZE>, 16> Samples;
|
||||
al::vector<std::array<ALfloat,BUFFERSIZE>, 16> Samples;
|
||||
/* These two alias into Samples */
|
||||
std::array<ALfloat,BUFFERSIZE> *SamplesHF;
|
||||
std::array<ALfloat,BUFFERSIZE> *SamplesLF;
|
||||
|
||||
+21
-50
@@ -1,65 +1,32 @@
|
||||
#ifndef AL_VECTOR_H
|
||||
#define AL_VECTOR_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "almalloc.h"
|
||||
|
||||
|
||||
#define TYPEDEF_VECTOR(T, N) typedef struct { \
|
||||
size_t Capacity; \
|
||||
size_t Size; \
|
||||
std::size_t Capacity; \
|
||||
std::size_t Size; \
|
||||
T Data[]; \
|
||||
} _##N; \
|
||||
typedef _##N* N; \
|
||||
typedef const _##N* const_##N;
|
||||
|
||||
#define VECTOR(T) struct { \
|
||||
size_t Capacity; \
|
||||
size_t Size; \
|
||||
std::size_t Capacity; \
|
||||
std::size_t Size; \
|
||||
T Data[]; \
|
||||
}*
|
||||
|
||||
#define VECTOR_INIT(_x) do { (_x) = NULL; } while(0)
|
||||
#define VECTOR_INIT_STATIC() NULL
|
||||
#define VECTOR_DEINIT(_x) do { al_free((_x)); (_x) = NULL; } while(0)
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define VECTOR_RESIZE(_x, _s, _c) do { \
|
||||
size_t _size = (_s); \
|
||||
size_t _cap = (_c); \
|
||||
if(_size > _cap) \
|
||||
_cap = _size; \
|
||||
\
|
||||
if(!(_x) && _cap == 0) \
|
||||
break; \
|
||||
\
|
||||
if(((_x) ? (_x)->Capacity : 0) < _cap) \
|
||||
{ \
|
||||
ptrdiff_t data_offset = (_x) ? (char*)((_x)->Data) - (char*)(_x) : \
|
||||
sizeof(*(_x)); \
|
||||
size_t old_size = ((_x) ? (_x)->Size : 0); \
|
||||
void *temp; \
|
||||
\
|
||||
temp = al_calloc(16, data_offset + sizeof((_x)->Data[0])*_cap); \
|
||||
assert(temp != NULL); \
|
||||
if((_x)) \
|
||||
memcpy(((char*)temp)+data_offset, (_x)->Data, \
|
||||
sizeof((_x)->Data[0])*old_size); \
|
||||
\
|
||||
al_free((_x)); \
|
||||
(_x) = temp; \
|
||||
(_x)->Capacity = _cap; \
|
||||
} \
|
||||
(_x)->Size = _size; \
|
||||
} while(0) \
|
||||
|
||||
#else
|
||||
#define VECTOR_INIT(_x) do { (_x) = nullptr; } while(0)
|
||||
#define VECTOR_INIT_STATIC() nullptr
|
||||
#define VECTOR_DEINIT(_x) do { al_free((_x)); (_x) = nullptr; } while(0)
|
||||
|
||||
template<typename T>
|
||||
inline void do_vector_resize(T *&vec, size_t size, size_t cap)
|
||||
inline void do_vector_resize(T *&vec, std::size_t size, std::size_t cap)
|
||||
{
|
||||
if(size > cap)
|
||||
cap = size;
|
||||
@@ -71,12 +38,9 @@ inline void do_vector_resize(T *&vec, size_t size, size_t cap)
|
||||
{
|
||||
ptrdiff_t data_offset = vec ? (char*)(vec->Data) - (char*)(vec) : sizeof(*vec);
|
||||
size_t old_size = (vec ? vec->Size : 0);
|
||||
T *temp;
|
||||
|
||||
temp = reinterpret_cast<T*>(al_calloc(16, data_offset + sizeof(vec->Data[0])*cap));
|
||||
assert(temp != nullptr);
|
||||
if(vec)
|
||||
memcpy(temp->Data, vec->Data, sizeof(vec->Data[0])*old_size);
|
||||
auto temp = static_cast<T*>(al_calloc(16, data_offset + sizeof(vec->Data[0])*cap));
|
||||
if(vec) std::memcpy(temp->Data, vec->Data, sizeof(vec->Data[0])*old_size);
|
||||
|
||||
al_free(vec);
|
||||
vec = temp;
|
||||
@@ -85,7 +49,6 @@ inline void do_vector_resize(T *&vec, size_t size, size_t cap)
|
||||
vec->Size = size;
|
||||
}
|
||||
#define VECTOR_RESIZE(_x, _s, _c) do_vector_resize(_x, _s, _c)
|
||||
#endif // __cplusplus
|
||||
|
||||
#define VECTOR_CAPACITY(_x) ((_x) ? (_x)->Capacity : 0)
|
||||
#define VECTOR_SIZE(_x) ((_x) ? (_x)->Size : 0)
|
||||
@@ -94,7 +57,7 @@ inline void do_vector_resize(T *&vec, size_t size, size_t cap)
|
||||
#define VECTOR_END(_x) ((_x) ? (_x)->Data + (_x)->Size : NULL)
|
||||
|
||||
#define VECTOR_PUSH_BACK(_x, _obj) do { \
|
||||
size_t _pbsize = VECTOR_SIZE(_x)+1; \
|
||||
std::size_t _pbsize = VECTOR_SIZE(_x)+1; \
|
||||
VECTOR_RESIZE(_x, _pbsize, _pbsize); \
|
||||
(_x)->Data[(_x)->Size-1] = (_obj); \
|
||||
} while(0)
|
||||
@@ -123,4 +86,12 @@ inline void do_vector_resize(T *&vec, size_t size, size_t cap)
|
||||
(_i) = _iter; \
|
||||
} while(0)
|
||||
|
||||
|
||||
namespace al {
|
||||
|
||||
template<typename T, size_t alignment=DEF_ALIGN>
|
||||
using vector = std::vector<T, al::allocator<T, alignment>>;
|
||||
|
||||
} // namespace al
|
||||
|
||||
#endif /* AL_VECTOR_H */
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <memory>
|
||||
#include <limits>
|
||||
|
||||
/* Minimum alignment required by posix_memalign. */
|
||||
#define DEF_ALIGN sizeof(void*)
|
||||
|
||||
@@ -28,4 +31,39 @@ int al_is_sane_alignment_allocator(void) noexcept;
|
||||
} \
|
||||
void operator delete(void *block) noexcept { al_free(block); }
|
||||
|
||||
namespace al {
|
||||
|
||||
template<typename T, size_t alignment=DEF_ALIGN>
|
||||
struct allocator : public std::allocator<T> {
|
||||
using size_type = size_t;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
using other = allocator<U, alignment>;
|
||||
};
|
||||
|
||||
pointer allocate(size_type n, const void* = nullptr)
|
||||
{
|
||||
if(n > std::numeric_limits<size_t>::max() / sizeof(T))
|
||||
throw std::bad_alloc();
|
||||
|
||||
void *ret{al_malloc(alignment, n*sizeof(T))};
|
||||
if(!ret) throw std::bad_alloc();
|
||||
return static_cast<pointer>(ret);
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type)
|
||||
{ al_free(p); }
|
||||
|
||||
allocator() : std::allocator<T>() { }
|
||||
allocator(const allocator &a) : std::allocator<T>(a) { }
|
||||
template<class U>
|
||||
allocator(const allocator<U,alignment> &a) : std::allocator<T>(a)
|
||||
{ }
|
||||
};
|
||||
|
||||
} // namespace al
|
||||
|
||||
#endif /* AL_MALLOC_H */
|
||||
|
||||
Reference in New Issue
Block a user