Logo ROOT   6.08/07
Reference Guide
impl_tuple_apply.hxx
Go to the documentation of this file.
1 /// \file ROOT/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 "RConfigure.h"
19 
20 #include <functional>
21 
22 // std::experimental::apply, invoke until it's there...
23 
24 namespace std {
25 // from http://en.cppreference.com/w/cpp/utility/functional/invoke
26 
27 inline namespace __ROOT {
28 
29 #ifndef R__HAS_STD_INVOKE
30 namespace detail {
31 template <class F, class... Args>
32 inline auto INVOKE(F&& f, Args&&... args) ->
33 decltype(std::forward<F>(f)(std::forward<Args>(args)...)) {
34  return std::forward<F>(f)(std::forward<Args>(args)...);
35 }
36 
37 template <class Base, class T, class Derived>
38 inline auto INVOKE(T Base::*pmd, Derived&& ref) ->
39 decltype(std::forward<Derived>(ref).*pmd) {
40  return std::forward<Derived>(ref).*pmd;
41 }
42 
43 template <class PMD, class Pointer>
44 inline auto INVOKE(PMD pmd, Pointer&& ptr) ->
45 decltype((*std::forward<Pointer>(ptr)).*pmd) {
46  return (*std::forward<Pointer>(ptr)).*pmd;
47 }
48 
49 template <class Base, class T, class Derived, class... Args>
50 inline auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args) ->
51 decltype((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...)) {
52  return (std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...);
53 }
54 
55 template <class PMF, class Pointer, class... Args>
56 inline auto INVOKE(PMF pmf, Pointer&& ptr, Args&&... args) ->
57 decltype(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...)) {
58  return ((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...);
59 }
60 } // namespace detail
61 
62 template< class F, class... ArgTypes>
63 decltype(auto) invoke(F&& f, ArgTypes&&... args) {
64  return detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...);
65 }
66 #endif // ndef R__HAS_STD_INVOKE
67 
68 // From http://en.cppreference.com/w/cpp/experimental/apply
69 namespace detail {
70 template<class F, class Tuple, std::size_t... I>
71 constexpr decltype(auto) apply_impl(F &&f, Tuple &&t,
72  std::index_sequence<I...>) {
73  return invoke(std::forward<F>(f),
74  std::get<I>(std::forward<Tuple>(t))...);
75  // Note: std::invoke is a C++17 feature
76 }
77 } // namespace detail
78 
79 template<class F, class Tuple>
80 constexpr decltype(auto) apply(F &&f, Tuple &&t) {
81  return detail::apply_impl(std::forward<F>(f), std::forward<Tuple>(t),
82  std::make_index_sequence < std::tuple_size <
83  std::decay_t < Tuple >> {} > {});
84 }
85 } // namespace __ROOT
86 } // namespace std
87 
88 #endif //ROOT7_TUPLE_APPLY_H
double T(double x)
Definition: ChebyshevPol.h:34
STL namespace.
#define F(x, y, z)
auto INVOKE(F &&f, Args &&... args) -> decltype(std::forward< F >(f)(std::forward< Args >(args)...))
decltype(auto) invoke(F &&f, ArgTypes &&... args)
double f(double x)
decltype(auto) constexpr apply_impl(F &&f, Tuple &&t, std::index_sequence< I... >)
#define I(x, y, z)
decltype(auto) constexpr apply(F &&f, Tuple &&t)