/// \file impl_tuple_apply.h /// \ingroup Base StdExt ROOT7 /// \author Axel Naumann /// \date 2015-07-09 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome! /************************************************************************* * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #ifndef ROOT7_Impl_Tuple_Apply #define ROOT7_Impl_Tuple_Apply #include // std::experimental::apply, invoke until it's there... namespace std { // from http://en.cppreference.com/w/cpp/utility/functional/invoke namespace detail { template inline auto INVOKE(F&& f, Args&&... args) -> decltype(std::forward(f)(std::forward(args)...)) { return std::forward(f)(std::forward(args)...); } template inline auto INVOKE(T Base::*pmd, Derived&& ref) -> decltype(std::forward(ref).*pmd) { return std::forward(ref).*pmd; } template inline auto INVOKE(PMD pmd, Pointer&& ptr) -> decltype((*std::forward(ptr)).*pmd) { return (*std::forward(ptr)).*pmd; } template inline auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args) -> decltype((std::forward(ref).*pmf)(std::forward(args)...)) { return (std::forward(ref).*pmf)(std::forward(args)...); } template inline auto INVOKE(PMF pmf, Pointer&& ptr, Args&&... args) -> decltype(((*std::forward(ptr)).*pmf)(std::forward(args)...)) { return ((*std::forward(ptr)).*pmf)(std::forward(args)...); } } // namespace detail template< class F, class... ArgTypes> decltype(auto) invoke(F&& f, ArgTypes&&... args) { return detail::INVOKE(std::forward(f), std::forward(args)...); } // From http://en.cppreference.com/w/cpp/experimental/apply namespace detail { template constexpr decltype(auto) apply_impl(F &&f, Tuple &&t, std::index_sequence) { return invoke(std::forward(f), std::get(std::forward(t))...); // Note: std::invoke is a C++17 feature } } // namespace detail template constexpr decltype(auto) apply(F &&f, Tuple &&t) { return detail::apply_impl(std::forward(f), std::forward(t), std::make_index_sequence < std::tuple_size < std::decay_t < Tuple >> {} > {}); } } #endif //ROOT7_TUPLE_APPLY_H