@@ -17,6 +17,15 @@ public class PointerParameterOverloader : IFunctionOverloader
1717 /// <inheritdoc/>
1818 public IEnumerable < ImplementedFunction > CreateOverloads ( Function function )
1919 {
20+ // we can't have the void pointer parameter overloader separate otherwise it'll run forever
21+ // i.e. PointerParameterOverloader will turn IntPtr to void*
22+ // VoidPointerParameterOverloader will turn void* to IntPtr
23+ // etc
24+ foreach ( var overload in CreateOverloadsVoidPtr ( function ) )
25+ {
26+ yield return overload ;
27+ }
28+
2029 if ( ! function . Parameters . Any ( p => p . Type . IsIntPtr ( ) ) )
2130 {
2231 yield break ;
@@ -30,6 +39,7 @@ public IEnumerable<ImplementedFunction> CreateOverloads(Function function)
3039 var newGenericArray3DParameters = new List < Parameter > ( baseParameters ) ;
3140
3241 var newGenericTypeParameters = new List < GenericTypeParameter > ( ) ;
42+ newGenericTypeParameters . AddRange ( function . GenericTypeParameters ) ;
3343 for ( var i = 0 ; i < baseParameters . Count ; ++ i )
3444 {
3545 var parameter = baseParameters [ i ] ;
@@ -120,6 +130,184 @@ public IEnumerable<ImplementedFunction> CreateOverloads(Function function)
120130 . Build ( )
121131 ) ;
122132 }
133+
134+ /// <inheritdoc/>
135+ public IEnumerable < ImplementedFunction > CreateOverloadsVoidPtr ( Function function )
136+ {
137+ if ( ! function . Parameters . Any ( p => p . Type . IsSingleVoidPointer ( ) ) )
138+ {
139+ yield break ;
140+ }
141+
142+ var baseParameters = function . Parameters ;
143+
144+ var newIntPtrParameters = new List < Parameter > ( baseParameters ) ;
145+ var newGenericArray1DParameters = new List < Parameter > ( baseParameters ) ;
146+ var newGenericArray2DParameters = new List < Parameter > ( baseParameters ) ;
147+ var newGenericArray3DParameters = new List < Parameter > ( baseParameters ) ;
148+
149+ var newGenericTypeParameters = new List < GenericTypeParameter > ( ) ;
150+ newGenericTypeParameters . AddRange ( function . GenericTypeParameters ) ;
151+ for ( var i = 0 ; i < baseParameters . Count ; ++ i )
152+ {
153+ var parameter = baseParameters [ i ] ;
154+ if ( ! parameter . Type . IsSingleVoidPointer ( ) || parameter . Type . IsOut )
155+ {
156+ continue ;
157+ }
158+
159+ var genericTypeParameterName = baseParameters . Count ( p => p . Type . IsSingleVoidPointer ( ) ) > 1
160+ ? $ "T{ newGenericTypeParameters . Count + 1 } " : "T" ;
161+
162+ var genericTypeParameter = new GenericTypeParameter (
163+ genericTypeParameterName ,
164+ new [ ] { "unmanaged" } ) ;
165+
166+ newGenericTypeParameters . Add ( genericTypeParameter ) ;
167+
168+ var newIntPtrParameterType = new TypeSignatureBuilder ( parameter . Type )
169+ . WithIndirectionLevel ( 0 )
170+ . WithName ( "IntPtr" )
171+ . Build ( ) ;
172+
173+ // TODO: Simplify and generalize this
174+ var newGenericArray1DParameterType = new TypeSignatureBuilder ( parameter . Type )
175+ . WithIndirectionLevel ( 0 )
176+ . WithArrayDimensions ( 1 )
177+ . WithName ( genericTypeParameterName )
178+ . Build ( ) ;
179+
180+ var newGenericArray2DParameterType = new TypeSignatureBuilder ( parameter . Type )
181+ . WithIndirectionLevel ( 0 )
182+ . WithArrayDimensions ( 2 )
183+ . WithName ( genericTypeParameterName )
184+ . Build ( ) ;
185+
186+ var newGenericArray3DParameterType = new TypeSignatureBuilder ( parameter . Type )
187+ . WithIndirectionLevel ( 0 )
188+ . WithArrayDimensions ( 3 )
189+ . WithName ( genericTypeParameterName )
190+ . Build ( ) ;
191+
192+ newIntPtrParameters [ i ] = new ParameterSignatureBuilder ( parameter )
193+ . WithType ( newIntPtrParameterType )
194+ . Build ( ) ;
195+
196+ newGenericArray1DParameters [ i ] = new ParameterSignatureBuilder ( parameter )
197+ . WithType ( newGenericArray1DParameterType )
198+ . Build ( ) ;
199+
200+ newGenericArray2DParameters [ i ] = new ParameterSignatureBuilder ( parameter )
201+ . WithType ( newGenericArray2DParameterType )
202+ . Build ( ) ;
203+
204+ newGenericArray3DParameters [ i ] = new ParameterSignatureBuilder ( parameter )
205+ . WithType ( newGenericArray3DParameterType )
206+ . Build ( ) ;
207+ }
208+
209+ yield return ToIntPtr
210+ (
211+ new FunctionSignatureBuilder ( function )
212+ . WithParameters ( newIntPtrParameters )
213+ . Build ( ) ,
214+ function
215+ ) ;
216+
217+ yield return FixedVoidPtr
218+ (
219+ new FunctionSignatureBuilder ( function )
220+ . WithParameters ( newGenericArray1DParameters )
221+ . WithGenericTypeParameters ( newGenericTypeParameters )
222+ . Build ( )
223+ ) ;
224+
225+ yield return FixedVoidPtr
226+ (
227+ new FunctionSignatureBuilder ( function )
228+ . WithParameters ( newGenericArray2DParameters )
229+ . WithGenericTypeParameters ( newGenericTypeParameters )
230+ . Build ( )
231+ ) ;
232+
233+ yield return FixedVoidPtr
234+ (
235+ new FunctionSignatureBuilder ( function )
236+ . WithParameters ( newGenericArray3DParameters )
237+ . WithGenericTypeParameters ( newGenericTypeParameters )
238+ . Build ( )
239+ ) ;
240+ }
241+
242+ private static ImplementedFunction ToIntPtr ( Function function , Function old )
243+ {
244+ var sb = new StringBuilder ( ) ;
245+ sb . AppendLine ( "// PointerParameterOverloader" ) ;
246+ if ( function . ReturnType . ToString ( ) != "void" )
247+ {
248+ sb . Append ( "return " ) ;
249+ }
250+
251+ sb . Append ( $ "{ function . Name } (") ;
252+ var list = new List < string > ( ) ;
253+ foreach ( var param in old . Parameters )
254+ {
255+ var nm = Utilities . CSharpKeywords . Contains ( param . Name ) ? $ "@{ param . Name } " : param . Name ;
256+ if ( param . Type . IsSingleVoidPointer ( ) )
257+ {
258+ list . Add ( $ "(void*) { nm } ") ;
259+ }
260+ else
261+ {
262+ var prefix = param . Type . IsOut ? "out " : param . Type . IsByRef ? "ref " : string . Empty ;
263+ list . Add ( prefix + nm ) ;
264+ }
265+ }
266+
267+ sb . Append ( string . Join ( ", " , list ) ) ;
268+ sb . AppendLine ( ");" ) ;
269+ return new ImplementedFunction ( function , sb , true ) ;
270+ }
271+
272+ private static ImplementedFunction FixedVoidPtr ( Function function )
273+ {
274+ var sb = new StringBuilder ( ) ;
275+ var parameters = new List < string > ( ) ;
276+ var ind = string . Empty ;
277+ sb . AppendLine ( "// PointerParameterOverloader" ) ;
278+ foreach ( var param in function . Parameters )
279+ {
280+ var nm = Utilities . CSharpKeywords . Contains ( param . Name ) ? $ "@{ param . Name } " : param . Name ;
281+ if ( function . GenericTypeParameters . Any ( x => x . Name == param . Type . Name ) )
282+ {
283+ sb . AppendLine ( $ "{ ind } fixed ({ param . Type . Name } * { param . Name } Ptr = { nm } )") ;
284+ sb . AppendLine ( $ "{ ind } {{") ;
285+ ind += " " ;
286+ parameters . Add ( $ "(void*) { param . Name } Ptr") ;
287+ }
288+ else
289+ {
290+ var prefix = param . Type . IsOut ? "out " : param . Type . IsByRef ? "ref " : string . Empty ;
291+ parameters . Add ( prefix + nm ) ;
292+ }
293+ }
294+
295+ sb . Append ( ind ) ;
296+ if ( function . ReturnType . ToString ( ) != "void" )
297+ {
298+ sb . Append ( "return " ) ;
299+ }
300+
301+ sb . AppendLine ( $ "{ function . Name } ({ string . Join ( ", " , parameters ) } );") ;
302+
303+ while ( ! string . IsNullOrEmpty ( ind ) )
304+ {
305+ ind = ind . Remove ( ind . Length - 4 , 4 ) ;
306+ sb . AppendLine ( $ "{ ind } }}") ;
307+ }
308+
309+ return new ImplementedFunction ( function , sb , true ) ;
310+ }
123311
124312 private static ImplementedFunction ToPointer ( Function function , Function old )
125313 {
0 commit comments