diff --git a/src/AST/Template.cs b/src/AST/Template.cs index 941fca46..74b28b25 100644 --- a/src/AST/Template.cs +++ b/src/AST/Template.cs @@ -4,9 +4,15 @@ using System.Linq; namespace CppSharp.AST { + /// + /// Represents a template parameter + /// public struct TemplateParameter { public string Name; + + // Generic type constraint + public string Constraint; } /// diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index 964e2d91..28d19470 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -306,7 +306,7 @@ namespace CppSharp.Generators.CLI public void GenerateClassGenericMethods(Class @class) { - var printer = TypePrinter as CLITypePrinter; + var printer = TypePrinter; var oldCtx = printer.Context; PushIndent(); @@ -333,12 +333,28 @@ namespace CppSharp.Generators.CLI var retType = function.ReturnType.Type.Visit(typePrinter, function.ReturnType.Qualifiers); - var typeNamesStr = ""; + var typeNames = ""; var paramNames = template.Parameters.Select(param => param.Name).ToList(); if (paramNames.Any()) - typeNamesStr = "typename " + string.Join(", typename ", paramNames); + typeNames = "typename " + string.Join(", typename ", paramNames); + + Write("generic<{0}>", typeNames); + + // Process the generic type constraints + var constraints = new List(); + foreach (var param in template.Parameters) + { + if (string.IsNullOrWhiteSpace(param.Constraint)) + continue; + constraints.Add(string.Format("{0} : {1}", param.Name, + param.Constraint)); + } + + if (constraints.Any()) + Write(" where {0}", string.Join(", ", constraints)); + + NewLine(); - WriteLine("generic<{0}>", typeNamesStr); WriteLine("{0} {1}({2});", retType, SafeIdentifier(function.Name), GenerateParametersList(function.Parameters)); diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 370d2092..a624afd3 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -102,6 +102,22 @@ namespace CppSharp.Generators.CLI } } + if (Options.GenerateFunctionTemplates) + { + foreach (var template in @namespace.Templates) + { + if (template.Ignore) continue; + + var functionTemplate = template as FunctionTemplate; + if (functionTemplate == null) continue; + + if (functionTemplate.Ignore) + continue; + + GenerateFunctionTemplate(functionTemplate); + } + } + foreach(var childNamespace in @namespace.Namespaces) GenerateDeclContext(childNamespace); @@ -161,20 +177,6 @@ namespace CppSharp.Generators.CLI GenerateEvent(@event, @class); } - if (Options.GenerateFunctionTemplates) - { - foreach (var template in @class.Templates) - { - if (template.Ignore) continue; - - var functionTemplate = template as FunctionTemplate; - if (functionTemplate == null) continue; - - GenerateDeclarationCommon(template); - GenerateFunctionTemplate(functionTemplate, @class); - } - } - foreach (var variable in @class.Variables) { if (variable.Ignore) @@ -190,11 +192,13 @@ namespace CppSharp.Generators.CLI PopBlock(); } - private void GenerateFunctionTemplate(FunctionTemplate template, Class @class) + private void GenerateFunctionTemplate(FunctionTemplate template) { - var printer = TypePrinter as CLITypePrinter; + var printer = TypePrinter; var oldCtx = printer.Context; + PushBlock(CLIBlockKind.Template); + var function = template.TemplatedFunction; var typeCtx = new CLITypePrinterContext() @@ -209,23 +213,26 @@ namespace CppSharp.Generators.CLI var retType = function.ReturnType.Type.Visit(typePrinter, function.ReturnType.Qualifiers); - var typeNamesStr = ""; + var typeNames = ""; var paramNames = template.Parameters.Select(param => param.Name).ToList(); if (paramNames.Any()) - typeNamesStr = "typename " + string.Join(", typename ", paramNames); + typeNames = "typename " + string.Join(", typename ", paramNames); - WriteLine("generic<{0}>", typeNamesStr); + WriteLine("generic<{0}>", typeNames); WriteLine("{0} {1}::{2}({3})", retType, - QualifiedIdentifier(@class), SafeIdentifier(function.Name), + QualifiedIdentifier(function.Namespace), SafeIdentifier(function.Name), GenerateParametersList(function.Parameters)); WriteStartBraceIndent(); + var @class = function.Namespace as Class; GenerateFunctionCall(function, @class); WriteCloseBraceIndent(); NewLine(); + PopBlock(NewLineKind.BeforeNextBlock); + printer.Context = oldCtx; } @@ -734,7 +741,7 @@ namespace CppSharp.Generators.CLI { WriteLine("auto {0} = ::{1}();", valueMarshalName, @class.QualifiedOriginalName); - var param = new Parameter() { Name = "(*this)" }; + var param = new Parameter { Name = "(*this)" }; var ctx = new MarshalContext(Driver) { MarshalVarPrefix = valueMarshalName, @@ -844,7 +851,7 @@ namespace CppSharp.Generators.CLI }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); - function.ReturnType.Type.Visit(marshal, function.ReturnType.Qualifiers); + function.ReturnType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) Write(marshal.Context.SupportBefore);