// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // AlignedMemory is a POD type that gives you a portable way to specify static // or local stack data of a given alignment and size. For example, if you need // static storage for a class, but you want manual control over when the object // is constructed and destructed (you don't want static initialization and // destruction), use AlignedMemory: // // static AlignedMemory my_class; // // // ... at runtime: // new(my_class.void_data()) MyClass(); // // // ... use it: // MyClass* mc = my_class.data_as(); // // // ... later, to destruct my_class: // my_class.data_as()->MyClass::~MyClass(); // // Alternatively, a runtime sized aligned allocation can be created: // // float* my_array = static_cast(AlignedAlloc(size, alignment)); // // // ... later, to release the memory: // AlignedFree(my_array); // // Or using scoped_ptr: // // scoped_ptr my_array( // static_cast(AlignedAlloc(size, alignment))); #ifndef BASE_MEMORY_ALIGNED_MEMORY_H_ #define BASE_MEMORY_ALIGNED_MEMORY_H_ #include "base/base_export.h" #include "base/basictypes.h" #include "base/compiler_specific.h" #if defined(COMPILER_MSVC) #include #else #include #endif namespace base { // AlignedMemory is specialized for all supported alignments. // Make sure we get a compiler error if someone uses an unsupported alignment. template struct AlignedMemory {}; #define BASE_DECL_ALIGNED_MEMORY(byte_alignment) \ template \ class AlignedMemory { \ public: \ ALIGNAS(byte_alignment) uint8 data_[Size]; \ void* void_data() { return static_cast(data_); } \ const void* void_data() const { \ return static_cast(data_); \ } \ template \ Type* data_as() { return static_cast(void_data()); } \ template \ const Type* data_as() const { \ return static_cast(void_data()); \ } \ private: \ void* operator new(size_t); \ void operator delete(void*); \ } // Specialization for all alignments is required because MSVC (as of VS 2008) // does not understand ALIGNAS(ALIGNOF(Type)) or ALIGNAS(template_param). // Greater than 4096 alignment is not supported by some compilers, so 4096 is // the maximum specified here. BASE_DECL_ALIGNED_MEMORY(1); BASE_DECL_ALIGNED_MEMORY(2); BASE_DECL_ALIGNED_MEMORY(4); BASE_DECL_ALIGNED_MEMORY(8); BASE_DECL_ALIGNED_MEMORY(16); BASE_DECL_ALIGNED_MEMORY(32); BASE_DECL_ALIGNED_MEMORY(64); BASE_DECL_ALIGNED_MEMORY(128); BASE_DECL_ALIGNED_MEMORY(256); BASE_DECL_ALIGNED_MEMORY(512); BASE_DECL_ALIGNED_MEMORY(1024); BASE_DECL_ALIGNED_MEMORY(2048); BASE_DECL_ALIGNED_MEMORY(4096); #undef BASE_DECL_ALIGNED_MEMORY BASE_EXPORT void* AlignedAlloc(size_t size, size_t alignment); inline void AlignedFree(void* ptr) { #if defined(COMPILER_MSVC) _aligned_free(ptr); #else free(ptr); #endif } // Deleter for use with scoped_ptr. E.g., use as // scoped_ptr foo; struct AlignedFreeDeleter { inline void operator()(void* ptr) const { AlignedFree(ptr); } }; } // namespace base #endif // BASE_MEMORY_ALIGNED_MEMORY_H_