xref: /aosp_15_r20/external/abseil-cpp/absl/base/no_destructor.h (revision 9356374a3709195abf420251b3e825997ff56c0f)
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