05709fb43e
This is not an API-breaking change, because it reduces the API that the leveldb embedder must implement. The project will build just fine against ports that still implement InitOnce. C++11 guarantees thread-safe initialization of static variables inside functions. This is a more restricted form of std::call_once or pthread_once_t (e.g., single call site), so the compiler might be able to generate better code [1]. Equally important, having less code in port_example.h makes it easier to port to other platforms. Due to the change above, this CL introduces a new approach for storing the singleton BytewiseComparatorImpl instance returned by BytewiseComparator(). The new approach avoids a dynamic memory allocation, which eliminates the false positive from LeakSanitizer reported in https://github.com/google/leveldb/issues/200 [1] https://stackoverflow.com/a/27206650/ ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=212348004
48 lines
1.5 KiB
C++
48 lines
1.5 KiB
C++
// Copyright (c) 2018 The LevelDB Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
|
|
|
#ifndef STORAGE_LEVELDB_UTIL_NO_DESTRUCTOR_H_
|
|
#define STORAGE_LEVELDB_UTIL_NO_DESTRUCTOR_H_
|
|
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
namespace leveldb {
|
|
|
|
// Wraps an instance whose destructor is never called.
|
|
//
|
|
// This is intended for use with function-level static variables.
|
|
template<typename InstanceType>
|
|
class NoDestructor {
|
|
public:
|
|
template <typename... ConstructorArgTypes>
|
|
explicit NoDestructor(ConstructorArgTypes&&... constructor_args) {
|
|
static_assert(sizeof(instance_storage_) >= sizeof(InstanceType),
|
|
"instance_storage_ is not large enough to hold the instance");
|
|
static_assert(
|
|
alignof(decltype(instance_storage_)) >= alignof(InstanceType),
|
|
"instance_storage_ does not meet the instance's alignment requirement");
|
|
new (&instance_storage_) InstanceType(
|
|
std::forward<ConstructorArgTypes>(constructor_args)...);
|
|
}
|
|
|
|
~NoDestructor() = default;
|
|
|
|
NoDestructor(const NoDestructor&) = delete;
|
|
NoDestructor& operator=(const NoDestructor&) = delete;
|
|
|
|
InstanceType* get() {
|
|
return reinterpret_cast<InstanceType*>(&instance_storage_);
|
|
}
|
|
|
|
private:
|
|
typename
|
|
std::aligned_storage<sizeof(InstanceType), alignof(InstanceType)>::type
|
|
instance_storage_;
|
|
};
|
|
|
|
} // namespace leveldb
|
|
|
|
#endif // STORAGE_LEVELDB_UTIL_NO_DESTRUCTOR_H_
|