From e139a3651157a42e0086b15ce9df5dcba48cf4b2 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 20 Aug 2022 15:40:53 +0100 Subject: [PATCH] SWIGTYPE && input typemaps now assume object has been moved Replicated Java implementation. Fully implemented for: - C# - D - Guile - Javascript (UTL) - Lua - MzScheme - Octave (UTL) - Perl (UTL) - PHP - Python (UTL) - Ruby (UTL) - Tcl (UTL) PHP std::auto_ptr std::unique_ptr minor tweaks and testcase corrections --- ...cpp11_rvalue_reference_move_input_runme.cs | 66 ++++++++++++++ .../test-suite/csharp/li_std_wstring_runme.cs | 2 +- ...pp11_rvalue_reference_move_input_runme.1.d | 66 ++++++++++++++ ...pp11_rvalue_reference_move_input_runme.2.d | 67 ++++++++++++++ ...pp11_rvalue_reference_move_input_runme.scm | 3 + ...p11_rvalue_reference_move_input_runme.java | 1 + ...cpp11_rvalue_reference_move_input_runme.js | 67 ++++++++++++++ ...pp11_rvalue_reference_move_input_runme.lua | 56 ++++++++++++ ...pp11_rvalue_reference_move_input_runme.scm | 54 ++++++++++++ .../cpp11_rvalue_reference_move_input_runme.m | 64 ++++++++++++++ ...cpp11_rvalue_reference_move_input_runme.pl | 56 ++++++++++++ ...pp11_rvalue_reference_move_input_runme.php | 64 ++++++++++++++ .../php/cpp11_std_unique_ptr_runme.php | 11 ++- .../test-suite/php/li_std_auto_ptr_runme.php | 11 ++- Examples/test-suite/php/tests.php | 5 ++ ...cpp11_rvalue_reference_move_input_runme.py | 52 +++++++++++ ...cpp11_rvalue_reference_move_input_runme.rb | 87 +++++++++++++++++++ .../cpp11_rvalue_reference_move_input.scm | 46 ++++++++++ ...pp11_rvalue_reference_move_input_runme.tcl | 62 +++++++++++++ Lib/csharp/csharp.swg | 12 +-- Lib/d/dswigtype.swg | 11 +-- Lib/guile/typemaps.i | 30 +++++-- Lib/java/java.swg | 4 +- Lib/lua/luatypemaps.swg | 14 ++- Lib/mzscheme/std_auto_ptr.i | 3 - Lib/mzscheme/std_unique_ptr.i | 3 - Lib/mzscheme/typemaps.i | 20 ++++- Lib/php/php.swg | 21 ++++- Lib/php/std_auto_ptr.i | 4 +- Lib/php/std_unique_ptr.i | 4 +- Lib/typemaps/swigtype.swg | 11 ++- 31 files changed, 931 insertions(+), 46 deletions(-) create mode 100644 Examples/test-suite/csharp/cpp11_rvalue_reference_move_input_runme.cs create mode 100644 Examples/test-suite/d/cpp11_rvalue_reference_move_input_runme.1.d create mode 100644 Examples/test-suite/d/cpp11_rvalue_reference_move_input_runme.2.d create mode 100644 Examples/test-suite/guile/cpp11_rvalue_reference_move_input_runme.scm create mode 100644 Examples/test-suite/javascript/cpp11_rvalue_reference_move_input_runme.js create mode 100644 Examples/test-suite/lua/cpp11_rvalue_reference_move_input_runme.lua create mode 100644 Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_input_runme.scm create mode 100644 Examples/test-suite/octave/cpp11_rvalue_reference_move_input_runme.m create mode 100644 Examples/test-suite/perl5/cpp11_rvalue_reference_move_input_runme.pl create mode 100644 Examples/test-suite/php/cpp11_rvalue_reference_move_input_runme.php create mode 100644 Examples/test-suite/python/cpp11_rvalue_reference_move_input_runme.py create mode 100644 Examples/test-suite/ruby/cpp11_rvalue_reference_move_input_runme.rb create mode 100644 Examples/test-suite/schemerunme/cpp11_rvalue_reference_move_input.scm create mode 100644 Examples/test-suite/tcl/cpp11_rvalue_reference_move_input_runme.tcl diff --git a/Examples/test-suite/csharp/cpp11_rvalue_reference_move_input_runme.cs b/Examples/test-suite/csharp/cpp11_rvalue_reference_move_input_runme.cs new file mode 100644 index 000000000..fb7024065 --- /dev/null +++ b/Examples/test-suite/csharp/cpp11_rvalue_reference_move_input_runme.cs @@ -0,0 +1,66 @@ +using System; +using cpp11_rvalue_reference_move_inputNamespace; + +public class cpp11_rvalue_reference_move_input_runme { + public static void Main() { + { + // Function containing rvalue reference parameter + Counter.reset_counts(); + MovableCopyable mo = new MovableCopyable(222); + Counter.check_counts(1, 0, 0, 0, 0, 0); + MovableCopyable.movein(mo); + Counter.check_counts(1, 0, 0, 1, 0, 2); + if (!MovableCopyable.is_nullptr(mo)) + throw new ApplicationException("is_nullptr failed"); + mo.Dispose(); + Counter.check_counts(1, 0, 0, 1, 0, 2); + } + + { + // Move constructor test + Counter.reset_counts(); + MovableCopyable mo = new MovableCopyable(222); + Counter.check_counts(1, 0, 0, 0, 0, 0); + MovableCopyable mo_moved = new MovableCopyable(mo); + Counter.check_counts(1, 0, 0, 1, 0, 1); + if (!MovableCopyable.is_nullptr(mo)) + throw new ApplicationException("is_nullptr failed"); + mo.Dispose(); + Counter.check_counts(1, 0, 0, 1, 0, 1); + mo_moved.Dispose(); + Counter.check_counts(1, 0, 0, 1, 0, 2); + } + + { + // Move assignment operator test + Counter.reset_counts(); + MovableCopyable mo111 = new MovableCopyable(111); + MovableCopyable mo222 = new MovableCopyable(222); + Counter.check_counts(2, 0, 0, 0, 0, 0); + mo111.MoveAssign(mo222); + Counter.check_counts(2, 0, 0, 0, 1, 1); + if (!MovableCopyable.is_nullptr(mo222)) + throw new ApplicationException("is_nullptr failed"); + mo222.Dispose(); + Counter.check_counts(2, 0, 0, 0, 1, 1); + mo111.Dispose(); + Counter.check_counts(2, 0, 0, 0, 1, 2); + } + + { + // null check + Counter.reset_counts(); + bool exception_thrown = false; + try { + MovableCopyable.movein(null); + } catch (ArgumentNullException e) { + if (!e.Message.Contains("MovableCopyable && is null")) + throw new ApplicationException("incorrect exception message:" + e); + exception_thrown = true; + } + if (!exception_thrown) + throw new ApplicationException("Should have thrown null error"); + Counter.check_counts(0, 0, 0, 0, 0, 0); + } + } +} diff --git a/Examples/test-suite/csharp/li_std_wstring_runme.cs b/Examples/test-suite/csharp/li_std_wstring_runme.cs index d2be3d1ff..97dfedbf0 100644 --- a/Examples/test-suite/csharp/li_std_wstring_runme.cs +++ b/Examples/test-suite/csharp/li_std_wstring_runme.cs @@ -66,7 +66,7 @@ public class runme li_std_wstring.test_reference(null); throw new Exception("NULL check failed"); } catch (ArgumentNullException e) { - if (!e.Message.Contains("type is null")) + if (!e.Message.Contains("is null")) throw new Exception("Missing text " + e); } try { diff --git a/Examples/test-suite/d/cpp11_rvalue_reference_move_input_runme.1.d b/Examples/test-suite/d/cpp11_rvalue_reference_move_input_runme.1.d new file mode 100644 index 000000000..e6d23868c --- /dev/null +++ b/Examples/test-suite/d/cpp11_rvalue_reference_move_input_runme.1.d @@ -0,0 +1,66 @@ +module cpp11_rvalue_reference_move_input_runme; + +import cpp11_rvalue_reference_move_input.Counter; +import cpp11_rvalue_reference_move_input.MovableCopyable; + +void main() { + { + // Function containing rvalue reference parameter + Counter.reset_counts(); + scope MovableCopyable mo = new MovableCopyable(222); + Counter.check_counts(1, 0, 0, 0, 0, 0); + MovableCopyable.movein(mo); + Counter.check_counts(1, 0, 0, 1, 0, 2); + if (!MovableCopyable.is_nullptr(mo)) + throw new Exception("is_nullptr failed"); + mo.dispose(); + Counter.check_counts(1, 0, 0, 1, 0, 2); + } + + { + // Move constructor test + Counter.reset_counts(); + scope MovableCopyable mo = new MovableCopyable(222); + Counter.check_counts(1, 0, 0, 0, 0, 0); + MovableCopyable mo_moved = new MovableCopyable(mo); + Counter.check_counts(1, 0, 0, 1, 0, 1); + if (!MovableCopyable.is_nullptr(mo)) + throw new Exception("is_nullptr failed"); + mo.dispose(); + Counter.check_counts(1, 0, 0, 1, 0, 1); + mo_moved.dispose(); + Counter.check_counts(1, 0, 0, 1, 0, 2); + } + + { + // Move assignment operator test + Counter.reset_counts(); + scope MovableCopyable mo111 = new MovableCopyable(111); + scope MovableCopyable mo222 = new MovableCopyable(222); + Counter.check_counts(2, 0, 0, 0, 0, 0); + mo111.MoveAssign(mo222); + Counter.check_counts(2, 0, 0, 0, 1, 1); + if (!MovableCopyable.is_nullptr(mo222)) + throw new Exception("is_nullptr failed"); + mo222.dispose(); + Counter.check_counts(2, 0, 0, 0, 1, 1); + mo111.dispose(); + Counter.check_counts(2, 0, 0, 0, 1, 2); + } + + { + // null check + Counter.reset_counts(); + bool exception_thrown = false; + try { + MovableCopyable.movein(null); + } catch (Exception e) { + if (!canFind(e.msg, "MovableCopyable && is null")) + throw new Exception("incorrect exception message:" ~ e.msg); + exception_thrown = true; + } + if (!exception_thrown) + throw new Exception("Should have thrown null error"); + Counter.check_counts(0, 0, 0, 0, 0, 0); + } +} diff --git a/Examples/test-suite/d/cpp11_rvalue_reference_move_input_runme.2.d b/Examples/test-suite/d/cpp11_rvalue_reference_move_input_runme.2.d new file mode 100644 index 000000000..5b3e6001a --- /dev/null +++ b/Examples/test-suite/d/cpp11_rvalue_reference_move_input_runme.2.d @@ -0,0 +1,67 @@ +module cpp11_rvalue_reference_move_input_runme; + +import cpp11_rvalue_reference_move_input.Counter; +import cpp11_rvalue_reference_move_input.MovableCopyable; +import std.algorithm; + +void main() { + { + // Function containing rvalue reference parameter + Counter.reset_counts(); + scope MovableCopyable mo = new MovableCopyable(222); + Counter.check_counts(1, 0, 0, 0, 0, 0); + MovableCopyable.movein(mo); + Counter.check_counts(1, 0, 0, 1, 0, 2); + if (!MovableCopyable.is_nullptr(mo)) + throw new Exception("is_nullptr failed"); + mo.dispose(); + Counter.check_counts(1, 0, 0, 1, 0, 2); + } + + { + // Move constructor test + Counter.reset_counts(); + scope MovableCopyable mo = new MovableCopyable(222); + Counter.check_counts(1, 0, 0, 0, 0, 0); + MovableCopyable mo_moved = new MovableCopyable(mo); + Counter.check_counts(1, 0, 0, 1, 0, 1); + if (!MovableCopyable.is_nullptr(mo)) + throw new Exception("is_nullptr failed"); + mo.dispose(); + Counter.check_counts(1, 0, 0, 1, 0, 1); + mo_moved.dispose(); + Counter.check_counts(1, 0, 0, 1, 0, 2); + } + + { + // Move assignment operator test + Counter.reset_counts(); + scope MovableCopyable mo111 = new MovableCopyable(111); + scope MovableCopyable mo222 = new MovableCopyable(222); + Counter.check_counts(2, 0, 0, 0, 0, 0); + mo111.MoveAssign(mo222); + Counter.check_counts(2, 0, 0, 0, 1, 1); + if (!MovableCopyable.is_nullptr(mo222)) + throw new Exception("is_nullptr failed"); + mo222.dispose(); + Counter.check_counts(2, 0, 0, 0, 1, 1); + mo111.dispose(); + Counter.check_counts(2, 0, 0, 0, 1, 2); + } + + { + // null check + Counter.reset_counts(); + bool exception_thrown = false; + try { + MovableCopyable.movein(null); + } catch (Exception e) { + if (!canFind(e.msg, "MovableCopyable && is null")) + throw new Exception("incorrect exception message:" ~ e.msg); + exception_thrown = true; + } + if (!exception_thrown) + throw new Exception("Should have thrown null error"); + Counter.check_counts(0, 0, 0, 0, 0, 0); + } +} diff --git a/Examples/test-suite/guile/cpp11_rvalue_reference_move_input_runme.scm b/Examples/test-suite/guile/cpp11_rvalue_reference_move_input_runme.scm new file mode 100644 index 000000000..6beecf3e8 --- /dev/null +++ b/Examples/test-suite/guile/cpp11_rvalue_reference_move_input_runme.scm @@ -0,0 +1,3 @@ +(dynamic-call "scm_init_cpp11_rvalue_reference_move_input_module" (dynamic-link "./libcpp11_rvalue_reference_move_input")) +(load "testsuite.scm") +(load "../schemerunme/cpp11_rvalue_reference_move_input.scm") diff --git a/Examples/test-suite/java/cpp11_rvalue_reference_move_input_runme.java b/Examples/test-suite/java/cpp11_rvalue_reference_move_input_runme.java index 121c93075..2115bd7ca 100644 --- a/Examples/test-suite/java/cpp11_rvalue_reference_move_input_runme.java +++ b/Examples/test-suite/java/cpp11_rvalue_reference_move_input_runme.java @@ -15,6 +15,7 @@ public class cpp11_rvalue_reference_move_input_runme { public static void main(String argv[]) { { + // Function containing rvalue reference parameter Counter.reset_counts(); MovableCopyable mo = new MovableCopyable(222); Counter.check_counts(1, 0, 0, 0, 0, 0); diff --git a/Examples/test-suite/javascript/cpp11_rvalue_reference_move_input_runme.js b/Examples/test-suite/javascript/cpp11_rvalue_reference_move_input_runme.js new file mode 100644 index 000000000..ba432d466 --- /dev/null +++ b/Examples/test-suite/javascript/cpp11_rvalue_reference_move_input_runme.js @@ -0,0 +1,67 @@ +var cpp11_rvalue_reference_move_input = require("cpp11_rvalue_reference_move_input"); + +{ + // Function containing rvalue reference parameter + cpp11_rvalue_reference_move_input.Counter.reset_counts(); + mo = new cpp11_rvalue_reference_move_input.MovableCopyable(222); + cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 0, 0, 0); + cpp11_rvalue_reference_move_input.MovableCopyable.movein(mo); + cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2); + if (!cpp11_rvalue_reference_move_input.MovableCopyable.is_nullptr(mo)) + throw new Error("is_nullptr failed"); + delete mo; + cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2); +} + +{ + // Move constructor test + cpp11_rvalue_reference_move_input.Counter.reset_counts(); + mo = new cpp11_rvalue_reference_move_input.MovableCopyable(222); + cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 0, 0, 0); + mo_moved = new cpp11_rvalue_reference_move_input.MovableCopyable(mo); + cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 1); + if (!cpp11_rvalue_reference_move_input.MovableCopyable.is_nullptr(mo)) + throw new Error("is_nullptr failed"); + delete mo; + cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 1); + // delete mo_moved; + // cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2); + // Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete + cpp11_rvalue_reference_move_input.MovableCopyable.movein(mo_moved); + cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 2, 0, 3); +} + +{ + // Move assignment operator test + cpp11_rvalue_reference_move_input.Counter.reset_counts(); + mo111 = new cpp11_rvalue_reference_move_input.MovableCopyable(111); + mo222 = new cpp11_rvalue_reference_move_input.MovableCopyable(222); + cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 0, 0); + mo111.MoveAssign(mo222); + cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 1); + if (!cpp11_rvalue_reference_move_input.MovableCopyable.is_nullptr(mo222)) + throw new Error("is_nullptr failed"); + delete mo222; + cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 1); + // delete mo111; + // cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 2); + // Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete + cpp11_rvalue_reference_move_input.MovableCopyable.movein(mo111); + cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 1, 1, 3); +} + +{ + // null check + cpp11_rvalue_reference_move_input.Counter.reset_counts(); + exception_thrown = false; + try { + cpp11_rvalue_reference_move_input.MovableCopyable.movein(null); + } catch (e) { + if (!e.message.includes("invalid null reference")) + throw new Error("incorrect exception message " + e.message); + exception_thrown = true; + } + if (!exception_thrown) + throw new Error("Should have thrown null error"); + cpp11_rvalue_reference_move_input.Counter.check_counts(0, 0, 0, 0, 0, 0); +} diff --git a/Examples/test-suite/lua/cpp11_rvalue_reference_move_input_runme.lua b/Examples/test-suite/lua/cpp11_rvalue_reference_move_input_runme.lua new file mode 100644 index 000000000..1dfeba7df --- /dev/null +++ b/Examples/test-suite/lua/cpp11_rvalue_reference_move_input_runme.lua @@ -0,0 +1,56 @@ +require("import") -- the import fn +import("cpp11_rvalue_reference_move_input") -- import code + +-- catch "undefined" global variables +local env = _ENV -- Lua 5.2 +if not env then env = getfenv () end -- Lua 5.1 +setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end}) + +-- Function containing rvalue reference parameter +cpp11_rvalue_reference_move_input.Counter.reset_counts() +mo = cpp11_rvalue_reference_move_input.MovableCopyable(222) +cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 0, 0, 0) +cpp11_rvalue_reference_move_input.MovableCopyable.movein(mo) +cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2) +if not (cpp11_rvalue_reference_move_input.MovableCopyable_is_nullptr(mo)) then + error("is_nullptr failed") +end +mo = nil +cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2) + +-- Move constructor test +cpp11_rvalue_reference_move_input.Counter.reset_counts() +mo = cpp11_rvalue_reference_move_input.MovableCopyable(222) +cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 0, 0, 0) +mo_moved = cpp11_rvalue_reference_move_input.MovableCopyable(mo) +cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 1) +if not (cpp11_rvalue_reference_move_input.MovableCopyable_is_nullptr(mo)) then + error("is_nullptr failed") +end +mo = nil +cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 1) +mo_moved = nil +collectgarbage() -- gc nudge needed here +cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2) + +-- Move assignment operator test +cpp11_rvalue_reference_move_input.Counter.reset_counts() +mo111 = cpp11_rvalue_reference_move_input.MovableCopyable(111) +mo222 = cpp11_rvalue_reference_move_input.MovableCopyable(222) +cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 0, 0) +mo111:MoveAssign(mo222) +cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 1) +if not (cpp11_rvalue_reference_move_input.MovableCopyable_is_nullptr(mo222)) then + error("is_nullptr failed") +end +mo222 = nil +cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 1) +mo111 = nil +collectgarbage() -- gc nudge needed here +cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 2) + +-- null check +cpp11_rvalue_reference_move_input.Counter.reset_counts() +s, msg = pcall(function() cpp11_rvalue_reference_move_input.MovableCopyable.movein(nil) end) +assert(s == false and msg:find("Error in MovableCopyable::movein (arg 1), expected 'MovableCopyable &&' got 'nil'", 1, true)) +cpp11_rvalue_reference_move_input.Counter.check_counts(0, 0, 0, 0, 0, 0) diff --git a/Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_input_runme.scm b/Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_input_runme.scm new file mode 100644 index 000000000..8e95a071b --- /dev/null +++ b/Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_input_runme.scm @@ -0,0 +1,54 @@ +(load-extension "cpp11_rvalue_reference_move_input.so") +(require (lib "defmacro.ss")) + +; Copied from ../schemerunme/cpp11_rvalue_reference_move_input.scm and modified for exceptions + +; Function containing rvalue reference parameter +(Counter-reset-counts) +(define mo (new-MovableCopyable 222)) +(Counter-check-counts 1 0 0 0 0 0) +(MovableCopyable-movein mo) +(Counter-check-counts 1 0 0 1 0 2) +(unless (MovableCopyable-is-nullptr mo) + (error "is_nullptr failed")) +(delete-MovableCopyable mo) +(Counter-check-counts 1 0 0 1 0 2) + +; Move constructor test +(Counter-reset-counts) +(define mo (new-MovableCopyable 222)) +(Counter-check-counts 1 0 0 0 0 0) +(define mo_moved (new-MovableCopyable mo)) +(Counter-check-counts 1 0 0 1 0 1) +(unless (MovableCopyable-is-nullptr mo) + (error "is_nullptr failed")) +(delete-MovableCopyable mo) +(Counter-check-counts 1 0 0 1 0 1) +(delete-MovableCopyable mo_moved) +(Counter-check-counts 1 0 0 1 0 2) + +; Move assignment operator test +(Counter-reset-counts) +(define mo111 (new-MovableCopyable 111)) +(define mo222 (new-MovableCopyable 222)) +(Counter-check-counts 2 0 0 0 0 0) +(MovableCopyable-MoveAssign mo111 mo222) +(Counter-check-counts 2 0 0 0 1 1) +(unless (MovableCopyable-is-nullptr mo222) + (error "is_nullptr failed")) +(delete-MovableCopyable mo222) +(Counter-check-counts 2 0 0 0 1 1) +(delete-MovableCopyable mo111) +(Counter-check-counts 2 0 0 0 1 2) + +; null check +(Counter-reset-counts) +(define exception_thrown "no exception thrown for kin") +(with-handlers ([exn:fail? (lambda (exn) + (set! exception_thrown (exn-message exn)))]) + (MovableCopyable-movein '())) +(unless (string=? exception_thrown "MovableCopyable-movein: swig-type-error (null reference)") + (error (format "incorrect exception message: ~a" exception_thrown))) +(Counter-check-counts 0 0 0 0 0 0) + +(exit 0) diff --git a/Examples/test-suite/octave/cpp11_rvalue_reference_move_input_runme.m b/Examples/test-suite/octave/cpp11_rvalue_reference_move_input_runme.m new file mode 100644 index 000000000..28b80d920 --- /dev/null +++ b/Examples/test-suite/octave/cpp11_rvalue_reference_move_input_runme.m @@ -0,0 +1,64 @@ +# do not dump Octave core +if exist("crash_dumps_octave_core", "builtin") + crash_dumps_octave_core(0); +endif + +cpp11_rvalue_reference_move_input + +# Function containing rvalue reference parameter +Counter.reset_counts(); +mo = MovableCopyable(222); +Counter.check_counts(1, 0, 0, 0, 0, 0); +MovableCopyable.movein(mo); +Counter.check_counts(1, 0, 0, 1, 0, 2); +if (!MovableCopyable_is_nullptr(mo)) + error("is_nullptr failed"); +endif +clear mo; +Counter.check_counts(1, 0, 0, 1, 0, 2); + +# Move constructor test +Counter.reset_counts(); +mo = MovableCopyable(222); +Counter.check_counts(1, 0, 0, 0, 0, 0); +mo_moved = MovableCopyable(mo); +Counter.check_counts(1, 0, 0, 1, 0, 1); +if (!MovableCopyable_is_nullptr(mo)) + error("is_nullptr failed"); +endif +clear mo; +Counter.check_counts(1, 0, 0, 1, 0, 1); +clear mo_moved; +Counter.check_counts(1, 0, 0, 1, 0, 2); + +# Move assignment operator test +Counter.reset_counts(); +mo111 = MovableCopyable(111); +mo222 = MovableCopyable(222); +Counter.check_counts(2, 0, 0, 0, 0, 0); +mo111.MoveAssign(mo222); +Counter.check_counts(2, 0, 0, 0, 1, 1); +if (!MovableCopyable_is_nullptr(mo222)) + error("is_nullptr failed"); +endif +clear mo222; +Counter.check_counts(2, 0, 0, 0, 1, 1); +clear mo111; +Counter.check_counts(2, 0, 0, 0, 1, 2); + +# null check +null = []; # NULL pointer +Counter.reset_counts(); +exception_thrown = false; +try + MovableCopyable.movein(null); +catch e + if (isempty(strfind(e.message, "invalid null reference"))) + error("incorrect exception message: %s", e.message) + endif + exception_thrown = true; +end_try_catch +if (!exception_thrown) + error("Should have thrown null error"); +endif +Counter.check_counts(0, 0, 0, 0, 0, 0); diff --git a/Examples/test-suite/perl5/cpp11_rvalue_reference_move_input_runme.pl b/Examples/test-suite/perl5/cpp11_rvalue_reference_move_input_runme.pl new file mode 100644 index 000000000..f4f419c87 --- /dev/null +++ b/Examples/test-suite/perl5/cpp11_rvalue_reference_move_input_runme.pl @@ -0,0 +1,56 @@ +use strict; +use warnings; +use Test::More tests => 6; +BEGIN { use_ok('cpp11_rvalue_reference_move_input') } +require_ok('cpp11_rvalue_reference_move_input'); + +{ + # Function containing rvalue reference parameter + cpp11_rvalue_reference_move_input::Counter::reset_counts(); + my $mo = new cpp11_rvalue_reference_move_input::MovableCopyable(222); + cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 0, 0, 0); + cpp11_rvalue_reference_move_input::MovableCopyable::movein($mo); + cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 1, 0, 2); + is(cpp11_rvalue_reference_move_input::MovableCopyable::is_nullptr($mo), 1, "is_nullptr check"); + undef $mo; + cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 1, 0, 2); +} + +{ + # Move constructor test + cpp11_rvalue_reference_move_input::Counter::reset_counts(); + my $mo = new cpp11_rvalue_reference_move_input::MovableCopyable(222); + cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 0, 0, 0); + my $mo_moved = new cpp11_rvalue_reference_move_input::MovableCopyable($mo); + cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 1, 0, 1); + is(cpp11_rvalue_reference_move_input::MovableCopyable::is_nullptr($mo), 1, "is_nullptr check"); + undef $mo; + cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 1, 0, 1); + undef $mo_moved; + cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 1, 0, 2); +} + +{ + # Move assignment operator test + cpp11_rvalue_reference_move_input::Counter::reset_counts(); + my $mo111 = new cpp11_rvalue_reference_move_input::MovableCopyable(111); + my $mo222 = new cpp11_rvalue_reference_move_input::MovableCopyable(222); + cpp11_rvalue_reference_move_input::Counter::check_counts(2, 0, 0, 0, 0, 0); + $mo111->MoveAssign($mo222); + cpp11_rvalue_reference_move_input::Counter::check_counts(2, 0, 0, 0, 1, 1); + is(cpp11_rvalue_reference_move_input::MovableCopyable::is_nullptr($mo222), 1, "is_nullptr check"); + undef $mo222; + cpp11_rvalue_reference_move_input::Counter::check_counts(2, 0, 0, 0, 1, 1); + undef $mo111; + cpp11_rvalue_reference_move_input::Counter::check_counts(2, 0, 0, 0, 1, 2); +} + +{ + # null check + cpp11_rvalue_reference_move_input::Counter::reset_counts(); + eval { + cpp11_rvalue_reference_move_input::MovableCopyable::movein(undef); + }; + like($@, qr/\binvalid null reference/, "Should have thrown null error"); + cpp11_rvalue_reference_move_input::Counter::check_counts(0, 0, 0, 0, 0, 0); +} diff --git a/Examples/test-suite/php/cpp11_rvalue_reference_move_input_runme.php b/Examples/test-suite/php/cpp11_rvalue_reference_move_input_runme.php new file mode 100644 index 000000000..176134682 --- /dev/null +++ b/Examples/test-suite/php/cpp11_rvalue_reference_move_input_runme.php @@ -0,0 +1,64 @@ +MoveAssign($mo222); +Counter::check_counts(2, 0, 0, 0, 1, 1); +try { + MovableCopyable::is_nullptr($mo222); + check::fail("is_nullptr check"); +} catch (TypeError $e) { +} +$mo222 = NULL; +Counter::check_counts(2, 0, 0, 0, 1, 1); +$mo111 = NULL; +Counter::check_counts(2, 0, 0, 0, 1, 2); + +# null check +Counter::reset_counts(); +$exception_thrown = false; +try { + MovableCopyable::movein(NULL); +} catch (TypeError $e) { + check::str_contains($e->getMessage(), "Invalid null reference", "incorrect exception message: {$e->getMessage()}"); + $exception_thrown = true; +} +check::equal($exception_thrown, true, "Should have thrown null error"); +Counter::check_counts(0, 0, 0, 0, 0, 0); + +check::done(); diff --git a/Examples/test-suite/php/cpp11_std_unique_ptr_runme.php b/Examples/test-suite/php/cpp11_std_unique_ptr_runme.php index b02fdaa33..2b169e748 100644 --- a/Examples/test-suite/php/cpp11_std_unique_ptr_runme.php +++ b/Examples/test-suite/php/cpp11_std_unique_ptr_runme.php @@ -40,20 +40,27 @@ try { check::fail("is_nullptr check"); } catch (TypeError $e) { } +$exception_thrown = false; try { + takeKlassUniquePtr($kin); } catch (TypeError $e) { - check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' of takeKlassUniquePtr", "Unexpected exception: {$e->getMessage()}"); + check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassUniquePtr", "Unexpected exception: {$e->getMessage()}"); + $exception_thrown = true; } +check::equal($exception_thrown, true, "double usage of takeKlassUniquePtr should have been an error"); $kin = NULL; # Should not fail, even though already deleted checkCount(0); $kin = new Klass("KlassInput"); +$exception_thrown = false; $notowned = get_not_owned_ptr($kin); try { takeKlassUniquePtr($notowned); } catch (TypeError $e) { - check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' of takeKlassUniquePtr", "Unexpected exception: {$e->getMessage()}"); + check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassUniquePtr", "Unexpected exception: {$e->getMessage()}"); + $exception_thrown = true; } +check::equal($exception_thrown, true, "double usage of takeKlassUniquePtr should have been an error"); checkCount(1); $kin = NULL; checkCount(0); diff --git a/Examples/test-suite/php/li_std_auto_ptr_runme.php b/Examples/test-suite/php/li_std_auto_ptr_runme.php index cba5f2109..16129490a 100644 --- a/Examples/test-suite/php/li_std_auto_ptr_runme.php +++ b/Examples/test-suite/php/li_std_auto_ptr_runme.php @@ -40,20 +40,27 @@ try { check::fail("is_nullptr check"); } catch (TypeError $e) { } +$exception_thrown = false; try { + takeKlassAutoPtr($kin); } catch (TypeError $e) { - check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' of takeKlassAutoPtr", "Unexpected exception: {$e->getMessage()}"); + check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassAutoPtr", "Unexpected exception: {$e->getMessage()}"); + $exception_thrown = true; } +check::equal($exception_thrown, true, "double usage of takeKlassAutoPtr should have been an error"); $kin = NULL; # Should not fail, even though already deleted checkCount(0); $kin = new Klass("KlassInput"); +$exception_thrown = false; $notowned = get_not_owned_ptr($kin); try { takeKlassAutoPtr($notowned); } catch (TypeError $e) { - check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' of takeKlassAutoPtr", "Unexpected exception: {$e->getMessage()}"); + check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassAutoPtr", "Unexpected exception: {$e->getMessage()}"); + $exception_thrown = true; } +check::equal($exception_thrown, true, "double usage of takeKlassAutoPtr should have been an error"); checkCount(1); $kin = NULL; checkCount(0); diff --git a/Examples/test-suite/php/tests.php b/Examples/test-suite/php/tests.php index 92e554741..0ff20e377 100644 --- a/Examples/test-suite/php/tests.php +++ b/Examples/test-suite/php/tests.php @@ -178,6 +178,11 @@ class check { return TRUE; } + static function str_contains($a,$b,$message=null) { + # Use strpos as PHP function str_contains requires PHP 8 + return check::equal(strpos($a,$b)!==false,true,$message); + } + static function isnull($a,$message=null) { return check::equal($a,NULL,$message); } diff --git a/Examples/test-suite/python/cpp11_rvalue_reference_move_input_runme.py b/Examples/test-suite/python/cpp11_rvalue_reference_move_input_runme.py new file mode 100644 index 000000000..7db7b4c3b --- /dev/null +++ b/Examples/test-suite/python/cpp11_rvalue_reference_move_input_runme.py @@ -0,0 +1,52 @@ +from cpp11_rvalue_reference_move_input import * + +# Function containing rvalue reference parameter +Counter.reset_counts() +mo = MovableCopyable(222) +Counter.check_counts(1, 0, 0, 0, 0, 0) +MovableCopyable.movein(mo) +Counter.check_counts(1, 0, 0, 1, 0, 2) +if not MovableCopyable.is_nullptr(mo): + raise RuntimeError("is_nullptr check") +del mo +Counter.check_counts(1, 0, 0, 1, 0, 2) + +# Move constructor test +Counter.reset_counts() +mo = MovableCopyable(222) +Counter.check_counts(1, 0, 0, 0, 0, 0) +mo_moved = MovableCopyable(mo) +Counter.check_counts(1, 0, 0, 1, 0, 1) +if not MovableCopyable.is_nullptr(mo): + raise RuntimeError("is_nullptr check") +del mo +Counter.check_counts(1, 0, 0, 1, 0, 1) +del mo_moved +Counter.check_counts(1, 0, 0, 1, 0, 2) + +# Move assignment operator test +Counter.reset_counts() +mo111 = MovableCopyable(111) +mo222 = MovableCopyable(222) +Counter.check_counts(2, 0, 0, 0, 0, 0) +mo111.MoveAssign(mo222) +Counter.check_counts(2, 0, 0, 0, 1, 1) +if not MovableCopyable.is_nullptr(mo222): + raise RuntimeError("is_nullptr check") +del mo222 +Counter.check_counts(2, 0, 0, 0, 1, 1) +del mo111 +Counter.check_counts(2, 0, 0, 0, 1, 2) + +# null check +Counter.reset_counts() +exception_thrown = False +try: + MovableCopyable.movein(None) +except ValueError as e: + if "invalid null reference" not in str(e): + raise RuntimeError("incorrect exception message:" + str(e)) + exception_thrown = True +if not exception_thrown: + raise RuntimeError("Should have thrown null error") +Counter.check_counts(0, 0, 0, 0, 0, 0) diff --git a/Examples/test-suite/ruby/cpp11_rvalue_reference_move_input_runme.rb b/Examples/test-suite/ruby/cpp11_rvalue_reference_move_input_runme.rb new file mode 100644 index 000000000..4b7347d43 --- /dev/null +++ b/Examples/test-suite/ruby/cpp11_rvalue_reference_move_input_runme.rb @@ -0,0 +1,87 @@ +#!/usr/bin/env ruby + +require 'swig_assert' + +require 'cpp11_rvalue_reference_move_input' + +# Function containing rvalue reference parameter +Cpp11_rvalue_reference_move_input::Counter.reset_counts() +mo = Cpp11_rvalue_reference_move_input::MovableCopyable.new(222) +Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 0, 0, 0) +Cpp11_rvalue_reference_move_input::MovableCopyable.movein(mo) +Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 1, 0, 2) +exception_thrown = false +begin + Cpp11_rvalue_reference_move_input::MovableCopyable.is_nullptr(mo) +rescue ObjectPreviouslyDeleted + exception_thrown = true +end +if (!exception_thrown) + raise RuntimeError, "is_nullptr failed to throw" +end +mo = nil +Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 1, 0, 2) + +# Move constructor test +Cpp11_rvalue_reference_move_input::Counter.reset_counts() +mo = Cpp11_rvalue_reference_move_input::MovableCopyable.new(222) +Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 0, 0, 0) +mo_moved = Cpp11_rvalue_reference_move_input::MovableCopyable.new(mo) +Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 1, 0, 1) +exception_thrown = false +begin + Cpp11_rvalue_reference_move_input::MovableCopyable.is_nullptr(mo) +rescue ObjectPreviouslyDeleted + exception_thrown = true +end +if (!exception_thrown) + raise RuntimeError, "is_nullptr failed to throw" +end +mo = nil +Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 1, 0, 1) +# mo_moved = nil +# Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 1, 0, 2) +# Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete +Cpp11_rvalue_reference_move_input::MovableCopyable.movein(mo_moved) +Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 2, 0, 3) + +# Move assignment operator test +Cpp11_rvalue_reference_move_input::Counter.reset_counts() +mo111 = Cpp11_rvalue_reference_move_input::MovableCopyable.new(111) +mo222 = Cpp11_rvalue_reference_move_input::MovableCopyable.new(222) +Cpp11_rvalue_reference_move_input::Counter.check_counts(2, 0, 0, 0, 0, 0) +mo111.MoveAssign(mo222) +Cpp11_rvalue_reference_move_input::Counter.check_counts(2, 0, 0, 0, 1, 1) +exception_thrown = false +begin + Cpp11_rvalue_reference_move_input::MovableCopyable.is_nullptr(mo222) +rescue ObjectPreviouslyDeleted + exception_thrown = true +end +if (!exception_thrown) + raise RuntimeError, "is_nullptr failed to throw" +end +mo222 = nil +Cpp11_rvalue_reference_move_input::Counter.check_counts(2, 0, 0, 0, 1, 1) +# mo111 = nil +# Cpp11_rvalue_reference_move_input::Counter.check_counts(2, 0, 0, 0, 1, 2) +# Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete +Cpp11_rvalue_reference_move_input::MovableCopyable.movein(mo111) +Cpp11_rvalue_reference_move_input::Counter.check_counts(2, 0, 0, 1, 1, 3) + +# null check +Cpp11_rvalue_reference_move_input::Counter.reset_counts() +exception_thrown = false +begin + Cpp11_rvalue_reference_move_input::MovableCopyable.movein(nil) +rescue ArgumentError => e + if (!e.to_s.include? "invalid null reference") + raise RuntimeError, "incorrect exception message: #{e.to_s}" + end + exception_thrown = true +end +if (!exception_thrown) + raise RuntimeError, "Should have thrown null error" +end +Cpp11_rvalue_reference_move_input::Counter.check_counts(0, 0, 0, 0, 0, 0) + diff --git a/Examples/test-suite/schemerunme/cpp11_rvalue_reference_move_input.scm b/Examples/test-suite/schemerunme/cpp11_rvalue_reference_move_input.scm new file mode 100644 index 000000000..303932f98 --- /dev/null +++ b/Examples/test-suite/schemerunme/cpp11_rvalue_reference_move_input.scm @@ -0,0 +1,46 @@ +; Function containing rvalue reference parameter +(Counter-reset-counts) +(define mo (new-MovableCopyable 222)) +(Counter-check-counts 1 0 0 0 0 0) +(MovableCopyable-movein mo) +(Counter-check-counts 1 0 0 1 0 2) +(unless (MovableCopyable-is-nullptr mo) + (error "is_nullptr failed")) +(delete-MovableCopyable mo) +(Counter-check-counts 1 0 0 1 0 2) + +; Move constructor test +(Counter-reset-counts) +(define mo (new-MovableCopyable 222)) +(Counter-check-counts 1 0 0 0 0 0) +(define mo_moved (new-MovableCopyable mo)) +(Counter-check-counts 1 0 0 1 0 1) +(unless (MovableCopyable-is-nullptr mo) + (error "is_nullptr failed")) +(delete-MovableCopyable mo) +(Counter-check-counts 1 0 0 1 0 1) +(delete-MovableCopyable mo_moved) +(Counter-check-counts 1 0 0 1 0 2) + +; Move assignment operator test +(Counter-reset-counts) +(define mo111 (new-MovableCopyable 111)) +(define mo222 (new-MovableCopyable 222)) +(Counter-check-counts 2 0 0 0 0 0) +(MovableCopyable-MoveAssign mo111 mo222) +(Counter-check-counts 2 0 0 0 1 1) +(unless (MovableCopyable-is-nullptr mo222) + (error "is_nullptr failed")) +(delete-MovableCopyable mo222) +(Counter-check-counts 2 0 0 0 1 1) +(delete-MovableCopyable mo111) +(Counter-check-counts 2 0 0 0 1 2) + +; null check +(Counter-reset-counts) +(expect-throw 'misc-error + (MovableCopyable-movein '())) +; TODO: check the exception message +(Counter-check-counts 0 0 0 0 0 0) + +(exit 0) diff --git a/Examples/test-suite/tcl/cpp11_rvalue_reference_move_input_runme.tcl b/Examples/test-suite/tcl/cpp11_rvalue_reference_move_input_runme.tcl new file mode 100644 index 000000000..a81bf398a --- /dev/null +++ b/Examples/test-suite/tcl/cpp11_rvalue_reference_move_input_runme.tcl @@ -0,0 +1,62 @@ + +if [ catch { load ./cpp11_rvalue_reference_move_input[info sharedlibextension] cpp11_rvalue_reference_move_input} err_msg ] { + puts stderr "Could not load shared object:\n$err_msg" +} + + +# Function containing rvalue reference parameter +Counter_reset_counts +MovableCopyable mo 222 +Counter_check_counts 1 0 0 0 0 0 +MovableCopyable_movein mo +Counter_check_counts 1 0 0 1 0 2 +if {![MovableCopyable_is_nullptr mo]} { + error "is_nullptr failed to throw" +} +mo -delete +Counter_check_counts 1 0 0 1 0 2 + +# Move constructor test +Counter_reset_counts +MovableCopyable mo 222 +Counter_check_counts 1 0 0 0 0 0 +MovableCopyable mo_moved mo +Counter_check_counts 1 0 0 1 0 1 +if {![MovableCopyable_is_nullptr mo]} { + error "is_nullptr failed to throw" +} +mo -delete +Counter_check_counts 1 0 0 1 0 1 +mo_moved -delete +Counter_check_counts 1 0 0 1 0 2 + +# Move assignment operator test +Counter_reset_counts +MovableCopyable mo111 111 +MovableCopyable mo222 222 +Counter_check_counts 2 0 0 0 0 0 +mo111 MoveAssign mo222 +Counter_check_counts 2 0 0 0 1 1 +if {![MovableCopyable_is_nullptr mo222]} { + error "is_nullptr failed to throw" +} +mo222 -delete +Counter_check_counts 2 0 0 0 1 1 +mo111 -delete +Counter_check_counts 2 0 0 0 1 2 + +# null check +Counter_reset_counts +set exception_thrown 0 +if [ catch { + MovableCopyable_movein "NULL" +} e ] { + if {[string first "invalid null reference" $e] == -1} { + error "incorrect exception message: $e" + } + set exception_thrown 1 +} +if {!$exception_thrown} { + error "Should have thrown null error" +} +Counter_check_counts 0 0 0 0 0 0 diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg index 60ab388f3..1f80d12a1 100644 --- a/Lib/csharp/csharp.swg +++ b/Lib/csharp/csharp.swg @@ -420,14 +420,15 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { %} %typemap(in, canthrow=1) SWIGTYPE & %{ $1 = ($1_ltype)$input; if (!$1) { - SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type type is null", 0); + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type is null", 0); return $null; } %} -%typemap(in, canthrow=1) SWIGTYPE && %{ $1 = ($1_ltype)$input; +%typemap(in, canthrow=1, fragment="") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = ($1_ltype)$input; if (!$1) { - SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type type is null", 0); + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type is null", 0); return $null; - } %} + } + rvrdeleter.reset($1); %} %typemap(out) SWIGTYPE * %{ $result = (void *)$1; %} %typemap(out, fragment="SWIG_PackData") SWIGTYPE (CLASS::*) %{ char buf[128]; @@ -613,7 +614,8 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { "$csinput" %typemap(csin) char *, char *&, char[ANY], char[] "$csinput" %typemap(csin) SWIGTYPE "$&csclassname.getCPtr($csinput)" -%typemap(csin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "$csclassname.getCPtr($csinput)" +%typemap(csin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$csclassname.getCPtr($csinput)" +%typemap(csin) SWIGTYPE && "$csclassname.swigRelease($csinput)" %typemap(csin) SWIGTYPE (CLASS::*) "$csclassname.getCMemberPtr($csinput)" /* The csout typemap is used for converting function return types from the return type diff --git a/Lib/d/dswigtype.swg b/Lib/d/dswigtype.swg index 3fb7f6a01..c227519e8 100644 --- a/Lib/d/dswigtype.swg +++ b/Lib/d/dswigtype.swg @@ -122,7 +122,7 @@ %typemap(in, canthrow=1) SWIGTYPE & %{ $1 = ($1_ltype)$input; if (!$1) { - SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type type is null"); + SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type is null"); return $null; } %} %typemap(out) SWIGTYPE & "$result = (void *)$1;" @@ -157,11 +157,12 @@ * Rvalue reference conversion typemaps. */ -%typemap(in, canthrow=1) SWIGTYPE && %{ $1 = ($1_ltype)$input; +%typemap(in, canthrow=1, fragment="") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = ($1_ltype)$input; if (!$1) { - SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type type is null"); + SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type is null"); return $null; - } %} + } + rvrdeleter.reset($1); %} %typemap(out) SWIGTYPE && "$result = (void *)$1;" %typemap(directorin) SWIGTYPE && @@ -182,7 +183,7 @@ %typemap(din, nativepointer="cast(void*)$dinput" -) SWIGTYPE && "$dclassname.swigGetCPtr($dinput)" +) SWIGTYPE && "$dclassname.swigRelease($dinput)" %typemap(dout, excode=SWIGEXCODE, nativepointer="{\n auto ret = cast($dtype)$imcall;$excode\n return ret;\n}") SWIGTYPE && { $dclassname ret = new $dclassname($imcall, $owner);$excode diff --git a/Lib/guile/typemaps.i b/Lib/guile/typemaps.i index 4381c3dec..37dfaee64 100644 --- a/Lib/guile/typemaps.i +++ b/Lib/guile/typemaps.i @@ -4,12 +4,33 @@ * Guile-specific typemaps * ----------------------------------------------------------------------------- */ +/* These are defined with a view to eventually merging with those defined for other target languages in swigtypemaps.swg and exception.swg */ +#define %set_output(obj) $result = obj +#define %set_varoutput(obj) $result = obj +#define %argument_fail(_code, _type, _name, _argn) scm_wrong_type_arg((char *) FUNC_NAME, _argn, $input) +#define %as_voidptr(ptr) (void*)(ptr) +#define %argument_nullref(_type, _name, _argn) scm_misc_error(FUNC_NAME, "invalid null reference for argument " #_argn " of type '" _type "'", SCM_EOL) +#define %releasenotowned_fail(_code, _type, _name, _argn) scm_misc_error(FUNC_NAME, "cannot release ownership as memory is not owned for argument " #_argn " of type '" _type "'", SCM_EOL) + /* Pointers */ -%typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] { +%typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { $1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, 0); } -%typemap(freearg) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] ""; +%typemap(in, noblock=1, fragment="") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) { + res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE); + if (!SWIG_IsOK(res)) { + if (res == SWIG_ERROR_RELEASE_NOT_OWNED) { + %releasenotowned_fail(res, "$1_type", $symname, $argnum); + } else { + %argument_fail(res, "$1_type", $symname, $argnum); + } + } + if (!argp) { %argument_nullref("$1_type", $symname, $argnum); } + $1 = ($1_ltype)argp; + rvrdeleter.reset($1); +} +%typemap(freearg) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "" %typemap(in) void * { $1 = ($1_ltype)SWIG_MustGetPtr($input, NULL, $argnum, 0); @@ -372,11 +393,6 @@ typedef unsigned long SCM; * taken from typemaps/swigtype.swg * ------------------------------------------------------------ */ -#define %set_output(obj) $result = obj -#define %set_varoutput(obj) $result = obj -#define %argument_fail(code, type, name, argn) scm_wrong_type_arg((char *) FUNC_NAME, argn, $input); -#define %as_voidptr(ptr) (void*)(ptr) - %typemap(in) SWIGTYPE (CLASS::*) { int res = SWIG_ConvertMember($input, %as_voidptr(&$1), sizeof($1), $descriptor); if (!SWIG_IsOK(res)) { diff --git a/Lib/java/java.swg b/Lib/java/java.swg index 821b5cdf6..8719818bb 100644 --- a/Lib/java/java.swg +++ b/Lib/java/java.swg @@ -692,12 +692,12 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); } } %typemap(in) SWIGTYPE & %{ $1 = *($&1_ltype)&$input; if (!$1) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null"); + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type is null"); return $null; } %} %typemap(in, fragment="") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = *($&1_ltype)&$input; if (!$1) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null"); + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type is null"); return $null; } rvrdeleter.reset($1); %} diff --git a/Lib/lua/luatypemaps.swg b/Lib/lua/luatypemaps.swg index fdb9b3a97..7d23917ee 100644 --- a/Lib/lua/luatypemaps.swg +++ b/Lib/lua/luatypemaps.swg @@ -151,11 +151,17 @@ SWIGINTERN int SWIG_lua_isnilstring(lua_State *L, int idx) { } %} -%typemap(in,checkfn="lua_isuserdata") SWIGTYPE&& -%{ - if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,$disown))){ - SWIG_fail_ptr("$symname",$argnum,$descriptor); +%typemap(in,checkfn="lua_isuserdata",fragment="") SWIGTYPE&& (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) %{ + res = SWIG_ConvertPtr(L, $input, &argp, $descriptor, SWIG_POINTER_RELEASE); + if (!SWIG_IsOK(res)) { + if (res == SWIG_ERROR_RELEASE_NOT_OWNED) { + lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type '$1_type' in $symname"); SWIG_fail; + } else { + SWIG_fail_ptr("$symname", $argnum, $descriptor); + } } + $1 = ($1_ltype)argp; + rvrdeleter.reset($1); %} // out is simple diff --git a/Lib/mzscheme/std_auto_ptr.i b/Lib/mzscheme/std_auto_ptr.i index a903d0063..dd55230b3 100644 --- a/Lib/mzscheme/std_auto_ptr.i +++ b/Lib/mzscheme/std_auto_ptr.i @@ -8,9 +8,6 @@ * C++ layer when passed as a parameter to a wrapped function. * ----------------------------------------------------------------------------- */ -#define %argument_fail(code, type, name, argn) scheme_wrong_type(FUNC_NAME, type, argn, argc, argv); -#define %set_output(obj) $result = obj - %define %auto_ptr(TYPE) %typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) { res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE); diff --git a/Lib/mzscheme/std_unique_ptr.i b/Lib/mzscheme/std_unique_ptr.i index 35386a783..af602c342 100644 --- a/Lib/mzscheme/std_unique_ptr.i +++ b/Lib/mzscheme/std_unique_ptr.i @@ -8,9 +8,6 @@ * C++ layer when passed as a parameter to a wrapped function. * ----------------------------------------------------------------------------- */ -#define %argument_fail(code, type, name, argn) scheme_wrong_type(FUNC_NAME, type, argn, argc, argv); -#define %set_output(obj) $result = obj - %define %unique_ptr(TYPE) %typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) { res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE); diff --git a/Lib/mzscheme/typemaps.i b/Lib/mzscheme/typemaps.i index 9a1e676e9..25c7b7707 100644 --- a/Lib/mzscheme/typemaps.i +++ b/Lib/mzscheme/typemaps.i @@ -4,7 +4,7 @@ #define %set_output(obj) $result = obj #define %set_varoutput(obj) $result = obj -#define %argument_fail(code, type, name, argn) scheme_wrong_type(FUNC_NAME, type, argn, argc, argv); +#define %argument_fail(code, type, name, argn) scheme_wrong_type(FUNC_NAME, type, argn, argc, argv) #define %as_voidptr(ptr) (void*)(ptr) @@ -72,9 +72,23 @@ #ifdef __cplusplus -%typemap(in) SWIGTYPE &, SWIGTYPE && { +%typemap(in) SWIGTYPE & { $1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, $argnum, 0); - if ($1 == NULL) scheme_signal_error("swig-type-error (null reference)"); + if ($1 == NULL) scheme_signal_error(FUNC_NAME ": swig-type-error (null reference)"); +} + +%typemap(in, noblock=1, fragment="") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) { + res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE); + if (!SWIG_IsOK(res)) { + if (res == SWIG_ERROR_RELEASE_NOT_OWNED) { + scheme_signal_error(FUNC_NAME ": cannot release ownership as memory is not owned for argument $argnum of type '$1_type'"); + } else { + %argument_fail(res, "$1_type", $symname, $argnum); + } + } + if (argp == NULL) scheme_signal_error(FUNC_NAME ": swig-type-error (null reference)"); + $1 = ($1_ltype)argp; + rvrdeleter.reset($1); } %typemap(out) SWIGTYPE &, SWIGTYPE && { diff --git a/Lib/php/php.swg b/Lib/php/php.swg index 26944a1af..04b7075b7 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -125,14 +125,31 @@ swig_acquire_ownership_obj((void*)$result, own); %} -%typemap(in, phptype="SWIGTYPE") SWIGTYPE &, - SWIGTYPE && +%typemap(in, phptype="SWIGTYPE") SWIGTYPE & %{ if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) { zend_type_error("Expected $1_descriptor for argument $argnum of $symname"); return; } %} +%typemap(in, fragment="") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) %{ + res = SWIG_ConvertPtr(&$input, &argp, $descriptor, SWIG_POINTER_RELEASE); + if (!SWIG_IsOK(res)) { + if (res == SWIG_ERROR_RELEASE_NOT_OWNED) { + zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $1_descriptor of $symname"); + return; + } else { + zend_type_error("Expected $1_descriptor for argument $argnum of $symname"); + return; + } + } + if (!argp) { + zend_type_error("Invalid null reference for argument $argnum of $1_descriptor of $symname"); + return; + } + $1 = ($1_ltype)argp; + rvrdeleter.reset($1); +%} %typemap(directorout) SWIGTYPE & ($1_ltype tmp), SWIGTYPE && ($1_ltype tmp) diff --git a/Lib/php/std_auto_ptr.i b/Lib/php/std_auto_ptr.i index 7df497e60..bd07dbdb5 100644 --- a/Lib/php/std_auto_ptr.i +++ b/Lib/php/std_auto_ptr.i @@ -13,10 +13,10 @@ res = SWIG_ConvertPtr(&$input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE); if (!SWIG_IsOK(res)) { if (res == SWIG_ERROR_RELEASE_NOT_OWNED) { - zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *' of $symname"); + zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $descriptor(TYPE *) of $symname"); return; } else { - zend_type_error("Expected TYPE * for argument $argnum of $symname"); + zend_type_error("Expected $descriptor(TYPE *) for argument $argnum of $symname"); return; } } diff --git a/Lib/php/std_unique_ptr.i b/Lib/php/std_unique_ptr.i index 591f580cb..168273663 100644 --- a/Lib/php/std_unique_ptr.i +++ b/Lib/php/std_unique_ptr.i @@ -13,10 +13,10 @@ res = SWIG_ConvertPtr(&$input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE); if (!SWIG_IsOK(res)) { if (res == SWIG_ERROR_RELEASE_NOT_OWNED) { - zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *' of $symname"); + zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $descriptor(TYPE *) of $symname"); return; } else { - zend_type_error("Expected TYPE * for argument $argnum of $symname"); + zend_type_error("Expected $descriptor(TYPE *) for argument $argnum of $symname"); return; } } diff --git a/Lib/typemaps/swigtype.swg b/Lib/typemaps/swigtype.swg index 0f35dc397..65f558a27 100644 --- a/Lib/typemaps/swigtype.swg +++ b/Lib/typemaps/swigtype.swg @@ -68,13 +68,18 @@ #endif /* Rvalue reference */ -%typemap(in, noblock=1) SWIGTYPE && (void *argp = 0, int res = 0) { - res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags); +%typemap(in, noblock=1, fragment="") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) { + res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE | %convertptr_flags); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + if (res == SWIG_ERROR_RELEASE_NOT_OWNED) { + %releasenotowned_fail(res, "$type", $symname, $argnum); + } else { + %argument_fail(res, "$type", $symname, $argnum); + } } if (!argp) { %argument_nullref("$type", $symname, $argnum); } $1 = %reinterpret_cast(argp, $ltype); + rvrdeleter.reset($1); } %typemap(freearg) SWIGTYPE && ""