Commit 619ff1d1 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

thunk

Summary:
Introduce `folly::detail::thunk`, a carefully curated collection of generic general-purpose thunk templates: `make`, `ruin`, `ctor`, `dtor`.

Initial uses in `StaticSingletonManager` and `to_erased_unique_ptr`.

Reviewed By: vitaut

Differential Revision: D26417824

fbshipit-source-id: 482f4154a957b3c3dbeede726ed870a8d10c2a32
parent fe3cce9b
......@@ -30,6 +30,7 @@
#include <folly/ConstexprMath.h>
#include <folly/Likely.h>
#include <folly/Traits.h>
#include <folly/Utility.h>
#include <folly/functional/Invoke.h>
#include <folly/lang/Align.h>
#include <folly/lang/Exception.h>
......@@ -426,13 +427,6 @@ std::shared_ptr<remove_cvref_t<T>> copy_to_shared_ptr(T&& t) {
return std::make_shared<remove_cvref_t<T>>(static_cast<T&&>(t));
}
namespace detail {
template <typename T>
struct erased_unique_ptr_deleter {
static void call(void* ptr) { delete static_cast<T*>(ptr); }
};
} // namespace detail
/**
* to_erased_unique_ptr
*
......@@ -442,7 +436,7 @@ struct erased_unique_ptr_deleter {
using erased_unique_ptr = std::unique_ptr<void, void (*)(void*)>;
template <typename T>
erased_unique_ptr to_erased_unique_ptr(T* ptr) {
return {ptr, &detail::erased_unique_ptr_deleter<T>::call};
return {ptr, detail::thunk::ruin<T>};
}
template <typename T>
erased_unique_ptr to_erased_unique_ptr(std::unique_ptr<T> ptr) {
......
......@@ -400,4 +400,35 @@ T declval() noexcept;
#define FOLLY_DECLVAL(...) ::folly::detail::declval<__VA_ARGS__>()
#endif
namespace detail {
// thunk
//
// A carefully curated collection of generic general-purpose thunk templates:
// * make: operator new with default constructor
// * ruin: operator delete
// * ctor: in-place default constructor
// * dtor: in-place destructor
struct thunk {
template <typename T>
static void* make() {
return new T();
}
template <typename T>
static void ruin(void* ptr) noexcept {
delete static_cast<T*>(ptr);
}
template <typename T>
static void ctor(void* ptr) {
::new (ptr) T();
}
template <typename T>
static void dtor(void* ptr) noexcept {
static_cast<T*>(ptr)->~T();
}
};
} // namespace detail
} // namespace folly
......@@ -22,6 +22,7 @@
#include <folly/CPortability.h>
#include <folly/Indestructible.h>
#include <folly/Likely.h>
#include <folly/Utility.h>
#include <folly/detail/Singleton.h>
#include <folly/lang/TypeInfo.h>
......@@ -57,9 +58,10 @@ class StaticSingletonManagerWithRtti {
public:
template <typename T, typename Tag>
FOLLY_EXPORT FOLLY_ALWAYS_INLINE static T& create() {
constexpr auto& make = thunk::make<T>;
// gcc and clang behave poorly if typeid is hidden behind a non-constexpr
// function, but typeid is not constexpr under msvc
static Arg arg{{nullptr}, FOLLY_TYPE_INFO_OF(tag_t<T, Tag>), make<T>};
static Arg arg{{nullptr}, FOLLY_TYPE_INFO_OF(tag_t<T, Tag>), make};
auto const v = arg.cache.load(std::memory_order_acquire);
auto const p = FOLLY_LIKELY(!!v) ? v : create_<noexcept(T())>(arg);
return *static_cast<T*>(p);
......@@ -75,11 +77,6 @@ class StaticSingletonManagerWithRtti {
Make& make;
};
template <typename T>
static void* make() {
return new T();
}
template <bool Noexcept>
FOLLY_NOINLINE static void* create_(Arg& arg) noexcept(Noexcept);
};
......
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