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 { ...@@ -27,10 +27,10 @@ namespace {
class StaticSingletonManagerImpl { class StaticSingletonManagerImpl {
public: 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); auto& e = entry(key);
std::lock_guard<std::mutex> lock(e.mutex); 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: private:
...@@ -51,10 +51,10 @@ class StaticSingletonManagerImpl { ...@@ -51,10 +51,10 @@ class StaticSingletonManagerImpl {
} // namespace } // 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. // This Leaky Meyers Singleton must always live in the .cpp file.
static auto& instance = *new StaticSingletonManagerImpl(); static auto& instance = *new StaticSingletonManagerImpl();
return instance.create(key, make, ctx); return instance.create(key, make);
} }
} // namespace detail } // namespace detail
......
...@@ -29,10 +29,10 @@ namespace detail { ...@@ -29,10 +29,10 @@ namespace detail {
// dynamically. // dynamically.
class StaticSingletonManager { class StaticSingletonManager {
public: public:
template <typename T, typename Tag, typename F> template <typename T, typename Tag>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN static T* create( FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN static T* create() {
F&& creator) { auto const& key = typeid(TypePair<T, Tag>);
return static_cast<T*>(create_<T, Tag>(creator)); return static_cast<T*>(create_(key, &Creator<T>::create));
} }
private: private:
...@@ -40,49 +40,21 @@ class StaticSingletonManager { ...@@ -40,49 +40,21 @@ class StaticSingletonManager {
struct TypePair {}; struct TypePair {};
using Key = std::type_info; using Key = std::type_info;
using Make = void*(void*); using Make = void*();
template <typename F> template <typename T>
struct Creator { struct Creator {
static void* create(void* f) { static void* create() {
return static_cast<void*>((*static_cast<F*>(f))()); return new T();
} }
}; };
template <typename T, typename Tag, typename F> FOLLY_NOINLINE static void* create_(Key const& key, Make* make);
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);
}; };
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> template <typename T, typename Tag>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN T* createGlobal() { FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN T* createGlobal() {
return createGlobal<T, Tag>(&singleton_global_cons<T>); return StaticSingletonManager::create<T, Tag>();
} }
} // namespace detail } // namespace detail
......
...@@ -26,23 +26,25 @@ struct StaticSingletonManagerTest : public testing::Test {}; ...@@ -26,23 +26,25 @@ struct StaticSingletonManagerTest : public testing::Test {};
template <typename T> template <typename T>
struct Tag {}; struct Tag {};
template <int I>
using Int = std::integral_constant<int, I>;
TEST_F(StaticSingletonManagerTest, example) { TEST_F(StaticSingletonManagerTest, example) {
auto make3 = [n = 3] { return new int(n); }; using T = std::integral_constant<int, 3>;
auto i = createGlobal<int, Tag<char>>(make3);
auto i = createGlobal<T, Tag<char>>();
ASSERT_NE(nullptr, i); 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<T, Tag<char>>();
auto j = createGlobal<int, Tag<char>>(make4);
ASSERT_NE(nullptr, j); ASSERT_NE(nullptr, j);
EXPECT_EQ(i, 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<T, Tag<char*>>();
auto k = createGlobal<int, Tag<char*>>(std::move(make5));
ASSERT_NE(nullptr, k); ASSERT_NE(nullptr, k);
EXPECT_NE(i, k); EXPECT_NE(i, k);
EXPECT_EQ(5, *k); EXPECT_EQ(T::value, *k);
} }
} // namespace detail } // 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