From fddd1b9a8dc1131b89f77e321a5e5342e991e035 Mon Sep 17 00:00:00 2001 From: Corentin Le Molgat Date: Mon, 28 Jan 2019 14:27:28 +0100 Subject: [PATCH] dotnet: Add delegate support for display_callback - Add Xunit Tests to check DisplayCallback delegates are working. --- examples/tests/ConstraintSolverTests.cs | 267 ++++++++++++++++++ examples/tests/ConstraintSolverTests.csproj | 24 ++ examples/tests/testcp.cs | 157 ---------- makefiles/Makefile.dotnet.mk | 5 + .../csharp/constraint_solver.i | 51 ++-- 5 files changed, 312 insertions(+), 192 deletions(-) create mode 100644 examples/tests/ConstraintSolverTests.cs create mode 100644 examples/tests/ConstraintSolverTests.csproj diff --git a/examples/tests/ConstraintSolverTests.cs b/examples/tests/ConstraintSolverTests.cs new file mode 100644 index 0000000000..88ea788b31 --- /dev/null +++ b/examples/tests/ConstraintSolverTests.cs @@ -0,0 +1,267 @@ +using System; +using Xunit; +using Google.OrTools.ConstraintSolver; + +namespace Google.OrTools.Tests { + public + class ConstraintSolverTest { + [Fact] + public void Constructors() { + Solver solver = new Solver("ConstructorsTest"); + IntVar x = solver.MakeIntVar(3, 7, "x"); + Assert.Equal("x(3..7)", x.ToString()); + Constraint c1 = x == 5; + Assert.Equal("(x(3..7) == 5)", c1.ToString()); + Constraint c2 = x >= 5; + Assert.Equal("(x(3..7) >= 5)", c2.ToString()); + Constraint c3 = x > 5; + Assert.Equal("(x(3..7) >= 6)", c3.ToString()); + Constraint c4 = x <= 5; + Assert.Equal("(x(3..7) <= 5)", c4.ToString()); + Constraint c5 = x < 5; + Assert.Equal("(x(3..7) <= 4)", c5.ToString()); + Constraint c6 = x != 5; + Assert.Equal("(x(3..7) != 5)", c6.ToString()); + Constraint c7 = x == 2; + Assert.Equal("FalseConstraint()", c7.ToString()); + } + + [Fact] + public void ConstraintWithExpr() { + Solver solver = new Solver("ConstraintWithExprTest"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal("x(3..13)", x.ToString()); + IntVar y = solver.MakeIntVar(5, 17, "y"); + Assert.Equal("y(5..17)", y.ToString()); + + Constraint c1 = x == 7; + Assert.Equal("(x(3..13) == 7)", c1.ToString()); + + // arithmetic operator with value + IntExpr e2a = c1 + 1; + Assert.Equal("(Watch(0 .. 1) + 1)", e2a.ToString()); + IntExpr e2b = 1 + c1; + Assert.Equal("(Watch(0 .. 1) + 1)", e2b.ToString()); + IntExpr e2c = c1 - 1; + Assert.Equal("(Watch(0 .. 1) + -1)", e2c.ToString()); + IntExpr e2d = 1 - c1; + Assert.Equal("Not(Watch(0 .. 1))", e2d.ToString()); + IntExpr e2e = c1 * 2; + Assert.Equal("(Watch(0 .. 1) * 2)", e2e.ToString()); + IntExpr e2f = 2 * c1; + Assert.Equal("(Watch(0 .. 1) * 2)", e2f.ToString()); + IntExpr e2g = c1 / 4; + Assert.Equal("(Watch(0 .. 1) div 4)", e2g.ToString()); + + // arithmetic operator with IntVar + IntExpr e3a = c1 + y; + Assert.Equal("(Watch(0 .. 1) + y(5..17))", e3a.ToString()); + IntExpr e3b = y + c1; + Assert.Equal("(Watch(0 .. 1) + y(5..17))", e3b.ToString()); + IntExpr e3c = c1 - y; + Assert.Equal("(Watch(0 .. 1) - y(5..17))", e3c.ToString()); + IntExpr e3d = y - c1; + Assert.Equal("(y(5..17) - Watch(0 .. 1))", e3d.ToString()); + IntExpr e3e = c1 * y; + Assert.Equal("(Watch(0 .. 1) * y(5..17))", e3e.ToString()); + IntExpr e3f = y * c1; + Assert.Equal("(Watch(0 .. 1) * y(5..17))", e3f.ToString()); + + // arithmetic operator with an IntExpr + IntExpr e11a = c1 + (y == 11); + Assert.Equal("(Watch(0 .. 1) + Watch(0 .. 1))", e11a.ToString()); + IntExpr e11b = (y == 11) + c1; + Assert.Equal("(Watch(0 .. 1) + Watch(0 .. 1))", e11b.ToString()); + IntExpr e11c = c1 - (y == 11); + Assert.Equal("(Watch(0 .. 1) - Watch(0 .. 1))", e11c.ToString()); + IntExpr e11d = (y == 11) - c1; + Assert.Equal("(Watch(0 .. 1) - Watch(0 .. 1))", e11d.ToString()); + IntExpr e11e = c1 * (y == 11); + Assert.Equal("(Watch(0 .. 1) * Watch(0 .. 1))", e11e.ToString()); + IntExpr e11f = (y == 11) * c1; + Assert.Equal("(Watch(0 .. 1) * Watch(0 .. 1))", e11f.ToString()); + + // Unary operator + IntExpr e4 = -c1; + Assert.Equal("-(Watch(0 .. 1))", e4.ToString()); + IntExpr e6 = c1.Abs(); + Assert.Equal("Watch(0 .. 1)", e6.ToString()); + IntExpr e7 = c1.Square(); + Assert.Equal("IntSquare(Watch(0 .. 1))", e7.ToString()); + + // Relational operator with a value + Constraint c8a = c1 == 1; + Assert.Equal("(Watch(0 .. 1) == 1)", c8a.ToString()); + Constraint c8b = 1 == c1; + Assert.Equal("(Watch(0 .. 1) == 1)", c8b.ToString()); + Constraint c8c = c1 != 1; + Assert.Equal("(Watch(0 .. 1) != 1)", c8c.ToString()); + Constraint c8d = 1 != c1; + Assert.Equal("(Watch(0 .. 1) != 1)", c8d.ToString()); + Constraint c8e = c1 >= 1; + Assert.Equal("(Watch(0 .. 1) >= 1)", c8e.ToString()); + Constraint c8f = 1 >= c1; + Assert.Equal("TrueConstraint()", c8f.ToString()); + Constraint c8g = c1 > 1; + Assert.Equal("FalseConstraint()", c8g.ToString()); + Constraint c8h = 1 > c1; + Assert.Equal("(Watch(0 .. 1) <= 0)", c8h.ToString()); + Constraint c8i = c1 <= 1; + Assert.Equal("TrueConstraint()", c8i.ToString()); + Constraint c8j = 1 <= c1; + Assert.Equal("(Watch(0 .. 1) >= 1)", c8j.ToString()); + Constraint c8k = c1 < 1; + Assert.Equal("(Watch(0 .. 1) <= 0)", c8k.ToString()); + Constraint c8l = 1 < c1; + Assert.Equal("FalseConstraint()", c8l.ToString()); + + // Relational operator with an IntVar + Constraint c9a = c1 == y; + Assert.Equal("Watch(0 .. 1) == y(5..17)", c9a.ToString()); + Constraint c9b = y == c1; + Assert.Equal("y(5..17) == Watch(0 .. 1)", c9b.ToString()); + Constraint c9c = c1 != y; + Assert.Equal("Watch(0 .. 1) != y(5..17)", c9c.ToString()); + Constraint c9d = y != c1; + Assert.Equal("y(5..17) != Watch(0 .. 1)", c9d.ToString()); + Constraint c9e = c1 >= y; + Assert.Equal("y(5..17) <= Watch(0 .. 1)", c9e.ToString()); + Constraint c9f = y >= c1; + Assert.Equal("Watch(0 .. 1) <= y(5..17)", c9f.ToString()); + Constraint c9g = c1 > y; + Assert.Equal("y(5..17) < Watch(0 .. 1)", c9g.ToString()); + Constraint c9h = y > c1; + Assert.Equal("Watch(0 .. 1) < y(5..17)", c9h.ToString()); + Constraint c9i = c1 <= y; + Assert.Equal("Watch(0 .. 1) <= y(5..17)", c9i.ToString()); + Constraint c9j = y <= c1; + Assert.Equal("y(5..17) <= Watch(0 .. 1)", c9j.ToString()); + Constraint c9k = c1 < y; + Assert.Equal("Watch(0 .. 1) < y(5..17)", c9k.ToString()); + Constraint c9l = y < c1; + Assert.Equal("y(5..17) < Watch(0 .. 1)", c9l.ToString()); + + // relational operator with a Constraint + Constraint c2 = y == 11; + Assert.Equal("(y(5..17) == 11)", c2.ToString()); + Constraint c10a = c1 == c2; + Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", c10a.ToString()); + Constraint c10c = c1 != c2; + Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", c10c.ToString()); + Constraint c10e = c1 >= c2; + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c10e.ToString()); + Constraint c10g = c1 > c2; + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c10g.ToString()); + Constraint c10i = c1 <= c2; + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c10i.ToString()); + Constraint c10k = c1 < c2; + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c10k.ToString()); + + // relational operator with an IntExpr + Constraint c12a = c1 == (y == 11); + Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", c12a.ToString()); + Constraint c12b = (y == 11) == c1; + Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", c12b.ToString()); + Constraint c12c = c1 != (y == 11); + Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", c12c.ToString()); + Constraint c12d = (y == 11) != c1; + Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", c12d.ToString()); + Constraint c12e = c1 >= (y == 11); + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c12e.ToString()); + Constraint c12f = (y == 11) >= c1; + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c12f.ToString()); + Constraint c12g = c1 > (y == 11); + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c12g.ToString()); + Constraint c12h = (y == 11) > c1; + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c12h.ToString()); + Constraint c12i = c1 <= (y == 11); + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c12i.ToString()); + Constraint c12j = (y == 11) <= c1; + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c12j.ToString()); + Constraint c12k = c1 < (y == 11); + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c12k.ToString()); + Constraint c12l = (y == 11) < c1; + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c12l.ToString()); + } + + // TODO(mizux): Improve search log tests; currently only tests coverage. + void RunSearchLog(in SearchMonitor searchlog) { + searchlog.EnterSearch(); + searchlog.ExitSearch(); + searchlog.AcceptSolution(); + searchlog.AtSolution(); + searchlog.BeginFail(); + searchlog.NoMoreSolutions(); + searchlog.BeginInitialPropagation(); + searchlog.EndInitialPropagation(); + } + + [Fact] + public void SearchLog() { + Solver solver = new Solver("TestSearchLog"); + IntVar var = solver.MakeIntVar(1, 1, "Variable"); + OptimizeVar objective = solver.MakeMinimize(var, 1); + SearchMonitor searchlog = solver.MakeSearchLog(0); + RunSearchLog(in searchlog); + } + + [Theory][InlineData(false)][InlineData(true)] + public void SearchLogWithCallback(bool callGC) { + Solver solver = new Solver("TestSearchLog"); + IntVar var = solver.MakeIntVar(1, 1, "Variable"); + OptimizeVar objective = solver.MakeMinimize(var, 1); + int count = 0; + SearchMonitor searchlog = solver.MakeSearchLog( + 0, // branch period + () => { + count++; + return "display callback..."; + }); + if (callGC) { + GC.Collect(); + } + RunSearchLog(in searchlog); + Assert.Equal(1, count); + } + + [Theory][InlineData(false)][InlineData(true)] + public void SearchLogWithObjectiveAndCallback(bool callGC) { + Solver solver = new Solver("TestSearchLog"); + IntVar var = solver.MakeIntVar(1, 1, "Variable"); + OptimizeVar objective = solver.MakeMinimize(var, 1); + int count = 0; + SearchMonitor searchlog = solver.MakeSearchLog( + 0, // branch period + objective, // objective var to monitor + () => { + count++; + return "OptimizeVar display callback"; + }); + if (callGC) { + GC.Collect(); + } + RunSearchLog(in searchlog); + Assert.Equal(1, count); + } + + [Theory][InlineData(false)][InlineData(true)] + public void SearchLogWithIntVarAndCallback(bool callGC) { + Solver solver = new Solver("TestSearchLog"); + IntVar var = solver.MakeIntVar(1, 1, "Variable"); + OptimizeVar objective = solver.MakeMinimize(var, 1); + int count = 0; + SearchMonitor searchlog = solver.MakeSearchLog( + 0, // branch period + var, // objective var to monitor + () => { + count++; + return "IntVar display callback"; + }); + if (callGC) { + GC.Collect(); + } + RunSearchLog(in searchlog); + Assert.Equal(1, count); + } + } +} // namespace Google.OrTools.Tests diff --git a/examples/tests/ConstraintSolverTests.csproj b/examples/tests/ConstraintSolverTests.csproj new file mode 100644 index 0000000000..1092027f7e --- /dev/null +++ b/examples/tests/ConstraintSolverTests.csproj @@ -0,0 +1,24 @@ + + + Exe + 7.2 + netcoreapp2.1 + false + Google.OrTools.CpSolverTests + + false + ../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json + + + + full + + + + + + + + + + diff --git a/examples/tests/testcp.cs b/examples/tests/testcp.cs index bbe49de20c..53936d53d4 100644 --- a/examples/tests/testcp.cs +++ b/examples/tests/testcp.cs @@ -51,163 +51,6 @@ public class CsTestCpOperator } } - static void ConstructorsTest() - { - Console.WriteLine("TestConstructors"); - Solver solver = new Solver("test"); - IntVar x = solver.MakeIntVar(0, 10, "x"); - Constraint c1 = x == 2; - Console.WriteLine(c1.ToString()); - Constraint c2 = x >= 2; - Console.WriteLine(c2.ToString()); - Constraint c3 = x > 2; - Console.WriteLine(c3.ToString()); - Constraint c4 = x <= 2; - Console.WriteLine(c4.ToString()); - Constraint c5 = x < 2; - Console.WriteLine(c5.ToString()); - Constraint c6 = x != 2; - Console.WriteLine(c6.ToString()); - } - - static void ConstraintWithExprTest() - { - Console.WriteLine("TestConstraintWithExpr"); - Solver solver = new Solver("test"); - IntVar x = solver.MakeIntVar(0, 10, "x"); - IntVar y = solver.MakeIntVar(0, 10, "y"); - Constraint c1 = x == 2; - Constraint c2 = y == 3; - IntExpr e2a = c1 + 1; - Console.WriteLine(e2a.ToString()); - IntExpr e2b = 1 + c1; - Console.WriteLine(e2b.ToString()); - IntExpr e2c = c1 - 1; - Console.WriteLine(e2c.ToString()); - IntExpr e2d = 1 - c1; - Console.WriteLine(e2d.ToString()); - IntExpr e2e = c1 * 2; - Console.WriteLine(e2e.ToString()); - IntExpr e2f = 2 * c1; - Console.WriteLine(e2f.ToString()); - IntExpr e3a = c1 + y; - Console.WriteLine(e3a.ToString()); - IntExpr e3b = y + c1; - Console.WriteLine(e3b.ToString()); - IntExpr e3c = c1 - y; - Console.WriteLine(e3c.ToString()); - IntExpr e3d = y - c1; - Console.WriteLine(e3d.ToString()); - IntExpr e3e = c1 * y; - Console.WriteLine(e3e.ToString()); - IntExpr e3f = y * c1; - Console.WriteLine(e3f.ToString()); - IntExpr e4 = -c1; - Console.WriteLine(e4.ToString()); - IntExpr e5 = c1 / 4; - Console.WriteLine(e5.ToString()); - IntExpr e6 = c1.Abs(); - Console.WriteLine(e6.ToString()); - IntExpr e7 = c1.Square(); - Console.WriteLine(e7.ToString()); - Constraint c8a = c1 == 1; - Console.WriteLine(c8a.ToString()); - Constraint c8b = 1 == c1; - Console.WriteLine(c8b.ToString()); - Constraint c8c = c1 != 1; - Console.WriteLine(c8c.ToString()); - Constraint c8d = 1 != c1; - Console.WriteLine(c8d.ToString()); - Constraint c8e = c1 >= 1; - Console.WriteLine(c8e.ToString()); - Constraint c8f = 1 >= c1; - Console.WriteLine(c8f.ToString()); - Constraint c8g = c1 > 1; - Console.WriteLine(c8g.ToString()); - Constraint c8h = 1 > c1; - Console.WriteLine(c8h.ToString()); - Constraint c8i = c1 <= 1; - Console.WriteLine(c8i.ToString()); - Constraint c8j = 1 <= c1; - Console.WriteLine(c8j.ToString()); - Constraint c8k = c1 < 1; - Console.WriteLine(c8k.ToString()); - Constraint c8l = 1 < c1; - Console.WriteLine(c8l.ToString()); - Constraint c9a = c1 == y; - Console.WriteLine(c9a.ToString()); - Constraint c9b = y == c1; - Console.WriteLine(c9b.ToString()); - Constraint c9c = c1 != y; - Console.WriteLine(c9c.ToString()); - Constraint c9d = y != c1; - Console.WriteLine(c9d.ToString()); - Constraint c9e = c1 >= y; - Console.WriteLine(c9e.ToString()); - Constraint c9f = y >= c1; - Console.WriteLine(c9f.ToString()); - Constraint c9g = c1 > y; - Console.WriteLine(c9g.ToString()); - Constraint c9h = y > c1; - Console.WriteLine(c9h.ToString()); - Constraint c9i = c1 <= y; - Console.WriteLine(c9i.ToString()); - Constraint c9j = y <= c1; - Console.WriteLine(c9j.ToString()); - Constraint c9k = c1 < y; - Console.WriteLine(c9k.ToString()); - Constraint c9l = y < c1; - Console.WriteLine(c9l.ToString()); - Constraint c10a = c1 == c2; - Console.WriteLine(c10a.ToString()); - Constraint c10c = c1 != c2; - Console.WriteLine(c10c.ToString()); - Constraint c10e = c1 >= c2; - Console.WriteLine(c10e.ToString()); - Constraint c10g = c1 > c2; - Console.WriteLine(c10g.ToString()); - Constraint c10i = c1 <= c2; - Console.WriteLine(c10i.ToString()); - Constraint c10k = c1 < c2; - Console.WriteLine(c10k.ToString()); - IntExpr e11a = c1 + (y == 2); - Console.WriteLine(e11a.ToString()); - IntExpr e11b = (y == 2) + c1; - Console.WriteLine(e11b.ToString()); - IntExpr e11c = c1 - (y == 2); - Console.WriteLine(e11c.ToString()); - IntExpr e11d = (y == 2) - c1; - Console.WriteLine(e11d.ToString()); - IntExpr e11e = c1 * (y == 2); - Console.WriteLine(e11e.ToString()); - IntExpr e11f = (y == 2) * c1; - Console.WriteLine(e11f.ToString()); - Constraint c12a = c1 == (y == 2); - Console.WriteLine(c12a.ToString()); - Constraint c12b = (y == 2) == c1; - Console.WriteLine(c12b.ToString()); - Constraint c12c = c1 != (y == 2); - Console.WriteLine(c12c.ToString()); - Constraint c12d = (y == 2) != c1; - Console.WriteLine(c12d.ToString()); - Constraint c12e = c1 >= (y == 2); - Console.WriteLine(c12e.ToString()); - Constraint c12f = (y == 2) >= c1; - Console.WriteLine(c12f.ToString()); - Constraint c12g = c1 > (y == 2); - Console.WriteLine(c12g.ToString()); - Constraint c12h = (y == 2) > c1; - Console.WriteLine(c12h.ToString()); - Constraint c12i = c1 <= (y == 2); - Console.WriteLine(c12i.ToString()); - Constraint c12j = (y == 2) <= c1; - Console.WriteLine(c12j.ToString()); - Constraint c12k = c1 < (y == 2); - Console.WriteLine(c12k.ToString()); - Constraint c12l = (y == 2) < c1; - Console.WriteLine(c12l.ToString()); - } - static void WrappedConstraintWithExprTest() { Console.WriteLine("TestWrappedConstraintWithExpr"); diff --git a/makefiles/Makefile.dotnet.mk b/makefiles/Makefile.dotnet.mk index 3c8170faa6..7e6f3c00b8 100644 --- a/makefiles/Makefile.dotnet.mk +++ b/makefiles/Makefile.dotnet.mk @@ -424,6 +424,10 @@ build: $(SOURCE) $(SOURCE)proj $(DOTNET_ORTOOLS_NUPKG) .PHONY: run # Run a .Net C# program. run: build "$(DOTNET_BIN)" run --no-build --project $(SOURCE_PATH)proj -- $(ARGS) + +.PHONY: run_test # Run a .Net C# program. +run_test: build + "$(DOTNET_BIN)" test --no-build $(SOURCE_PATH)proj -- $(ARGS) endif # .Net F# @@ -573,6 +577,7 @@ check_dotnet_pimpl: \ .PHONY: test_dotnet_tests # Build and Run all .Net Tests (located in examples/test) test_dotnet_tests: + $(MAKE) run_test SOURCE=examples/tests/ConstraintSolverTests.cs $(MAKE) run SOURCE=examples/tests/issue18.cs $(MAKE) run SOURCE=examples/tests/issue22.cs $(MAKE) run SOURCE=examples/tests/issue33.cs diff --git a/ortools/constraint_solver/csharp/constraint_solver.i b/ortools/constraint_solver/csharp/constraint_solver.i index 3c6160dd3e..1244f69189 100644 --- a/ortools/constraint_solver/csharp/constraint_solver.i +++ b/ortools/constraint_solver/csharp/constraint_solver.i @@ -356,18 +356,6 @@ namespace operations_research { %ignore Solver::MakeFixedDurationIntervalVarArray; // Take care of API with function. SWIG doesn't wrap std::function<> properly, // so we write our custom wrappers for all methods involving std::function<>. -%ignore Solver::MakeSearchLog( - int branch_period, - std::function display_callback); -%ignore Solver::MakeSearchLog( - int branch_period, - IntVar* var, - std::function display_callback); -%ignore Solver::MakeSearchLog( - int branch_period, - OptimizeVar* const opt_var, - std::function display_callback); - %ignore Solver::MakeActionDemon; %ignore Solver::MakeCustomLimit(std::function limiter); @@ -388,6 +376,8 @@ namespace operations_research { %typemap(csimports) Solver %{ using System.Collections.Generic; // List<> + public delegate string DisplayCallback(); + public delegate long IndexEvaluator1(long u); public delegate long IndexEvaluator2(long u, long v); public delegate long IndexEvaluator3(long u, long v, long w); @@ -442,6 +432,9 @@ namespace operations_research { // ... // ...PINVOKE.Foo_f_SWIG(..., StoreIndexEvaluator1(arg1), ...); // } +%typemap(cstype, out="IntPtr") Solver::DisplayCallback "DisplayCallback" +%typemap(csin) Solver::DisplayCallback "$csinput" + %typemap(cstype, out="IntPtr") Solver::IndexEvaluator1 "IndexEvaluator1" %typemap(csin) Solver::IndexEvaluator1 "StoreIndexEvaluator1($csinput)" %typemap(cstype, out="IntPtr") Solver::IndexEvaluator2 "IndexEvaluator2" @@ -454,6 +447,8 @@ namespace operations_research { %typemap(cstype, out="IntPtr") Solver::ObjectiveWatcher "ObjectiveWatcher" %typemap(csin) Solver::ObjectiveWatcher "StoreObjectiveWatcher($csinput)" // Type in the prototype of PINVOKE function. +%typemap(imtype, out="IntPtr") Solver::DisplayCallback "DisplayCallback" + %typemap(imtype, out="IntPtr") Solver::IndexEvaluator1 "IndexEvaluator1" %typemap(imtype, out="IntPtr") Solver::IndexEvaluator2 "IndexEvaluator2" %typemap(imtype, out="IntPtr") Solver::IndexEvaluator3 "IndexEvaluator3" @@ -463,6 +458,8 @@ namespace operations_research { // Type use in module_csharp_wrap.h function declaration. // since SWIG generate code as: `ctype argX` we can't use a C function pointer type. +%typemap(ctype) Solver::DisplayCallback "void*" // "char * (*)()" + %typemap(ctype) Solver::IndexEvaluator1 "void*" // "int64 (*)(int64)" %typemap(ctype) Solver::IndexEvaluator2 "void*" // "int64 (*)(int64, int64)" %typemap(ctype) Solver::IndexEvaluator3 "void*" // "int64 (*)(int64, int64, int64)" @@ -471,6 +468,13 @@ namespace operations_research { %typemap(ctype) Solver::ObjectiveWatcher "void*" // "void (*)(int64)" // Convert in module_csharp_wrap.cc input argument (delegate marshaled in C function pointer) to original std::function<...> +%typemap(in) Solver::DisplayCallback %{ + $1 = [$input]() -> std::string { + std::string result; + return result.assign((*(char* (*)())$input)()); + }; +%} + %typemap(in) Solver::IndexEvaluator1 %{ $1 = [$input](int64 u) -> int64 { return (*(int64 (*)(int64))$input)(u); @@ -501,29 +505,6 @@ namespace operations_research { // return $self->ConcatenateOperators(ops, [evaluator](int i, int64 j) { // return evaluator->Run(i, j); }); //} - //SearchMonitor* MakeSearchLog( - // int branch_count, - // OptimizeVar* const objective, - // swig_util::VoidToString* display_callback) { - // return $self->MakeSearchLog(branch_count, objective, [display_callback]() { - // return display_callback->Run(); - // }); - //} - //SearchMonitor* MakeSearchLog( - // int branch_count, - // IntVar* const obj_var, - // swig_util::VoidToString* display_callback) { - // return $self->MakeSearchLog(branch_count, obj_var, [display_callback]() { - // return display_callback->Run(); - // }); - //} - //SearchMonitor* MakeSearchLog( - // int branch_count, - // swig_util::VoidToString* display_callback) { - // return $self->MakeSearchLog(branch_count, [display_callback]() { - // return display_callback->Run(); - // }); - //} //SearchLimit* MakeCustomLimit(swig_util::VoidToBoolean* limiter) { // return $self->MakeCustomLimit([limiter]() { return limiter->Run(); }); //}