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