no_destructor.h raw

   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    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      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    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_
  51