Line data Source code
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 50 : 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 50 : 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 1301 : 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_
|