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);