ROOT  6.06/09
Reference Guide
impl_tuple_apply.h
Go to the documentation of this file.
1 /// \file impl_tuple_apply.h
2 /// \ingroup Base StdExt ROOT7
3 /// \author Axel Naumann <axel@cern.ch>
4 /// \date 2015-07-09
5 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
6 
7 /*************************************************************************
8  * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers. *
9  * All rights reserved. *
10  * *
11  * For the licensing terms see $ROOTSYS/LICENSE. *
12  * For the list of contributors see $ROOTSYS/README/CREDITS. *
13  *************************************************************************/
14 
15 #ifndef ROOT7_Impl_Tuple_Apply
16 #define ROOT7_Impl_Tuple_Apply
17 
18 #include <functional>
19 
20 // std::experimental::apply, invoke until it's there...
21 
22 namespace std {
23 // from http://en.cppreference.com/w/cpp/utility/functional/invoke
24 
25 namespace detail {
26 template <class F, class... Args>
27 inline auto INVOKE(F&& f, Args&&... args) ->
28 decltype(std::forward<F>(f)(std::forward<Args>(args)...)) {
29  return std::forward<F>(f)(std::forward<Args>(args)...);
30 }
31 
32 template <class Base, class T, class Derived>
33 inline auto INVOKE(T Base::*pmd, Derived&& ref) ->
34 decltype(std::forward<Derived>(ref).*pmd) {
35  return std::forward<Derived>(ref).*pmd;
36 }
37 
38 template <class PMD, class Pointer>
39 inline auto INVOKE(PMD pmd, Pointer&& ptr) ->
40 decltype((*std::forward<Pointer>(ptr)).*pmd) {
41  return (*std::forward<Pointer>(ptr)).*pmd;
42 }
43 
44 template <class Base, class T, class Derived, class... Args>
45 inline auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args) ->
46 decltype((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...)) {
47  return (std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...);
48 }
49 
50 template <class PMF, class Pointer, class... Args>
51 inline auto INVOKE(PMF pmf, Pointer&& ptr, Args&&... args) ->
52 decltype(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...)) {
53  return ((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...);
54 }
55 } // namespace detail
56 
57 template< class F, class... ArgTypes>
58 decltype(auto) invoke(F&& f, ArgTypes&&... args) {
59  return detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...);
60 }
61 
62 // From http://en.cppreference.com/w/cpp/experimental/apply
63 namespace detail {
64 template<class F, class Tuple, std::size_t... I>
65 constexpr decltype(auto) apply_impl(F &&f, Tuple &&t,
66  std::index_sequence<I...>) {
67  return invoke(std::forward<F>(f),
68  std::get<I>(std::forward<Tuple>(t))...);
69  // Note: std::invoke is a C++17 feature
70 }
71 } // namespace detail
72 
73 template<class F, class Tuple>
74 constexpr decltype(auto) apply(F &&f, Tuple &&t) {
75  return detail::apply_impl(std::forward<F>(f), std::forward<Tuple>(t),
76  std::make_index_sequence < std::tuple_size <
77  std::decay_t < Tuple >> {} > {});
78 }
79 }
80 
81 #endif //ROOT7_TUPLE_APPLY_H
double T(double x)
Definition: ChebyshevPol.h:34
auto INVOKE(F &&f, Args &&...args) -> decltype(std::forward< F >(f)(std::forward< Args >(args)...))
STL namespace.
size_t
Definition: TBuffer.cxx:28
#define F(x, y, z)
double f(double x)
#define I(x, y, z)
decltype(auto) constexpr apply_impl(F &&f, Tuple &&t, std::index_sequence< I...>)