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

a std::decay_t lookalike

Summary: Appears to be measurably faster to compile under clang as compared to `std::decay_t`.

Reviewed By: Alfus, luciang

Differential Revision: D32946561

fbshipit-source-id: 028c79633095ae9d6dc75d967282b53b32986736
parent eadf2192
...@@ -60,6 +60,23 @@ T declval() noexcept; ...@@ -60,6 +60,23 @@ T declval() noexcept;
#define FOLLY_DECLVAL(...) ::folly::detail::declval<__VA_ARGS__>() #define FOLLY_DECLVAL(...) ::folly::detail::declval<__VA_ARGS__>()
#endif #endif
namespace detail {
template <typename T>
T decay_(T) noexcept;
// decay_t
//
// Like std::decay_t but possibly faster to compile.
//
// Marked as detail since this differs from std::decay_t in some respects:
// * incomplete decayed types are forbidden
// * non-moveable decayed types are forbidden
//
// mimic: std::decay_t, C++14
template <typename T>
using decay_t = decltype(detail::decay_(FOLLY_DECLVAL(T &&)));
} // namespace detail
/** /**
* copy * copy
* *
...@@ -103,9 +120,9 @@ T declval() noexcept; ...@@ -103,9 +120,9 @@ T declval() noexcept;
*/ */
template <typename T> template <typename T>
constexpr typename std::decay<T>::type copy(T&& value) noexcept( constexpr detail::decay_t<T> copy(T&& value) noexcept(
noexcept(typename std::decay<T>::type(std::forward<T>(value)))) { noexcept(detail::decay_t<T>(static_cast<T&&>(value)))) {
return std::forward<T>(value); return static_cast<T&&>(value);
} }
/** /**
......
...@@ -32,6 +32,31 @@ static_assert(std::is_same_v<decltype(FOLLY_DECLVAL(int&)), int&>); ...@@ -32,6 +32,31 @@ static_assert(std::is_same_v<decltype(FOLLY_DECLVAL(int&)), int&>);
static_assert(std::is_same_v<decltype(FOLLY_DECLVAL(int&&)), int&&>); static_assert(std::is_same_v<decltype(FOLLY_DECLVAL(int&&)), int&&>);
static_assert(noexcept(FOLLY_DECLVAL(int))); static_assert(noexcept(FOLLY_DECLVAL(int)));
// Tests for folly::decay_t:
template <typename T>
using dec = folly::detail::decay_t<T>;
static_assert(std::is_same_v<int, dec<int>>);
static_assert(std::is_same_v<int, dec<int&>>);
static_assert(std::is_same_v<int, dec<int&&>>);
static_assert(std::is_same_v<int, dec<int const>>);
static_assert(std::is_same_v<int, dec<int const&&>>);
static_assert(std::is_same_v<int, dec<int const&>>);
static_assert(std::is_same_v<int, dec<int volatile>>);
static_assert(std::is_same_v<int, dec<int volatile&>>);
static_assert(std::is_same_v<int, dec<int volatile&&>>);
static_assert(std::is_same_v<int, dec<int const volatile>>);
static_assert(std::is_same_v<int, dec<int const volatile&>>);
static_assert(std::is_same_v<int, dec<int const volatile&&>>);
static_assert(std::is_same_v<int*, dec<int*>>);
static_assert(std::is_same_v<int*, dec<int[]>>);
static_assert(std::is_same_v<int*, dec<int[7]>>);
static_assert(std::is_same_v<int*, dec<int*&>>);
static_assert(std::is_same_v<int*, dec<int (&)[]>>);
static_assert(std::is_same_v<int*, dec<int (&)[7]>>);
static_assert(std::is_same_v<int (*)(), dec<int (*)()>>);
static_assert(std::is_same_v<int (*)(), dec<int (&)()>>);
TEST_F(UtilityTest, copy) { TEST_F(UtilityTest, copy) {
struct MyData {}; struct MyData {};
struct Worker { struct Worker {
......
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