chromium/third_party/mediapipe/src/mediapipe/framework/deps/no_destructor.h

// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef MEDIAPIPE_DEPS_NO_DESTRUCTOR_H_
#define MEDIAPIPE_DEPS_NO_DESTRUCTOR_H_

#include <type_traits>
#include <utility>

namespace mediapipe {

// NoDestructor<T> is a wrapper around an object of type T that
// * stores the object of type T inline inside NoDestructor<T>
// * eagerly forwards constructor arguments to it (i.e. acts like T in terms
//   of construction)
// * provides access to the object of type T like a pointer via ->, *, and get()
//   (note that const NoDestructor<T> works like a pointer to const T)
// * never calls T's destructor for the object
//   (hence NoDestructor<T> objects created on the stack or as member variables
//   will lead to memory and/or resource leaks)
//
// One key use case of NoDestructor (which in itself is not lazy) is optimizing
// the following pattern of safe on-demand construction of an object with
// non-trivial constructor in static storage without destruction ever happening:
//   const std::string& MyString() {
//     static std::string* x = new std::string("foo");  // note the "static"
//     return *x;
//   }
// By using NoDestructor we do not need to involve heap allocation and
// corresponding pointer following (and hence extra CPU cache usage/needs)
// on each access:
//   const std::string& MyString() {
//     static NoDestructor<std::string> x("foo");
//     return *x;
//   }
// Since C++11 this static-in-a-function pattern results in exactly-once,
// thread-safe, on-demand construction of an object, and very fast access
// thereafter (the cost is a few extra cycles).
// NoDestructor makes accesses even faster by storing the object inline in
// static storage.
//
// Note that:
// * Since destructor is never called, the object lives on during program exit
//   and can be safely accessed by any threads that have not been joined.
// * This static-in-a-function NoDestructor usage pattern should be preferred
//   to uses of gtl::LazyStaticPtr in new code.
//
// Also note that
//   static NoDestructor<NonPOD> ptr(whatever);
// can safely replace
//   static NonPOD* ptr = new NonPOD(whatever);
// or
//   static NonPOD obj(whatever);
// at file-level scope when the safe static-in-a-function pattern is infeasible
// to use for some good reason.
// All three of the NonPOD patterns above suffer from the same issue that
// initialization of that object happens non-thread-safely at
// a globally-undefined point during initialization of static-storage objects,
// but NoDestructor<> usage provides both the safety of having the object alive
// during program exit sequence and the performance of not doing extra memory
// dereference on access.
//
template <typename T>
class NoDestructor {};

}  // namespace mediapipe

#endif  // MEDIAPIPE_DEPS_NO_DESTRUCTOR_H_