1 // Copyright 2018 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 #pragma once 5 #include <utility> 6 namespace android::base { 7 // A wrapper that makes it easy to create an object of type T with static 8 // storage duration that: 9 // - is only constructed on first access 10 // - never invokes the destructor 11 // in order to satisfy the styleguide ban on global constructors and 12 // destructors. 13 // 14 // Runtime constant example: 15 // const std::string& GetLineSeparator() { 16 // // Forwards to std::string(size_t, char, const Allocator&) constructor. 17 // static const base::NoDestructor<std::string> s(5, '-'); 18 // return s; 19 // } 20 // 21 // More complex initialization with a lambda: 22 // const std::string& GetSessionNonce() { 23 // static const base::NoDestructor<std::string> nonce([] { 24 // std::string s(16); 25 // crypto::RandString(s.data(), s.size()); 26 // return s; 27 // })()); 28 // return *nonce; 29 // } 30 // 31 // NoDestructor<T> stores the object inline, so it also avoids a pointer 32 // indirection and a malloc. Code should prefer to use NoDestructor<T> over: 33 // - The CR_DEFINE_STATIC_LOCAL() helper macro. 34 // - A function scoped static T* or T& that is dynamically initialized. 35 // - A global base::LazyInstance<T>. 36 // 37 // Note that since the destructor is never run, this *will* leak memory if used 38 // as a stack or member variable. Furthermore, a NoDestructor<T> should never 39 // have global scope as that may require a static initializer. 40 template <typename T> 41 class NoDestructor { 42 public: 43 // Not constexpr; just write static constexpr T x = ...; if the value should 44 // be a constexpr. 45 template <typename... Args> NoDestructor(Args &&...args)46 explicit NoDestructor(Args&&... args) { 47 new (get()) T(std::forward<Args>(args)...); 48 } 49 ~NoDestructor() = default; 50 const T& operator*() const { return *get(); } 51 T& operator*() { return *get(); } 52 const T* operator->() const { return get(); } 53 T* operator->() { return get(); } get()54 const T* get() const { return reinterpret_cast<const T*>(&storage_); } get()55 T* get() { return reinterpret_cast<T*>(&storage_); } 56 57 private: 58 alignas(T) char storage_[sizeof(T)]; 59 }; 60 } // namespace android::base 61