Got changes to song book numbers to save
[kworship.git] / include / functionInfo.h
blobaa28eaff0c3f832c13c32a1624522143d65431c4
1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
5 * KWorship is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * KWorship is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
20 #ifndef _functionInfo_h_
21 #define _functionInfo_h_
23 #include "repeatMacros.h"
25 namespace meta
27 template <typename F>
28 struct Tuple;
29 #define META_TUPLE(ARGS) ::meta::Tuple<void (*)ARGS>
31 template <typename F, int P>
32 struct ParameterInfo;
34 // Number of arguments of a function
35 template <typename F>
36 struct FunctionInfo;
39 // Macros to make this easier
41 // Parameter list, e.g. "typename Param0; typename Param1;"
42 #define FUNCTION_INFO_PARAM_INSTANTIATION(A,B,N) Param##N param##N;
43 #define FUNCTION_INFO_PARAM_INSTANTIATIONS(N) REPEATB(FUNCTION_INFO_PARAM_INSTANTIATION,0,0,N)
44 // Parameter list, e.g. "typename Param0, typename Param1"
45 #define FUNCTION_INFO_TEMPLATE_PARAMETER(A,B,N) typename Param##N
46 #define FUNCTION_INFO_TEMPLATE_PARAMETERS(N) REPEATB_LIST(FUNCTION_INFO_TEMPLATE_PARAMETER,0,0,N)
47 // Parameter list, e.g. ", typename Param0, typename Param1"
48 #define FUNCTION_INFO_TEMPLATE_PARAMETER_TAIL(A,B,N) , typename Param##N
49 #define FUNCTION_INFO_TEMPLATE_PARAMETERS_TAIL(N) REPEATB(FUNCTION_INFO_TEMPLATE_PARAMETER_TAIL,0,0,N)
50 // Argument list, e.g. "(Param0 param0, Param1 param1)"
51 #define FUNCTION_INFO_PARAMETER(A,B,N) Param##N param##N
52 #define FUNCTION_INFO_PARAMETERS(N) \
53 ( REPEATB_LIST(FUNCTION_INFO_PARAMETER,0,0,N) )
54 // Tail argument list, e.g. ", Param0, Param1"
55 #define FUNCTION_INFO_PARAMETER_TAIL(A,B,N) , Param##N
56 #define FUNCTION_INFO_PARAMETERS_TAIL(N) \
57 REPEATB(FUNCTION_INFO_PARAMETER_TAIL,0,0,N)
58 // Argument list, e.g. "(param0, param1)"
59 #define FUNCTION_INFO_ARGUMENT(A,B,N) param##N
60 #define FUNCTION_INFO_ARGUMENTS(N) \
61 ( REPEATB_LIST(FUNCTION_INFO_ARGUMENT,0,0,N) )
62 // Unpack Argument list, e.g. "(P.param0, P.param1)"
63 #define FUNCTION_INFO_UNPACK_ARGUMENT(P,B,N) (P).param##N
64 #define FUNCTION_INFO_UNPACK_ARGUMENTS(P,N) \
65 ( REPEATB_LIST(FUNCTION_INFO_UNPACK_ARGUMENT,P,0,N) )
67 // Parameter template instantiation
68 #define PARAMETER_INFO(T,N) \
69 template <FUNCTION_INFO_TEMPLATE_PARAMETERS(T) > \
70 struct ParameterInfo<void (*)FUNCTION_INFO_PARAMETERS(T),N> \
71 { \
72 typedef Param##N Type; \
75 // Function length template instantiation
76 #define FUNCTION_INFO(N) \
77 template <FUNCTION_INFO_TEMPLATE_PARAMETERS(N) > \
78 struct Tuple<void (*)FUNCTION_INFO_PARAMETERS(N)> \
79 { \
80 enum \
81 { \
82 length = N \
83 }; \
84 struct Pack \
85 { \
86 /* A member for each item */ \
87 FUNCTION_INFO_PARAM_INSTANTIATIONS(N) \
88 /* Construct a new CTYPE using the pack as arguments */ \
89 template <typename CTYPE> \
90 CTYPE* construct() const \
91 { \
92 return new CTYPE FUNCTION_INFO_ARGUMENTS(N); \
93 } \
94 }; \
95 static struct Pack pack FUNCTION_INFO_PARAMETERS(N) \
96 { \
97 Pack myPack = { REPEATB_LIST(FUNCTION_INFO_ARGUMENT,0,0,N) }; \
98 return myPack; \
99 } \
100 template <int id> \
101 struct Param : public ParameterInfo<void (*)FUNCTION_INFO_PARAMETERS(N), id> \
103 }; \
104 template <typename Ret> \
105 struct Return \
107 typedef Ret (Signiture)FUNCTION_INFO_PARAMETERS(N); \
108 typedef Ret (*Pointer)FUNCTION_INFO_PARAMETERS(N); \
109 typedef FunctionInfo<Pointer> Info; \
110 }; \
111 template <typename NewArg> \
112 struct Unshift \
114 typedef void (*Pointer)(NewArg FUNCTION_INFO_PARAMETERS_TAIL(N)); \
115 typedef Tuple<Pointer> Info; \
116 }; \
117 }; \
118 template <typename Ret FUNCTION_INFO_TEMPLATE_PARAMETERS_TAIL(N) > \
119 struct FunctionInfo<Ret (*)FUNCTION_INFO_PARAMETERS(N)> \
121 typedef Ret Return; \
122 typedef Ret (*Pointer)FUNCTION_INFO_PARAMETERS(N); \
123 typedef Tuple<void (*)FUNCTION_INFO_PARAMETERS(N)> Params; \
124 template <typename FUNCTOR> \
125 static Ret unpack(typename Params::Pack package) \
127 return FUNCTOR::call FUNCTION_INFO_UNPACK_ARGUMENTS(package,N); \
129 template <typename NewArg> \
130 struct Unshift \
132 typedef Ret (*Pointer)(NewArg FUNCTION_INFO_PARAMETERS_TAIL(N)); \
133 typedef FunctionInfo<Pointer> Info; \
134 }; \
135 }; \
136 REPEATA(PARAMETER_INFO, N, N)
139 REPEAT(FUNCTION_INFO, 8)
141 #undef FUNCTION_INFO_PARAMETER
142 #undef FUNCTION_INFO_PARAMETERS
143 #undef FUNCTION_INFO_ARGUMENT
144 #undef FUNCTION_INFO_POINTER_TYPE
145 #undef PARAMETER_INFO
146 #undef FUNCTION_INFO
149 #endif // _functionInfo_h_