Commit 592b2621 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Remove StaticSingletonManager support for creator function

Summary: [Folly] Remove `StaticSingletonManager` support for creator function. In general, derived types may be used instead.

Reviewed By: andriigrynenko

Differential Revision: D13114823

fbshipit-source-id: ecd781a1e11f1726e5e8689874e7f4473d21ecb0
parent 60c9115b
......@@ -27,10 +27,10 @@ namespace {
class StaticSingletonManagerImpl {
public:
void* create(std::type_info const& key, void* (*make)(void*), void* ctx) {
void* create(std::type_info const& key, void* (*make)()) {
auto& e = entry(key);
std::lock_guard<std::mutex> lock(e.mutex);
return e.ptr ? e.ptr : (e.ptr = make(ctx));
return e.ptr ? e.ptr : (e.ptr = make());
}
private:
......@@ -51,10 +51,10 @@ class StaticSingletonManagerImpl {
} // namespace
void* StaticSingletonManager::create_(Key const& key, Make* make, void* ctx) {
void* StaticSingletonManager::create_(Key const& key, Make* make) {
// This Leaky Meyers Singleton must always live in the .cpp file.
static auto& instance = *new StaticSingletonManagerImpl();
return instance.create(key, make, ctx);
return instance.create(key, make);
}
} // namespace detail
......
......@@ -29,10 +29,10 @@ namespace detail {
// dynamically.
class StaticSingletonManager {
public:
template <typename T, typename Tag, typename F>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN static T* create(
F&& creator) {
return static_cast<T*>(create_<T, Tag>(creator));
template <typename T, typename Tag>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN static T* create() {
auto const& key = typeid(TypePair<T, Tag>);
return static_cast<T*>(create_(key, &Creator<T>::create));
}
private:
......@@ -40,49 +40,21 @@ class StaticSingletonManager {
struct TypePair {};
using Key = std::type_info;
using Make = void*(void*);
using Make = void*();
template <typename F>
template <typename T>
struct Creator {
static void* create(void* f) {
return static_cast<void*>((*static_cast<F*>(f))());
static void* create() {
return new T();
}
};
template <typename T, typename Tag, typename F>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN static void* create_(
F& creator) {
auto const& key = typeid(TypePair<T, Tag>);
return create_(key, &Creator<F>::create, &creator);
}
template <typename T, typename Tag, typename F>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN static void* create_(
F const& creator) {
auto const& key = typeid(TypePair<T, Tag>);
return create_(key, &Creator<F const>::create, const_cast<F*>(&creator));
}
FOLLY_NOINLINE static void* create_(Key const& key, Make* make, void* ctx);
FOLLY_NOINLINE static void* create_(Key const& key, Make* make);
};
template <typename T, typename Tag, typename F>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN T* createGlobal(F&& creator) {
return StaticSingletonManager::create<T, Tag>(static_cast<F&&>(creator));
}
// TODO(T36779215): A bug in the gcc-5-glibc-2.23 llvm-fb/clang doesn't like
// passing this as a lambda (e.g. P60328775).
namespace {
template <typename T>
T* singleton_global_cons() {
return new T();
}
} // namespace
template <typename T, typename Tag>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN T* createGlobal() {
return createGlobal<T, Tag>(&singleton_global_cons<T>);
return StaticSingletonManager::create<T, Tag>();
}
} // namespace detail
......
......@@ -26,23 +26,25 @@ struct StaticSingletonManagerTest : public testing::Test {};
template <typename T>
struct Tag {};
template <int I>
using Int = std::integral_constant<int, I>;
TEST_F(StaticSingletonManagerTest, example) {
auto make3 = [n = 3] { return new int(n); };
auto i = createGlobal<int, Tag<char>>(make3);
using T = std::integral_constant<int, 3>;
auto i = createGlobal<T, Tag<char>>();
ASSERT_NE(nullptr, i);
EXPECT_EQ(3, *i);
EXPECT_EQ(T::value, *i);
auto const make4 = [n = 4] { return new int(n); };
auto j = createGlobal<int, Tag<char>>(make4);
auto j = createGlobal<T, Tag<char>>();
ASSERT_NE(nullptr, j);
EXPECT_EQ(i, j);
EXPECT_EQ(3, *j);
EXPECT_EQ(T::value, *j);
auto make5 = [n = 5] { return new int(n); };
auto k = createGlobal<int, Tag<char*>>(std::move(make5));
auto k = createGlobal<T, Tag<char*>>();
ASSERT_NE(nullptr, k);
EXPECT_NE(i, k);
EXPECT_EQ(5, *k);
EXPECT_EQ(T::value, *k);
}
} // namespace detail
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment