1 /***************************************************************************
2 * Mechanized Assault and Exploration Reloaded Projectfile *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20 #ifndef utility_invokeH
21 #define utility_invokeH
22
23 #include <functional>
24 #include <tuple>
25
26 #include "maxrconfig.h"
27
28 #include "utility/functiontraits.h"
29
30 #if MAXR_NO_VARIADIC_TEMPLATES
31
32 template<typename F>
invoke(const std::function<F> & func,const std::tuple<> & args)33 typename sFunctionTraits<F>::result_type invoke (const std::function<F>& func, const std::tuple<>& args)
34 {
35 static_assert (sFunctionTraits<F>::arity == 0, "Tuple size does not match functions argument count");
36 return func();
37 }
38
39 template<typename F, typename Arg1>
invoke(const std::function<F> & func,const std::tuple<Arg1> & args)40 typename sFunctionTraits<F>::result_type invoke (const std::function<F>& func, const std::tuple<Arg1>& args)
41 {
42 static_assert (sFunctionTraits<F>::arity == 1, "Tuple size does not match functions argument count");
43 return func (std::get<0> (args));
44 }
45
46 template<typename F, typename Arg1, typename Arg2>
invoke(const std::function<F> & func,const std::tuple<Arg1,Arg2> & args)47 typename sFunctionTraits<F>::result_type invoke (const std::function<F>& func, const std::tuple<Arg1, Arg2>& args)
48 {
49 static_assert (sFunctionTraits<F>::arity == 2, "Tuple size does not match functions argument count");
50 return func (std::get<0> (args), std::get<1> (args));
51 }
52
53 template<typename F, typename Arg1, typename Arg2, typename Arg3>
invoke(const std::function<F> & func,const std::tuple<Arg1,Arg2,Arg3> & args)54 typename sFunctionTraits<F>::result_type invoke (const std::function<F>& func, const std::tuple<Arg1, Arg2, Arg3>& args)
55 {
56 static_assert (sFunctionTraits<F>::arity == 3, "Tuple size does not match functions argument count");
57 return func (std::get<0> (args), std::get<1> (args), std::get<2> (args));
58 }
59
60 template<typename F, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
invoke(const std::function<F> & func,const std::tuple<Arg1,Arg2,Arg3,Arg4> & args)61 typename sFunctionTraits<F>::result_type invoke (const std::function<F>& func, const std::tuple<Arg1, Arg2, Arg3, Arg4>& args)
62 {
63 static_assert (sFunctionTraits<F>::arity == 4, "Tuple size does not match functions argument count");
64 return func (std::get<0> (args), std::get<1> (args), std::get<2> (args), std::get<3> (args));
65 }
66
67 template<typename F, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
invoke(const std::function<F> & func,const std::tuple<Arg1,Arg2,Arg3,Arg4,Arg5> & args)68 typename sFunctionTraits<F>::result_type invoke (const std::function<F>& func, const std::tuple<Arg1, Arg2, Arg3, Arg4, Arg5>& args)
69 {
70 static_assert (sFunctionTraits<F>::arity == 5, "Tuple size does not match functions argument count");
71 return func (std::get<0> (args), std::get<1> (args), std::get<2> (args), std::get<3> (args), std::get<4> (args));
72 }
73
74 #else
75
76 namespace detail
77 {
78
79 template<int ...>
80 struct sequence {};
81
82 template<int N, int ...S>
83 struct generate_sequence : generate_sequence < N - 1, N - 1, S... > {};
84
85 template<int ...S>
86 struct generate_sequence<0, S...>
87 {
88 typedef sequence<S...> type;
89 };
90
91 template<typename F, typename ArgsTuple, int ...S>
92 typename sFunctionTraits<F>::result_type invoke_impl (const std::function<F>& func, const ArgsTuple& args, sequence<S...>)
93 {
94 return func (std::get<S> (args)...);
95 }
96
97 } // namespace detail
98
99 template<typename F, typename... Args>
100 typename sFunctionTraits<F>::result_type invoke (const std::function<F>& func, const std::tuple<Args...>& args)
101 {
102 static_assert (sFunctionTraits<F>::arity == sizeof... (Args), "Tuple size does not match functions argument count");
103 return detail::invoke_impl (func, args, typename detail::generate_sequence<sizeof... (Args)>::type());
104 }
105
106 #endif // MAXR_NO_VARIADIC_TEMPLATES
107
108 #endif // utility_invokeH
109