First, I will start with a basic tip.
Foo* aligned_foo() {
void* raw = 0;
if(posix_memalign(&raw, 8, sizeof(Foo)))
return 0;
try{
return new(raw) Foo();
}catch(...){
free(raw);
throw;
}
}
then when you are done with Foo* foo, do foo->~Foo(); free(foo);instead delete.
reinterpret_cast s.
:
template<class T>
struct free_then_delete {
void operator()(T*t)const{
if(!t)return;
t->~T();
free(t);
};
};
template<class T>
using aligned_ptr=std::unique_ptr<T,free_then_delete<T>>;
template<class T,class...Args>
T* make_aligned_raw_ptr(size_t alignment, Args&&...args) {
void* raw = 0;
if(int err = posix_memalign(&raw, alignment, sizeof(T)))
{
if (err==ENOMEM)
throw std::bad_alloc{};
return 0;
}
try {
return new(raw) T(std::forward<Args>(args)...);
} catch(...) {
free(raw);
throw;
}
}
template<class T,class...Args> // ,class... Args optional
aligned_ptr<T> make_aligned_ptr(size_t alignment=8, Args&&...args){
T* t = make_aligned_raw_ptr<T>(alignment, std::forward<Args>(args)...);
if (t)
return aligned_ptr<T>(t);
else
return nullptr;
}
unique_ptr aligned_ptr - , , . .release() , .