Index: base/memory/aligned_memory.h |
diff --git a/base/memory/aligned_memory.h b/base/memory/aligned_memory.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..80a601305a2c115a5c586b6671a97271ae012d1b |
--- /dev/null |
+++ b/base/memory/aligned_memory.h |
@@ -0,0 +1,113 @@ |
+// Copyright 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<sizeof(MyClass), ALIGNOF(MyClass)> my_class; |
+// |
+// // ... at runtime: |
+// new(my_class.void_data()) MyClass(); |
+// |
+// // ... use it: |
+// MyClass* mc = my_class.data_as<MyClass>(); |
+// |
+// // ... later, to destruct my_class: |
+// my_class.data_as<MyClass>()->MyClass::~MyClass(); |
+// |
+// Alternatively, a runtime sized aligned allocation can be created: |
+// |
+// float* my_array = static_cast<float*>(AlignedAlloc(size, alignment)); |
+// |
+// // ... later, to release the memory: |
+// AlignedFree(my_array); |
+// |
+// Or using scoped_ptr: |
+// |
+// scoped_ptr<float, AlignedFreeDeleter> my_array( |
+// static_cast<float*>(AlignedAlloc(size, alignment))); |
+ |
+#ifndef BASE_MEMORY_ALIGNED_MEMORY_H_ |
+#define BASE_MEMORY_ALIGNED_MEMORY_H_ |
+ |
+#include "base/basictypes.h" |
+#include "base/compiler_specific.h" |
+ |
+#if defined(COMPILER_MSVC) |
+#include <malloc.h> |
+#else |
+#include <stdlib.h> |
+#endif |
+ |
+namespace base { |
+ |
+// AlignedMemory is specialized for all supported alignments. |
+// Make sure we get a compiler error if someone uses an unsupported alignment. |
+template <size_t Size, size_t ByteAlignment> |
+struct AlignedMemory {}; |
+ |
+#define BASE_DECL_ALIGNED_MEMORY(byte_alignment) \ |
+ template <size_t Size> \ |
+ class AlignedMemory<Size, byte_alignment> { \ |
+ public: \ |
+ ALIGNAS(byte_alignment) uint8_t data_[Size]; \ |
+ void* void_data() { return static_cast<void*>(data_); } \ |
+ const void* void_data() const { \ |
+ return static_cast<const void*>(data_); \ |
+ } \ |
+ template<typename Type> \ |
+ Type* data_as() { return static_cast<Type*>(void_data()); } \ |
+ template<typename Type> \ |
+ const Type* data_as() const { \ |
+ return static_cast<const Type*>(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 |
+ |
+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, base::AlignedFreeDeleter> foo; |
+struct AlignedFreeDeleter { |
+ inline void operator()(void* ptr) const { |
+ AlignedFree(ptr); |
+ } |
+}; |
+ |
+} // namespace base |
+ |
+#endif // BASE_MEMORY_ALIGNED_MEMORY_H_ |