no_destruct.h
Go to the documentation of this file.
1 // Copyright 2022 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_CORE_LIB_GPRPP_NO_DESTRUCT_H
16 #define GRPC_CORE_LIB_GPRPP_NO_DESTRUCT_H
17 
19 
20 #include <type_traits>
21 #include <utility>
22 
24 
25 namespace grpc_core {
26 
27 // NoDestruct<T> is a wrapper around an object of type T that:
28 // - stores the value inline - no heap allocation
29 // - is non-copyable
30 // - is eagerly constructed (i.e. the constructor is called when NoDestruct is
31 // constructed)
32 // - *NEVER* calls ~T()
33 // It's useful in cases where no ordering can be assumed between destructors of
34 // objects that need to refer to each other - such as at program destruction
35 // time.
36 // Examples:
37 // // globally available object:
38 // static NoDestruct<Foo> g_foo(1, "foo", 2.0);
39 // // used as:
40 // g_foo->DoSomething();
41 // // singleton function:
42 // Bar* BarSingleton() {
43 // static NoDestruct<Bar> bar(1, "bar", 2.0);
44 // return &*bar;
45 // }
46 // The globally available version is constructed at program startup, and the
47 // singleton version is constructed at the first call to BarSingleton().
48 // Neither Foo nor Bar instance will be destructed.
49 template <typename T>
50 class NoDestruct {
51  public:
52  template <typename... Args>
53  explicit NoDestruct(Args&&... args) {
54  static_assert(std::is_trivially_destructible<NoDestruct<T>>::value,
55  "NoDestruct must be trivially destructible");
56  Construct(reinterpret_cast<T*>(&space_), std::forward<Args>(args)...);
57  }
58  NoDestruct(const NoDestruct&) = delete;
59  NoDestruct& operator=(const NoDestruct&) = delete;
60  ~NoDestruct() = default;
61 
62  T* operator->() { return get(); }
63  const T* operator->() const { return get(); }
64  T& operator*() { return *get(); }
65  const T& operator*() const { return *get(); }
66 
67  T* get() { return reinterpret_cast<T*>(&space_); }
68  const T* get() const { return reinterpret_cast<const T*>(&space_); }
69 
70  private:
71  typename std::aligned_storage<sizeof(T), alignof(T)>::type space_;
72 };
73 
74 // Helper for when a program desires a single *process wide* instance of a
75 // default constructed T to be always available.
76 // The instance is constructed eagerly at program startup, so it's essentially
77 // free to load the pointer to the instance.
78 template <typename T>
80  public:
81  static T* Get() { return &*value_; }
82 
83  private:
84  NoDestructSingleton() = delete;
85  ~NoDestructSingleton() = delete;
86 
88 };
89 
90 template <typename T>
92 
93 } // namespace grpc_core
94 
95 #endif // GRPC_CORE_LIB_GPRPP_NO_DESTRUCT_H
grpc_core::NoDestructSingleton
Definition: no_destruct.h:79
grpc_core::NoDestruct
Definition: no_destruct.h:50
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::NoDestructSingleton::Get
static T * Get()
Definition: no_destruct.h:81
grpc_core::NoDestruct::~NoDestruct
~NoDestruct()=default
grpc_core::NoDestructSingleton::NoDestructSingleton
NoDestructSingleton()=delete
T
#define T(upbtypeconst, upbtype, ctype, default_value)
grpc_core::NoDestruct::get
const T * get() const
Definition: no_destruct.h:68
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
hpack_encoder_fixtures::Args
Args({0, 16384})
grpc_core::NoDestruct::operator=
NoDestruct & operator=(const NoDestruct &)=delete
grpc_core::NoDestruct::operator->
const T * operator->() const
Definition: no_destruct.h:63
grpc_core::NoDestruct::operator*
const T & operator*() const
Definition: no_destruct.h:65
grpc_core::NoDestruct::space_
std::aligned_storage< sizeof(T), alignof(T)>::type space_
Definition: no_destruct.h:71
grpc_core::Construct
void Construct(T *p, Args &&... args)
Definition: construct_destruct.h:34
value
const char * value
Definition: hpack_parser_table.cc:165
grpc_core::NoDestruct::operator->
T * operator->()
Definition: no_destruct.h:62
grpc_core::NoDestructSingleton::~NoDestructSingleton
~NoDestructSingleton()=delete
grpc_core::NoDestruct::operator*
T & operator*()
Definition: no_destruct.h:64
grpc_core::NoDestruct::get
T * get()
Definition: no_destruct.h:67
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
construct_destruct.h
grpc_core::NoDestruct::NoDestruct
NoDestruct(Args &&... args)
Definition: no_destruct.h:53
grpc_core::NoDestructSingleton::value_
static NoDestruct< T > value_
Definition: no_destruct.h:87
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:42