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 <type_traits> |
9 | #include <utility> |
10 | |
11 | namespace leveldb { |
12 | |
13 | // Wraps an instance whose destructor is never called. |
14 | // |
15 | // This is intended for use with function-level static variables. |
16 | template <typename InstanceType> |
17 | class NoDestructor { |
18 | public: |
19 | template <typename... ConstructorArgTypes> |
20 | explicit NoDestructor(ConstructorArgTypes&&... constructor_args) { |
21 | static_assert(sizeof(instance_storage_) >= sizeof(InstanceType), |
22 | "instance_storage_ is not large enough to hold the instance" ); |
23 | static_assert( |
24 | alignof(decltype(instance_storage_)) >= alignof(InstanceType), |
25 | "instance_storage_ does not meet the instance's alignment requirement" ); |
26 | new (&instance_storage_) |
27 | InstanceType(std::forward<ConstructorArgTypes>(constructor_args)...); |
28 | } |
29 | |
30 | ~NoDestructor() = default; |
31 | |
32 | NoDestructor(const NoDestructor&) = delete; |
33 | NoDestructor& operator=(const NoDestructor&) = delete; |
34 | |
35 | InstanceType* get() { |
36 | return reinterpret_cast<InstanceType*>(&instance_storage_); |
37 | } |
38 | |
39 | private: |
40 | typename std::aligned_storage<sizeof(InstanceType), |
41 | alignof(InstanceType)>::type instance_storage_; |
42 | }; |
43 | |
44 | } // namespace leveldb |
45 | |
46 | #endif // STORAGE_LEVELDB_UTIL_NO_DESTRUCTOR_H_ |
47 | |