X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FApplyTuple.h;h=cce6fec07d6e3e23bf0e6a574f8ac352535953db;hp=3046e0fbce99de7cbf7ea387dcb69bff223f8863;hb=02fe20e3434fd6400ecf2ad92c7e1231b8f17108;hpb=2843ff12364e1159d99f2b96bcc4a5c428dad1fa diff --git a/folly/ApplyTuple.h b/folly/ApplyTuple.h index 3046e0fb..cce6fec0 100644 --- a/folly/ApplyTuple.h +++ b/folly/ApplyTuple.h @@ -113,5 +113,52 @@ inline constexpr auto applyTuple(F&& f, Tuples&&... t) detail::apply_tuple::MakeIndexSequenceFromTuple{}); } +namespace detail { +namespace apply_tuple { + +template +class Uncurry { + public: + explicit Uncurry(F&& func) : func_(std::move(func)) {} + explicit Uncurry(const F& func) : func_(func) {} + + template + auto operator()(Tuple&& tuple) const + -> decltype(applyTuple(std::declval(), std::forward(tuple))) { + return applyTuple(func_, std::forward(tuple)); + } + + private: + F func_; +}; +} // namespace apply_tuple +} // namespace detail + +/** + * Wraps a function taking N arguments into a function which accepts a tuple of + * N arguments. Note: This function will also accept an std::pair if N == 2. + * + * For example, given the below code: + * + * std::vector> rows = ...; + * auto test = [](std::tuple& row) { + * return std::get<0>(row) * std::get<1>(row) * std::get<2>(row) == 24; + * }; + * auto found = std::find_if(rows.begin(), rows.end(), test); + * + * + * 'test' could be rewritten as: + * + * auto test = + * folly::uncurry([](int a, int b, int c) { return a * b * c == 24; }); + * + */ +template +auto uncurry(F&& f) + -> detail::apply_tuple::Uncurry::type> { + return detail::apply_tuple::Uncurry::type>( + std::forward(f)); +} + ////////////////////////////////////////////////////////////////////// }