no_destructor.h raw
1 // Copyright (c) 2018 The LevelDB 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. See the AUTHORS file for names of contributors.
4
5 #ifndef STORAGE_LEVELDB_UTIL_NO_DESTRUCTOR_H_
6 #define STORAGE_LEVELDB_UTIL_NO_DESTRUCTOR_H_
7
8 #include <cstddef>
9 #include <type_traits>
10 #include <utility>
11
12 namespace leveldb {
13
14 // Wraps an instance whose destructor is never called.
15 //
16 // This is intended for use with function-level static variables.
17 template <typename InstanceType>
18 class NoDestructor {
19 public:
20 template <typename... ConstructorArgTypes>
21 explicit NoDestructor(ConstructorArgTypes&&... constructor_args) {
22 static_assert(sizeof(instance_storage_) >= sizeof(InstanceType),
23 "instance_storage_ is not large enough to hold the instance");
24 static_assert(std::is_standard_layout_v<NoDestructor<InstanceType>>);
25 static_assert(
26 offsetof(NoDestructor, instance_storage_) % alignof(InstanceType) == 0,
27 "instance_storage_ does not meet the instance's alignment requirement");
28 static_assert(
29 alignof(NoDestructor<InstanceType>) % alignof(InstanceType) == 0,
30 "instance_storage_ does not meet the instance's alignment requirement");
31 new (instance_storage_)
32 InstanceType(std::forward<ConstructorArgTypes>(constructor_args)...);
33 }
34
35 ~NoDestructor() = default;
36
37 NoDestructor(const NoDestructor&) = delete;
38 NoDestructor& operator=(const NoDestructor&) = delete;
39
40 InstanceType* get() {
41 return reinterpret_cast<InstanceType*>(&instance_storage_);
42 }
43
44 private:
45 alignas(InstanceType) char instance_storage_[sizeof(InstanceType)];
46 };
47
48 } // namespace leveldb
49
50 #endif // STORAGE_LEVELDB_UTIL_NO_DESTRUCTOR_H_
51