diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index e3afe2c9..b1d6f2ff 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -176,6 +176,7 @@ namespace Cxxi Assembly = string.Empty; GeneratorKind = LanguageGeneratorKind.CSharp; GenerateLibraryNamespace = true; + GenerateFunctionTemplates = false; } public bool Verbose = false; @@ -186,6 +187,7 @@ namespace Cxxi public bool IgnoreErrors = false; public bool OutputInteropIncludes = true; public bool GenerateLibraryNamespace; + public bool GenerateFunctionTemplates; public string OutputNamespace; public string OutputDir; public string LibraryName; diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index a7f800ba..6524a4d6 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -244,11 +244,50 @@ namespace Cxxi.Generators.CLI GenerateClassEvents(@class); GenerateClassMethods(@class); + + if (Options.GenerateFunctionTemplates) + GenerateClassGenericMethods(@class); + GenerateClassVariables(@class); WriteLine("};"); } + public void GenerateClassGenericMethods(Class @class) + { + var printer = TypePrinter as CLITypePrinter; + var oldCtx = printer.Context; + + PushIndent(); + foreach (var template in @class.FunctionTemplates) + { + if (template.Ignore) continue; + + var function = template.TemplatedFunction; + + var typeNames = template.Parameters.Select( + param => "typename " + param.Name).ToList(); + + var typeCtx = new TypePrinterContext() + { + Kind = TypePrinterContextKind.Template, + Declaration = template + }; + + printer.Context = typeCtx; + + var typePrinter = new CLITypePrinter(Driver, typeCtx); + var retType = function.ReturnType.Visit(typePrinter); + + WriteLine("generic<{0}>", string.Join(", ", typeNames)); + WriteLine("{0} {1}({2});", retType, SafeIdentifier(function.Name), + GenerateParametersList(function.Parameters)); + } + PopIndent(); + + printer.Context = oldCtx; + } + public void GenerateClassConstructors(Class @class, string nativeType) { PushIndent(); diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 43663160..948c6204 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -156,6 +156,18 @@ namespace Cxxi.Generators.CLI GenerateEvent(@event, @class); } + if (Options.GenerateFunctionTemplates) + { + foreach (var template in @class.FunctionTemplates) + { + if (template.Ignore) + continue; + + GenerateDeclarationCommon(template); + GenerateFunctionTemplate(template, @class); + } + } + foreach (var variable in @class.Variables) { if (variable.Ignore) @@ -166,6 +178,42 @@ namespace Cxxi.Generators.CLI } } + private void GenerateFunctionTemplate(FunctionTemplate template, Class @class) + { + var printer = TypePrinter as CLITypePrinter; + var oldCtx = printer.Context; + + var function = template.TemplatedFunction; + + var typeNames = template.Parameters.Select( + param => "typename " + param.Name).ToList(); + + var typeCtx = new TypePrinterContext() + { + Kind = TypePrinterContextKind.Template, + Declaration = template + }; + + printer.Context = typeCtx; + + var typePrinter = new CLITypePrinter(Driver, typeCtx); + var retType = function.ReturnType.Visit(typePrinter); + + WriteLine("generic<{0}>", string.Join(", ", typeNames)); + WriteLine("{0} {1}::{2}({3})", retType, QualifiedIdentifier(@class), + SafeIdentifier(function.Name), + GenerateParametersList(function.Parameters)); + + WriteStartBraceIndent(); + + GenerateFunctionCall(function, @class); + + WriteCloseBraceIndent(); + NewLine(); + + printer.Context = oldCtx; + } + private void GenerateFieldProperty(Field field) { var @class = field.Class;