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
11namespace leveldb {
12
13// Wraps an instance whose destructor is never called.
14//
15// This is intended for use with function-level static variables.
16template <typename InstanceType>
17class 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