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