#ifndef MEMUTIL_H_
#define MEMUTIL_H_
#include "common.h"
namespace FastPFor {
template<class T, size_t alignment>
T * moveToBoundary(T * inbyte) {
return reinterpret_cast<T *> ((reinterpret_cast<uintptr_t> (inbyte)
+ (alignment - 1)) & ~(alignment - 1));
}
template<class T, size_t alignment>
class AlignedSTLAllocator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
template<class U>
struct rebind {
typedef AlignedSTLAllocator<U, alignment> other;
};
pointer address(reference value) const {
return &value;
}
const_pointer address(const_reference value) const {
return &value;
}
AlignedSTLAllocator() {
}
AlignedSTLAllocator(const AlignedSTLAllocator& ) {
}
~AlignedSTLAllocator() {
}
size_type max_size() const throw () {
return std::numeric_limits<std::size_t>::max() / sizeof(T);
}
pointer allocate(size_type num, const void* = 0) {
size_t * buffer = reinterpret_cast<size_t *> (::operator new(
sizeof(uintptr_t) + (num + alignment) * sizeof(T)));
size_t * answer = moveToBoundary<size_t, alignment> (buffer + 1);
*(answer - 1) = reinterpret_cast<uintptr_t> (answer) - reinterpret_cast<uintptr_t> (buffer);
return reinterpret_cast<pointer> (answer);
}
void construct(pointer p, const T& value) {
new (p) T(value);
}
void destroy(pointer p) {
p->~T();
}
void deallocate(pointer p, size_type ) {
const size_t * assize_t = reinterpret_cast<size_t *> (p);
const size_t offset = assize_t[-1];
::operator delete(reinterpret_cast<pointer>(reinterpret_cast<uintptr_t> (p) - offset));
}
};
template <class T1, size_t t, class T2>
bool operator== (const AlignedSTLAllocator<T1,t>&,
const T2&) throw() {
return true;
}
template <class T1, size_t t, class T2>
bool operator!= (const AlignedSTLAllocator<T1,t>&,
const T2&) throw() {
return false;
}
typedef AlignedSTLAllocator<uint32_t, 64> cacheallocator;
}
#endif