X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FApplyTuple.h;h=cce6fec07d6e3e23bf0e6a574f8ac352535953db;hb=d84e6482135417bafed3dea69c29b8d8b8c39970;hp=b22987766702fa4f023ae780abf30e0c55c7d4e9;hpb=74d1af87831f9df2b5cb9d104db1d0e2edab591e;p=folly.git diff --git a/folly/ApplyTuple.h b/folly/ApplyTuple.h index b2298776..cce6fec0 100644 --- a/folly/ApplyTuple.h +++ b/folly/ApplyTuple.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,8 @@ #include #include +#include + namespace folly { ////////////////////////////////////////////////////////////////////// @@ -38,15 +40,6 @@ namespace folly { namespace detail { namespace apply_tuple { -template -struct IndexSequence {}; - -template -struct MakeIndexSequence : MakeIndexSequence {}; - -template -struct MakeIndexSequence<0, Is...> : IndexSequence {}; - inline constexpr std::size_t sum() { return 0; } @@ -61,7 +54,7 @@ struct TupleSizeSum { }; template -using MakeIndexSequenceFromTuple = MakeIndexSequence< +using MakeIndexSequenceFromTuple = folly::make_index_sequence< TupleSizeSum::type...>::value>; // This is to allow using this with pointers to member functions, @@ -76,14 +69,14 @@ inline constexpr auto makeCallable(M(C::*d)) -> decltype(std::mem_fn(d)) { } template -inline constexpr auto call(F&& f, Tuple&& t, IndexSequence) +inline constexpr auto call(F&& f, Tuple&& t, folly::index_sequence) -> decltype( std::forward(f)(std::get(std::forward(t))...)) { return std::forward(f)(std::get(std::forward(t))...); } template -inline constexpr auto forwardTuple(Tuple&& t, IndexSequence) +inline constexpr auto forwardTuple(Tuple&& t, folly::index_sequence) -> decltype( std::forward_as_tuple(std::get(std::forward(t))...)) { return std::forward_as_tuple(std::get(std::forward(t))...); @@ -120,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)); +} + ////////////////////////////////////////////////////////////////////// }