Commit abc55483 authored by Eric Niebler's avatar Eric Niebler Committed by Facebook Github Bot

Add folly::Identity function object to Utility.h; replace AtomicHashArray's...

Add folly::Identity function object to Utility.h; replace AtomicHashArray's AHAIdentity and folly/gen's Identity with it

Summary: Code duplication is bad.

Reviewed By: yfeldblum

Differential Revision: D5011806

fbshipit-source-id: cab7bb3af1c934a5a63cd3fb98aa33f2578aebfb
parent 6d94a087
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <folly/Hash.h> #include <folly/Hash.h>
#include <folly/ThreadCachedInt.h> #include <folly/ThreadCachedInt.h>
#include <folly/Utility.h>
namespace folly { namespace folly {
...@@ -66,16 +67,6 @@ struct AtomicHashArrayQuadraticProbeFcn ...@@ -66,16 +67,6 @@ struct AtomicHashArrayQuadraticProbeFcn
// Enables specializing checkLegalKey without specializing its class. // Enables specializing checkLegalKey without specializing its class.
namespace detail { namespace detail {
// Local copy of folly::gen::Identity, to avoid heavy dependencies.
class AHAIdentity {
public:
template<class Value>
auto operator()(Value&& value) const ->
decltype(std::forward<Value>(value)) {
return std::forward<Value>(value);
}
};
template <typename NotKeyT, typename KeyT> template <typename NotKeyT, typename KeyT>
inline void checkLegalKeyIfKeyTImpl(NotKeyT /* ignored */, inline void checkLegalKeyIfKeyTImpl(NotKeyT /* ignored */,
KeyT /* emptyKey */, KeyT /* emptyKey */,
...@@ -91,20 +82,24 @@ inline void checkLegalKeyIfKeyTImpl(KeyT key_in, KeyT emptyKey, ...@@ -91,20 +82,24 @@ inline void checkLegalKeyIfKeyTImpl(KeyT key_in, KeyT emptyKey,
} }
} // namespace detail } // namespace detail
template <class KeyT, class ValueT, template <
class HashFcn = std::hash<KeyT>, class KeyT,
class EqualFcn = std::equal_to<KeyT>, class ValueT,
class Allocator = std::allocator<char>, class HashFcn = std::hash<KeyT>,
class ProbeFcn = AtomicHashArrayLinearProbeFcn, class EqualFcn = std::equal_to<KeyT>,
class KeyConvertFcn = detail::AHAIdentity> class Allocator = std::allocator<char>,
class ProbeFcn = AtomicHashArrayLinearProbeFcn,
class KeyConvertFcn = Identity>
class AtomicHashMap; class AtomicHashMap;
template <class KeyT, class ValueT, template <
class HashFcn = std::hash<KeyT>, class KeyT,
class EqualFcn = std::equal_to<KeyT>, class ValueT,
class Allocator = std::allocator<char>, class HashFcn = std::hash<KeyT>,
class ProbeFcn = AtomicHashArrayLinearProbeFcn, class EqualFcn = std::equal_to<KeyT>,
class KeyConvertFcn = detail::AHAIdentity> class Allocator = std::allocator<char>,
class ProbeFcn = AtomicHashArrayLinearProbeFcn,
class KeyConvertFcn = Identity>
class AtomicHashArray : boost::noncopyable { class AtomicHashArray : boost::noncopyable {
static_assert((std::is_convertible<KeyT,int32_t>::value || static_assert((std::is_convertible<KeyT,int32_t>::value ||
std::is_convertible<KeyT,int64_t>::value || std::is_convertible<KeyT,int64_t>::value ||
...@@ -348,13 +343,12 @@ friend class AtomicHashMap<KeyT, ...@@ -348,13 +343,12 @@ friend class AtomicHashMap<KeyT,
SimpleRetT() = default; SimpleRetT() = default;
}; };
template <
typename LookupKeyT = key_type,
template <typename LookupKeyT = key_type, typename LookupHashFcn = hasher,
typename LookupHashFcn = hasher, typename LookupEqualFcn = key_equal,
typename LookupEqualFcn = key_equal, typename LookupKeyToKeyFcn = Identity,
typename LookupKeyToKeyFcn = detail::AHAIdentity, typename... ArgTs>
typename... ArgTs>
SimpleRetT insertInternal(LookupKeyT key, ArgTs&&... vCtorArgs); SimpleRetT insertInternal(LookupKeyT key, ArgTs&&... vCtorArgs);
template <typename LookupKeyT = key_type, template <typename LookupKeyT = key_type,
......
...@@ -131,4 +131,31 @@ template <std::size_t N> ...@@ -131,4 +131,31 @@ template <std::size_t N>
using make_index_sequence = detail::make_index_sequence<N>; using make_index_sequence = detail::make_index_sequence<N>;
#endif #endif
/**
* A simple function object that passes its argument through unchanged.
*
* Example:
*
* int i = 42;
* int &j = Identity()(i);
* assert(&i == &j);
*
* Warning: passing a prvalue through Identity turns it into an xvalue,
* which can effect whether lifetime extension occurs or not. For instance:
*
* auto&& x = std::make_unique<int>(42);
* cout << *x ; // OK, x refers to a valid unique_ptr.
*
* auto&& y = Identity()(std::make_unique<int>(42));
* cout << *y ; // ERROR: y did not lifetime-extend the unique_ptr. It
* // is no longer valid
*/
struct Identity {
using is_transparent = void;
template <class T>
constexpr T&& operator()(T&& x) const noexcept {
return static_cast<T&&>(x);
}
};
} }
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <folly/Conv.h> #include <folly/Conv.h>
#include <folly/Optional.h> #include <folly/Optional.h>
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/Utility.h>
#include <folly/gen/Core.h> #include <folly/gen/Core.h>
/** /**
...@@ -199,15 +200,6 @@ public: ...@@ -199,15 +200,6 @@ public:
} }
}; };
class Identity {
public:
template<class Value>
auto operator()(Value&& value) const ->
decltype(std::forward<Value>(value)) {
return std::forward<Value>(value);
}
};
/** /**
* Class and helper function for negating a boolean Predicate * Class and helper function for negating a boolean Predicate
*/ */
......
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