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>
NoDestructor(ConstructorArgTypes &&...constructor_args)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 
get()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