dReal4
never_destroyed.h
1 #pragma once
2 
3 #include <new>
4 #include <type_traits>
5 #include <utility>
6 
7 namespace dreal {
8 namespace drake {
9 
10 /// Wraps an underlying type T such that its storage is a direct member field
11 /// of this object (i.e., without any indirection into the heap), but *unlike*
12 /// most member fields T's destructor is never invoked.
13 ///
14 /// This is especially useful for function-local static variables that are not
15 /// trivially destructable. We shouldn't call their destructor at program exit
16 /// because of the "indeterminate order of ... destruction" as mentioned in
17 /// cppguide's Static_and_Global_Variables section, but other solutions to
18 /// this problem place the objects on the heap through an indirection.
19 ///
20 /// Compared with other approaches, this mechanism more clearly describes the
21 /// intent to readers, avoids "possible leak" warnings from memory-checking
22 /// tools, and is probably slightly faster.
23 template <typename T>
25  public:
26  never_destroyed(const never_destroyed&) = delete;
27  void operator=(const never_destroyed&) = delete;
28  never_destroyed(never_destroyed&&) = delete;
29  void operator=(never_destroyed&&) = delete;
30 
31  /// Passes the constructor arguments along to T using perfect forwarding.
32  template <typename... Args>
33  explicit never_destroyed(Args&&... args) {
34  // Uses "placement new" to construct a `T` in `storage_`.
35  new (&storage_) T(std::forward<Args>(args)...);
36  }
37 
38  /// Does nothing. Guaranteed!
39  ~never_destroyed() = default;
40 
41  /// Returns the underlying T reference.
42  T& access() { return *reinterpret_cast<T*>(&storage_); }
43  const T& access() const { return *reinterpret_cast<const T*>(&storage_); }
44 
45  private:
46  typename std::aligned_storage<sizeof(T), alignof(T)>::type storage_;
47 };
48 
49 } // namespace drake
50 } // namespace dreal
~never_destroyed()=default
Does nothing. Guaranteed!
Sum type of symbolic::Expression and symbolic::Formula.
Definition: api.cc:9
never_destroyed(Args &&... args)
Passes the constructor arguments along to T using perfect forwarding.
Definition: never_destroyed.h:33
Wraps an underlying type T such that its storage is a direct member field of this object (i...
Definition: never_destroyed.h:24
T & access()
Returns the underlying T reference.
Definition: never_destroyed.h:42