Logo ROOT   6.16/01
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// from http://en.cppreference.com/w/cpp/utility/functional/invoke
24
25#ifndef R__HAS_STD_INVOKE
26namespace ROOT {
27namespace Detail {
28template <class F, class... Args>
29inline auto INVOKE(F&& f, Args&&... args) ->
30decltype(std::forward<F>(f)(std::forward<Args>(args)...)) {
31 return std::forward<F>(f)(std::forward<Args>(args)...);
32}
33
34template <class Base, class T, class Derived>
35inline auto INVOKE(T Base::*pmd, Derived&& ref) ->
36decltype(std::forward<Derived>(ref).*pmd) {
37 return std::forward<Derived>(ref).*pmd;
38}
39
40template <class PMD, class Pointer>
41inline auto INVOKE(PMD pmd, Pointer&& ptr) ->
42decltype((*std::forward<Pointer>(ptr)).*pmd) {
43 return (*std::forward<Pointer>(ptr)).*pmd;
44}
45
46template <class Base, class T, class Derived, class... Args>
47inline auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args) ->
48decltype((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...)) {
49 return (std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...);
50}
51
52template <class PMF, class Pointer, class... Args>
53inline auto INVOKE(PMF pmf, Pointer&& ptr, Args&&... args) ->
54decltype(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...)) {
55 return ((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...);
56}
57} // namespace Detail
58} // namespace ROOT
59
60namespace std {
61inline namespace __ROOT {
62
63template< class F, class... ArgTypes>
64decltype(auto) invoke(F&& f, ArgTypes&&... args) {
65 return ROOT::Detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...);
66}
67
68} // inline namespace __ROOT {
69} // namespace std
70#endif // ndef R__HAS_STD_INVOKE
71
72#ifndef R__HAS_STD_APPLY
73// From http://en.cppreference.com/w/cpp/experimental/apply
74namespace ROOT {
75namespace Detail {
76template<class F, class Tuple, std::size_t... I>
77constexpr decltype(auto) apply_impl(F &&f, Tuple &&t,
79 return std::invoke(std::forward<F>(f),
80 std::get<I>(std::forward<Tuple>(t))...);
81 // Note: std::invoke is a C++17 feature
82}
83} // namespace Detail
84} // namespace ROOT
85
86namespace std {
87inline namespace __ROOT {
88template<class F, class Tuple>
89constexpr decltype(auto) apply(F &&f, Tuple &&t) {
90 return ROOT::Detail::apply_impl(std::forward<F>(f), std::forward<Tuple>(t),
91 std::make_index_sequence < std::tuple_size <
92 std::decay_t < Tuple >> {} > {});
93}
94} // inline namespace __ROOT
95} // namespace std
96#endif // ndef R__HAS_STD_APPLY
97
98#endif //ROOT7_TUPLE_APPLY_H
#define f(i)
Definition: RSha256.hxx:104
#define F(x, y, z)
#define I(x, y, z)
auto INVOKE(F &&f, Args &&... args) -> decltype(std::forward< F >(f)(std::forward< Args >(args)...))
constexpr decltype(auto) apply_impl(F &&f, Tuple &&t, std::index_sequence< I... >)
double T(double x)
Definition: ChebyshevPol.h:34
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
constexpr decltype(auto) apply(F &&f, Tuple &&t)
decltype(auto) invoke(F &&f, ArgTypes &&... args)
STL namespace.
make_integer_sequence< size_t, _Np > make_index_sequence