1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// ManualConstructor statically-allocates space in which to store some 6// object, but does not initialize it. You can then call the constructor 7// and destructor for the object yourself as you see fit. This is useful 8// for memory management optimizations, where you want to initialize and 9// destroy an object multiple times but only allocate it once. 10// 11// (When I say ManualConstructor statically allocates space, I mean that 12// the ManualConstructor object itself is forced to be the right size.) 13// 14// For example usage, check out base/containers/small_map.h. 15 16#ifndef BASE_MEMORY_MANUAL_CONSTRUCTOR_H_ 17#define BASE_MEMORY_MANUAL_CONSTRUCTOR_H_ 18 19#include <stddef.h> 20 21#include "base/compiler_specific.h" 22#include "base/memory/aligned_memory.h" 23 24namespace base { 25 26template <typename Type> 27class ManualConstructor { 28 public: 29 // No constructor or destructor because one of the most useful uses of 30 // this class is as part of a union, and members of a union cannot have 31 // constructors or destructors. And, anyway, the whole point of this 32 // class is to bypass these. 33 34 // Support users creating arrays of ManualConstructor<>s. This ensures that 35 // the array itself has the correct alignment. 36 static void* operator new[](size_t size) { 37 return AlignedAlloc(size, ALIGNOF(Type)); 38 } 39 static void operator delete[](void* mem) { 40 AlignedFree(mem); 41 } 42 43 inline Type* get() { 44 return space_.template data_as<Type>(); 45 } 46 inline const Type* get() const { 47 return space_.template data_as<Type>(); 48 } 49 50 inline Type* operator->() { return get(); } 51 inline const Type* operator->() const { return get(); } 52 53 inline Type& operator*() { return *get(); } 54 inline const Type& operator*() const { return *get(); } 55 56 template <typename... Ts> 57 inline void Init(Ts&&... params) { 58 new(space_.void_data()) Type(std::forward<Ts>(params)...); 59 } 60 61 inline void InitFromMove(ManualConstructor<Type>&& o) { 62 Init(std::move(*o)); 63 } 64 65 inline void Destroy() { 66 get()->~Type(); 67 } 68 69 private: 70 AlignedMemory<sizeof(Type), ALIGNOF(Type)> space_; 71}; 72 73} // namespace base 74 75#endif // BASE_MEMORY_MANUAL_CONSTRUCTOR_H_ 76