no_destructor.h 1.7 KB

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