DirectXTK/Src/AlignedNew.h

82 строки
2.2 KiB
C++

//--------------------------------------------------------------------------------------
// File: AlignedNew.h
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// http://go.microsoft.com/fwlink/?LinkId=248929
// http://go.microsoft.com/fwlink/?LinkID=615561
//--------------------------------------------------------------------------------------
#pragma once
#include <cstddef>
#include <cstdlib>
#include <exception>
#ifdef WIN32
#include <malloc.h>
#endif
namespace DirectX
{
// Derive from this to customize operator new and delete for
// types that have special heap alignment requirements.
//
// Example usage:
//
// XM_ALIGNED_STRUCT(16) MyAlignedType : public AlignedNew<MyAlignedType>
template<typename TDerived>
struct AlignedNew
{
// Allocate aligned memory.
static void* operator new (size_t size)
{
const size_t alignment = alignof(TDerived);
static_assert(alignment > 8, "AlignedNew is only useful for types with > 8 byte alignment. Did you forget a __declspec(align) on TDerived?");
static_assert(((alignment - 1) & alignment) == 0, "AlignedNew only works with power of two alignment");
#ifdef WIN32
void* ptr = _aligned_malloc(size, alignment);
#else
// This C++17 Standard Library function is currently NOT
// implemented for the Microsoft Standard C++ Library.
void* ptr = aligned_alloc(alignment, size);
#endif
if (!ptr)
throw std::bad_alloc();
return ptr;
}
// Free aligned memory.
static void operator delete (void* ptr)
{
#ifdef WIN32
_aligned_free(ptr);
#else
free(ptr);
#endif
}
// Array overloads.
static void* operator new[](size_t size)
{
static_assert((sizeof(TDerived) % alignof(TDerived) == 0), "AlignedNew expects type to be padded to the alignment");
return operator new(size);
}
static void operator delete[](void* ptr)
{
operator delete(ptr);
}
};
}