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