1*9356374aSAndroid Build Coastguard Worker // Copyright 2023 The Abseil Authors. 2*9356374aSAndroid Build Coastguard Worker // 3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*9356374aSAndroid Build Coastguard Worker // 7*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0 8*9356374aSAndroid Build Coastguard Worker // 9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*9356374aSAndroid Build Coastguard Worker // limitations under the License. 14*9356374aSAndroid Build Coastguard Worker // 15*9356374aSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------- 16*9356374aSAndroid Build Coastguard Worker // File: no_destructor.h 17*9356374aSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------- 18*9356374aSAndroid Build Coastguard Worker // 19*9356374aSAndroid Build Coastguard Worker // This header file defines the absl::NoDestructor<T> wrapper for defining a 20*9356374aSAndroid Build Coastguard Worker // static type that does not need to be destructed upon program exit. Instead, 21*9356374aSAndroid Build Coastguard Worker // such an object survives during program exit (and can be safely accessed at 22*9356374aSAndroid Build Coastguard Worker // any time). 23*9356374aSAndroid Build Coastguard Worker // 24*9356374aSAndroid Build Coastguard Worker // absl::NoDestructor<T> is useful when when a variable has static storage 25*9356374aSAndroid Build Coastguard Worker // duration but its type has a non-trivial destructor. Global constructors are 26*9356374aSAndroid Build Coastguard Worker // not recommended because of the C++'s static initialization order fiasco (See 27*9356374aSAndroid Build Coastguard Worker // https://en.cppreference.com/w/cpp/language/siof). Global destructors are not 28*9356374aSAndroid Build Coastguard Worker // allowed due to similar concerns about destruction ordering. Using 29*9356374aSAndroid Build Coastguard Worker // absl::NoDestructor<T> as a function-local static prevents both of these 30*9356374aSAndroid Build Coastguard Worker // issues. 31*9356374aSAndroid Build Coastguard Worker // 32*9356374aSAndroid Build Coastguard Worker // See below for complete details. 33*9356374aSAndroid Build Coastguard Worker 34*9356374aSAndroid Build Coastguard Worker 35*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_BASE_NO_DESTRUCTOR_H_ 36*9356374aSAndroid Build Coastguard Worker #define ABSL_BASE_NO_DESTRUCTOR_H_ 37*9356374aSAndroid Build Coastguard Worker 38*9356374aSAndroid Build Coastguard Worker #include <new> 39*9356374aSAndroid Build Coastguard Worker #include <type_traits> 40*9356374aSAndroid Build Coastguard Worker #include <utility> 41*9356374aSAndroid Build Coastguard Worker 42*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h" 43*9356374aSAndroid Build Coastguard Worker #include "absl/base/nullability.h" 44*9356374aSAndroid Build Coastguard Worker 45*9356374aSAndroid Build Coastguard Worker namespace absl { 46*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN 47*9356374aSAndroid Build Coastguard Worker 48*9356374aSAndroid Build Coastguard Worker // absl::NoDestructor<T> 49*9356374aSAndroid Build Coastguard Worker // 50*9356374aSAndroid Build Coastguard Worker // NoDestructor<T> is a wrapper around an object of type T that behaves as an 51*9356374aSAndroid Build Coastguard Worker // object of type T but never calls T's destructor. NoDestructor<T> makes it 52*9356374aSAndroid Build Coastguard Worker // safer and/or more efficient to use such objects in static storage contexts, 53*9356374aSAndroid Build Coastguard Worker // ideally as function scope static variables. 54*9356374aSAndroid Build Coastguard Worker // 55*9356374aSAndroid Build Coastguard Worker // An instance of absl::NoDestructor<T> has similar type semantics to an 56*9356374aSAndroid Build Coastguard Worker // instance of T: 57*9356374aSAndroid Build Coastguard Worker // 58*9356374aSAndroid Build Coastguard Worker // * Constructs in the same manner as an object of type T through perfect 59*9356374aSAndroid Build Coastguard Worker // forwarding. 60*9356374aSAndroid Build Coastguard Worker // * Provides pointer/reference semantic access to the object of type T via 61*9356374aSAndroid Build Coastguard Worker // `->`, `*`, and `get()`. 62*9356374aSAndroid Build Coastguard Worker // (Note that `const NoDestructor<T>` works like a pointer to const `T`.) 63*9356374aSAndroid Build Coastguard Worker // 64*9356374aSAndroid Build Coastguard Worker // Additionally, NoDestructor<T> provides the following benefits: 65*9356374aSAndroid Build Coastguard Worker // 66*9356374aSAndroid Build Coastguard Worker // * Never calls T's destructor for the object 67*9356374aSAndroid Build Coastguard Worker // * If the object is a function-local static variable, the type can be 68*9356374aSAndroid Build Coastguard Worker // lazily constructed. 69*9356374aSAndroid Build Coastguard Worker // 70*9356374aSAndroid Build Coastguard Worker // An object of type NoDestructor<T> is "trivially destructible" in the notion 71*9356374aSAndroid Build Coastguard Worker // that its destructor is never run. 72*9356374aSAndroid Build Coastguard Worker // 73*9356374aSAndroid Build Coastguard Worker // Usage as Function Scope Static Variables 74*9356374aSAndroid Build Coastguard Worker // 75*9356374aSAndroid Build Coastguard Worker // Function static objects will be lazily initialized within static storage: 76*9356374aSAndroid Build Coastguard Worker // 77*9356374aSAndroid Build Coastguard Worker // // Function scope. 78*9356374aSAndroid Build Coastguard Worker // const std::string& MyString() { 79*9356374aSAndroid Build Coastguard Worker // static const absl::NoDestructor<std::string> x("foo"); 80*9356374aSAndroid Build Coastguard Worker // return *x; 81*9356374aSAndroid Build Coastguard Worker // } 82*9356374aSAndroid Build Coastguard Worker // 83*9356374aSAndroid Build Coastguard Worker // For function static variables, NoDestructor avoids heap allocation and can be 84*9356374aSAndroid Build Coastguard Worker // inlined in static storage, resulting in exactly-once, thread-safe 85*9356374aSAndroid Build Coastguard Worker // construction of an object, and very fast access thereafter (the cost is a few 86*9356374aSAndroid Build Coastguard Worker // extra cycles). 87*9356374aSAndroid Build Coastguard Worker // 88*9356374aSAndroid Build Coastguard Worker // Using NoDestructor<T> in this manner is generally better than other patterns 89*9356374aSAndroid Build Coastguard Worker // which require pointer chasing: 90*9356374aSAndroid Build Coastguard Worker // 91*9356374aSAndroid Build Coastguard Worker // // Prefer using absl::NoDestructor<T> instead for the static variable. 92*9356374aSAndroid Build Coastguard Worker // const std::string& MyString() { 93*9356374aSAndroid Build Coastguard Worker // static const std::string* x = new std::string("foo"); 94*9356374aSAndroid Build Coastguard Worker // return *x; 95*9356374aSAndroid Build Coastguard Worker // } 96*9356374aSAndroid Build Coastguard Worker // 97*9356374aSAndroid Build Coastguard Worker // Usage as Global Static Variables 98*9356374aSAndroid Build Coastguard Worker // 99*9356374aSAndroid Build Coastguard Worker // NoDestructor<T> allows declaration of a global object of type T that has a 100*9356374aSAndroid Build Coastguard Worker // non-trivial destructor since its destructor is never run. However, such 101*9356374aSAndroid Build Coastguard Worker // objects still need to worry about initialization order, so such use is not 102*9356374aSAndroid Build Coastguard Worker // recommended, strongly discouraged by the Google C++ Style Guide, and outright 103*9356374aSAndroid Build Coastguard Worker // banned in Chromium. 104*9356374aSAndroid Build Coastguard Worker // See https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables 105*9356374aSAndroid Build Coastguard Worker // 106*9356374aSAndroid Build Coastguard Worker // // Global or namespace scope. 107*9356374aSAndroid Build Coastguard Worker // absl::NoDestructor<MyRegistry> reg{"foo", "bar", 8008}; 108*9356374aSAndroid Build Coastguard Worker // 109*9356374aSAndroid Build Coastguard Worker // Note that if your object already has a trivial destructor, you don't need to 110*9356374aSAndroid Build Coastguard Worker // use NoDestructor<T>. 111*9356374aSAndroid Build Coastguard Worker // 112*9356374aSAndroid Build Coastguard Worker template <typename T> 113*9356374aSAndroid Build Coastguard Worker class NoDestructor { 114*9356374aSAndroid Build Coastguard Worker public: 115*9356374aSAndroid Build Coastguard Worker // Forwards arguments to the T's constructor: calls T(args...). 116*9356374aSAndroid Build Coastguard Worker template <typename... Ts, 117*9356374aSAndroid Build Coastguard Worker // Disable this overload when it might collide with copy/move. 118*9356374aSAndroid Build Coastguard Worker typename std::enable_if<!std::is_same<void(std::decay_t<Ts>&...), 119*9356374aSAndroid Build Coastguard Worker void(NoDestructor&)>::value, 120*9356374aSAndroid Build Coastguard Worker int>::type = 0> NoDestructor(Ts &&...args)121*9356374aSAndroid Build Coastguard Worker explicit constexpr NoDestructor(Ts&&... args) 122*9356374aSAndroid Build Coastguard Worker : impl_(std::forward<Ts>(args)...) {} 123*9356374aSAndroid Build Coastguard Worker 124*9356374aSAndroid Build Coastguard Worker // Forwards copy and move construction for T. Enables usage like this: 125*9356374aSAndroid Build Coastguard Worker // static NoDestructor<std::array<string, 3>> x{{{"1", "2", "3"}}}; 126*9356374aSAndroid Build Coastguard Worker // static NoDestructor<std::vector<int>> x{{1, 2, 3}}; NoDestructor(const T & x)127*9356374aSAndroid Build Coastguard Worker explicit constexpr NoDestructor(const T& x) : impl_(x) {} NoDestructor(T && x)128*9356374aSAndroid Build Coastguard Worker explicit constexpr NoDestructor(T&& x) 129*9356374aSAndroid Build Coastguard Worker : impl_(std::move(x)) {} 130*9356374aSAndroid Build Coastguard Worker 131*9356374aSAndroid Build Coastguard Worker // No copying. 132*9356374aSAndroid Build Coastguard Worker NoDestructor(const NoDestructor&) = delete; 133*9356374aSAndroid Build Coastguard Worker NoDestructor& operator=(const NoDestructor&) = delete; 134*9356374aSAndroid Build Coastguard Worker 135*9356374aSAndroid Build Coastguard Worker // Pretend to be a smart pointer to T with deep constness. 136*9356374aSAndroid Build Coastguard Worker // Never returns a null pointer. 137*9356374aSAndroid Build Coastguard Worker T& operator*() { return *get(); } 138*9356374aSAndroid Build Coastguard Worker absl::Nonnull<T*> operator->() { return get(); } get()139*9356374aSAndroid Build Coastguard Worker absl::Nonnull<T*> get() { return impl_.get(); } 140*9356374aSAndroid Build Coastguard Worker const T& operator*() const { return *get(); } 141*9356374aSAndroid Build Coastguard Worker absl::Nonnull<const T*> operator->() const { return get(); } get()142*9356374aSAndroid Build Coastguard Worker absl::Nonnull<const T*> get() const { return impl_.get(); } 143*9356374aSAndroid Build Coastguard Worker 144*9356374aSAndroid Build Coastguard Worker private: 145*9356374aSAndroid Build Coastguard Worker class DirectImpl { 146*9356374aSAndroid Build Coastguard Worker public: 147*9356374aSAndroid Build Coastguard Worker template <typename... Args> DirectImpl(Args &&...args)148*9356374aSAndroid Build Coastguard Worker explicit constexpr DirectImpl(Args&&... args) 149*9356374aSAndroid Build Coastguard Worker : value_(std::forward<Args>(args)...) {} get()150*9356374aSAndroid Build Coastguard Worker absl::Nonnull<const T*> get() const { return &value_; } get()151*9356374aSAndroid Build Coastguard Worker absl::Nonnull<T*> get() { return &value_; } 152*9356374aSAndroid Build Coastguard Worker 153*9356374aSAndroid Build Coastguard Worker private: 154*9356374aSAndroid Build Coastguard Worker T value_; 155*9356374aSAndroid Build Coastguard Worker }; 156*9356374aSAndroid Build Coastguard Worker 157*9356374aSAndroid Build Coastguard Worker class PlacementImpl { 158*9356374aSAndroid Build Coastguard Worker public: 159*9356374aSAndroid Build Coastguard Worker template <typename... Args> PlacementImpl(Args &&...args)160*9356374aSAndroid Build Coastguard Worker explicit PlacementImpl(Args&&... args) { 161*9356374aSAndroid Build Coastguard Worker new (&space_) T(std::forward<Args>(args)...); 162*9356374aSAndroid Build Coastguard Worker } get()163*9356374aSAndroid Build Coastguard Worker absl::Nonnull<const T*> get() const { 164*9356374aSAndroid Build Coastguard Worker return Launder(reinterpret_cast<const T*>(&space_)); 165*9356374aSAndroid Build Coastguard Worker } get()166*9356374aSAndroid Build Coastguard Worker absl::Nonnull<T*> get() { return Launder(reinterpret_cast<T*>(&space_)); } 167*9356374aSAndroid Build Coastguard Worker 168*9356374aSAndroid Build Coastguard Worker private: 169*9356374aSAndroid Build Coastguard Worker template <typename P> Launder(absl::Nonnull<P * > p)170*9356374aSAndroid Build Coastguard Worker static absl::Nonnull<P*> Launder(absl::Nonnull<P*> p) { 171*9356374aSAndroid Build Coastguard Worker #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606L 172*9356374aSAndroid Build Coastguard Worker return std::launder(p); 173*9356374aSAndroid Build Coastguard Worker #elif ABSL_HAVE_BUILTIN(__builtin_launder) 174*9356374aSAndroid Build Coastguard Worker return __builtin_launder(p); 175*9356374aSAndroid Build Coastguard Worker #else 176*9356374aSAndroid Build Coastguard Worker // When `std::launder` or equivalent are not available, we rely on 177*9356374aSAndroid Build Coastguard Worker // undefined behavior, which works as intended on Abseil's officially 178*9356374aSAndroid Build Coastguard Worker // supported platforms as of Q3 2023. 179*9356374aSAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__clang__) 180*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic push 181*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wstrict-aliasing" 182*9356374aSAndroid Build Coastguard Worker #endif 183*9356374aSAndroid Build Coastguard Worker return p; 184*9356374aSAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__clang__) 185*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic pop 186*9356374aSAndroid Build Coastguard Worker #endif 187*9356374aSAndroid Build Coastguard Worker #endif 188*9356374aSAndroid Build Coastguard Worker } 189*9356374aSAndroid Build Coastguard Worker 190*9356374aSAndroid Build Coastguard Worker alignas(T) unsigned char space_[sizeof(T)]; 191*9356374aSAndroid Build Coastguard Worker }; 192*9356374aSAndroid Build Coastguard Worker 193*9356374aSAndroid Build Coastguard Worker // If the object is trivially destructible we use a member directly to avoid 194*9356374aSAndroid Build Coastguard Worker // potential once-init runtime initialization. It somewhat defeats the 195*9356374aSAndroid Build Coastguard Worker // purpose of NoDestructor in this case, but this makes the class more 196*9356374aSAndroid Build Coastguard Worker // friendly to generic code. 197*9356374aSAndroid Build Coastguard Worker std::conditional_t<std::is_trivially_destructible<T>::value, DirectImpl, 198*9356374aSAndroid Build Coastguard Worker PlacementImpl> 199*9356374aSAndroid Build Coastguard Worker impl_; 200*9356374aSAndroid Build Coastguard Worker }; 201*9356374aSAndroid Build Coastguard Worker 202*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 203*9356374aSAndroid Build Coastguard Worker // Provide 'Class Template Argument Deduction': the type of NoDestructor's T 204*9356374aSAndroid Build Coastguard Worker // will be the same type as the argument passed to NoDestructor's constructor. 205*9356374aSAndroid Build Coastguard Worker template <typename T> 206*9356374aSAndroid Build Coastguard Worker NoDestructor(T) -> NoDestructor<T>; 207*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 208*9356374aSAndroid Build Coastguard Worker 209*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END 210*9356374aSAndroid Build Coastguard Worker } // namespace absl 211*9356374aSAndroid Build Coastguard Worker 212*9356374aSAndroid Build Coastguard Worker #endif // ABSL_BASE_NO_DESTRUCTOR_H_ 213