From: Eric Niebler Date: Tue, 9 May 2017 21:30:11 +0000 (-0700) Subject: Add folly::Identity function object to Utility.h; replace AtomicHashArray's AHAIdenti... X-Git-Tag: v2017.05.15.00~18 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=commitdiff_plain;h=abc5548320d2f51e31a4dbb0a5031fcd54171aa5 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 --- diff --git a/folly/AtomicHashArray.h b/folly/AtomicHashArray.h index 96a647d1..e590dad5 100644 --- a/folly/AtomicHashArray.h +++ b/folly/AtomicHashArray.h @@ -39,6 +39,7 @@ #include #include +#include namespace folly { @@ -66,16 +67,6 @@ struct AtomicHashArrayQuadraticProbeFcn // Enables specializing checkLegalKey without specializing its class. namespace detail { -// Local copy of folly::gen::Identity, to avoid heavy dependencies. -class AHAIdentity { - public: - template - auto operator()(Value&& value) const -> - decltype(std::forward(value)) { - return std::forward(value); - } -}; - template inline void checkLegalKeyIfKeyTImpl(NotKeyT /* ignored */, KeyT /* emptyKey */, @@ -91,20 +82,24 @@ inline void checkLegalKeyIfKeyTImpl(KeyT key_in, KeyT emptyKey, } } // namespace detail -template , - class EqualFcn = std::equal_to, - class Allocator = std::allocator, - class ProbeFcn = AtomicHashArrayLinearProbeFcn, - class KeyConvertFcn = detail::AHAIdentity> +template < + class KeyT, + class ValueT, + class HashFcn = std::hash, + class EqualFcn = std::equal_to, + class Allocator = std::allocator, + class ProbeFcn = AtomicHashArrayLinearProbeFcn, + class KeyConvertFcn = Identity> class AtomicHashMap; -template , - class EqualFcn = std::equal_to, - class Allocator = std::allocator, - class ProbeFcn = AtomicHashArrayLinearProbeFcn, - class KeyConvertFcn = detail::AHAIdentity> +template < + class KeyT, + class ValueT, + class HashFcn = std::hash, + class EqualFcn = std::equal_to, + class Allocator = std::allocator, + class ProbeFcn = AtomicHashArrayLinearProbeFcn, + class KeyConvertFcn = Identity> class AtomicHashArray : boost::noncopyable { static_assert((std::is_convertible::value || std::is_convertible::value || @@ -348,13 +343,12 @@ friend class AtomicHashMap + template < + typename LookupKeyT = key_type, + typename LookupHashFcn = hasher, + typename LookupEqualFcn = key_equal, + typename LookupKeyToKeyFcn = Identity, + typename... ArgTs> SimpleRetT insertInternal(LookupKeyT key, ArgTs&&... vCtorArgs); template using make_index_sequence = detail::make_index_sequence; #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(42); + * cout << *x ; // OK, x refers to a valid unique_ptr. + * + * auto&& y = Identity()(std::make_unique(42)); + * cout << *y ; // ERROR: y did not lifetime-extend the unique_ptr. It + * // is no longer valid + */ +struct Identity { + using is_transparent = void; + template + constexpr T&& operator()(T&& x) const noexcept { + return static_cast(x); + } +}; } diff --git a/folly/gen/Base.h b/folly/gen/Base.h index 61e9d410..a5d4b05a 100644 --- a/folly/gen/Base.h +++ b/folly/gen/Base.h @@ -30,6 +30,7 @@ #include #include #include +#include #include /** @@ -199,15 +200,6 @@ public: } }; -class Identity { -public: - template - auto operator()(Value&& value) const -> - decltype(std::forward(value)) { - return std::forward(value); - } -}; - /** * Class and helper function for negating a boolean Predicate */