12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- // (c) Daniel Llorens - 2011
- // This library is free software; you can redistribute it and/or modify it under
- // the terms of the GNU Lesser General Public License as published by the Free
- // Software Foundation; either version 3 of the License, or (at your option) any
- // later version.
- /// @file arglist.H
- /// @brief Manipulate argument list.
- #pragma once
- #include "ra/macros.H"
- #include <tuple>
- // @note It's cleaner to have P0, P ... be parameters of the function and not of the class, but that triggers unimplemented features on gcc 4.5--4.6. Also below shuffle_args<>.
- template <int i, class T, class Enable=void>
- struct nth_arg_impl;
- template <int i, class P0, class ... P>
- struct nth_arg_impl<i, std::tuple<P0, P ...>, std::enable_if_t<i==0>>
- {
- static decltype(auto) f(P0 && p0, P && ... p)
- {
- return std::forward<P0>(p0);
- }
- };
- template <int i, class P0, class ... P>
- struct nth_arg_impl<i, std::tuple<P0, P ...>, std::enable_if_t<(i>0)>>
- {
- static_assert(i<=sizeof...(P), "bad argument index");
- using rest = std::tuple<P ...>;
- static auto f(P0 && p0, P && ... p) -> decltype(nth_arg_impl<i-1, rest>::f(std::forward<P>(p) ...))
- {
- return nth_arg_impl<i-1, rest>::f(std::forward<P>(p) ...);
- }
- };
- template <int i, class ... P>
- inline auto nth_arg(P && ... p) -> decltype(nth_arg_impl<i, std::tuple<P ...>>::f(std::forward<P>(p) ...))
- {
- return nth_arg_impl<i, std::tuple<P ...>>::f(std::forward<P>(p) ...);
- }
- template <class II, class TT>
- struct shuffle_args_impl;
- template <class ... I, class ... T>
- struct shuffle_args_impl<std::tuple<I ...>, std::tuple<T ...>>
- {
- using II = std::tuple<I ...>;
- using TT = std::tuple<T ...>;
- template <class G>
- static auto f(G && g, T && ... t) -> decltype(g(nth_arg<I::value>(std::forward<T>(t) ...) ...))
- {
- return g(nth_arg<I::value>(std::forward<T>(t) ...) ...);
- }
- template <class G>
- static auto ff(T && ... t) -> decltype(G::f(nth_arg<I::value>(std::forward<T>(t) ...) ...))
- {
- return G::f(nth_arg<I::value>(std::forward<T>(t) ...) ...);
- }
- };
- // when shuffling doesn't change the types.
- template <class II, class G, class ... T>
- static auto shuffle_args(G && g, T && ... t)
- -> decltype(shuffle_args_impl<II, std::tuple<T ...>>::template f(std::forward<G>(g), std::forward<T>(t) ...))
- {
- return shuffle_args_impl<II, std::tuple<T ...>>::template f(std::forward<G>(g), std::forward<T>(t) ...);
- }
- // when shuffling changes the types, cannot use a single g.
- template <class II, class G, class ... T>
- static auto shuffle_args_types(T && ... t)
- -> decltype(shuffle_args_impl<II, std::tuple<T ...>>::template ff<G>(std::forward<T>(t) ...))
- {
- return shuffle_args_impl<II, std::tuple<T ...>>::template ff<G>(std::forward<T>(t) ...);
- }
|