/* * Copyright 2016-present Facebook, Inc. * * 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. */ #pragma once #include #include namespace folly { namespace detail { // This internal-use-only class is used to create all leaked Meyers singletons. // It guarantees that only one instance of every such singleton will ever be // created, even when requested from different compilation units linked // dynamically. class StaticSingletonManager { public: template FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN static T* create( F&& creator) { return static_cast(create_(creator)); } private: template struct TypePair {}; using Key = std::type_info; using Make = void*(void*); template struct Creator { static void* create(void* f) { return static_cast((*static_cast(f))()); } }; template FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN static void* create_( F& creator) { auto const& key = typeid(TypePair); return create_(key, &Creator::create, &creator); } template FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN static void* create_( F const& creator) { auto const& key = typeid(TypePair); return create_(key, &Creator::create, const_cast(&creator)); } FOLLY_NOINLINE static void* create_(Key const& key, Make* make, void* ctx); }; template FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN T* createGlobal(F&& creator) { return StaticSingletonManager::create(static_cast(creator)); } template FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN T* createGlobal() { return StaticSingletonManager::create([]() { return new T(); }); } } // namespace detail } // namespace folly