-template<class Tuple>
-struct DerefSize
- : std::tuple_size<typename std::remove_reference<Tuple>::type>
-{};
-
-// CallTuple recursively unpacks tuple arguments so we can forward
-// them into the function.
-template<class Ret>
-struct CallTuple {
- template<class F, class Tuple, class ...Unpacked>
- static typename std::enable_if<
- (sizeof...(Unpacked) < DerefSize<Tuple>::value),
- Ret
- >::type call(const F& f, Tuple&& t, Unpacked&&... unp) {
- typedef typename std::tuple_element<
- sizeof...(Unpacked),
- typename std::remove_reference<Tuple>::type
- >::type ElementType;
- return CallTuple<Ret>::call(f, std::forward<Tuple>(t),
- std::forward<Unpacked>(unp)...,
- std::forward<ElementType>(std::get<sizeof...(Unpacked)>(t))
- );
- }
-
- template<class F, class Tuple, class ...Unpacked>
- static typename std::enable_if<
- (sizeof...(Unpacked) == DerefSize<Tuple>::value),
- Ret
- >::type call(const F& f, Tuple&& t, Unpacked&&... unp) {
- return makeCallable(f)(std::forward<Unpacked>(unp)...);
- }
-};
-
-// The point of this meta function is to extract the contents of the
-// tuple as a parameter pack so we can pass it into std::result_of<>.
-template<class F, class Args> struct ReturnValue {};
-template<class F, class ...Args>
-struct ReturnValue<F,std::tuple<Args...>> {
- typedef typename std::result_of<F (Args...)>::type type;
-};
+template <class F, class Tuple, std::size_t... Indexes>
+inline constexpr auto call(F&& f, Tuple&& t, folly::index_sequence<Indexes...>)
+ -> decltype(
+ std::forward<F>(f)(std::get<Indexes>(std::forward<Tuple>(t))...)) {
+ return std::forward<F>(f)(std::get<Indexes>(std::forward<Tuple>(t))...);
+}