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