diff --git a/CHANGES.current b/CHANGES.current index 41824f3fa..e312abaaa 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,15 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.1.0 (in progress) =========================== +2022-07-12: wsfulton + Performance optimisation for parameters passed by value that are C++11 movable. + The C++ wrappers create a temporary variable for a parameter to be passed to a + function. This is initially default constructed and then copy assigned from the + instance being passed in from the target language. This is unchanged, however, + when the temporary variable is passed to wrapped function, it is now done using + std::move. If the type is move constructible, the move constructor will be used + instead of the copy constructor. + 2022-07-12: wsfulton [Perl] Add std::auto_ptr support in std_auto_ptr.i library file. diff --git a/Examples/test-suite/cpp11_move_only.i b/Examples/test-suite/cpp11_move_only.i index 7c91933c4..f97d7090e 100644 --- a/Examples/test-suite/cpp11_move_only.i +++ b/Examples/test-suite/cpp11_move_only.i @@ -27,6 +27,8 @@ struct MoveOnly { static MoveOnly create() { return MoveOnly(111); } // static const MoveOnly createConst() { return MoveOnly(111); } // not supported by default + + // static void take(MoveOnly mo) { if (debug) cout << "take(MoveOnly)" << " " << &mo << endl; } }; %} @@ -48,5 +50,7 @@ struct MovableCopyable { static MovableCopyable create() { return MovableCopyable(111); } static const MovableCopyable createConst() { return MovableCopyable(111); } + + static void take(MovableCopyable mc) { if (debug) cout << "take(MovableCopyable)" << " " << &mc << endl; } }; %} diff --git a/Examples/test-suite/csharp/cpp11_move_only_runme.cs b/Examples/test-suite/csharp/cpp11_move_only_runme.cs index 57cb7aa18..f2d1c4cb5 100644 --- a/Examples/test-suite/csharp/cpp11_move_only_runme.cs +++ b/Examples/test-suite/csharp/cpp11_move_only_runme.cs @@ -4,6 +4,8 @@ using cpp11_move_onlyNamespace; public class cpp11_move_only_runme { public static void Main() { + + // Output Counter.reset_counts(); using (MoveOnly mo = MoveOnly.create()) { } @@ -19,5 +21,14 @@ public class cpp11_move_only_runme { using (MovableCopyable mo = MovableCopyable.createConst()) { } Counter.check_counts(2, 1, 1, 0, 0, 3); + + // Input + Counter.reset_counts(); + using (MovableCopyable mo = new MovableCopyable(222)) { + Counter.check_counts(1, 0, 0, 0, 0, 0); + MovableCopyable.take(mo); + Counter.check_counts(2, 0, 1, 1, 0, 2); + } + Counter.check_counts(2, 0, 1, 1, 0, 3); } } diff --git a/Examples/test-suite/java/cpp11_move_only_runme.java b/Examples/test-suite/java/cpp11_move_only_runme.java index b652634e5..8f0f2acef 100644 --- a/Examples/test-suite/java/cpp11_move_only_runme.java +++ b/Examples/test-suite/java/cpp11_move_only_runme.java @@ -14,6 +14,7 @@ public class cpp11_move_only_runme { public static void main(String argv[]) { + // Output { Counter.reset_counts(); MoveOnly mo = MoveOnly.create(); @@ -35,5 +36,16 @@ public class cpp11_move_only_runme { mo.delete(); Counter.check_counts(2, 1, 1, 0, 0, 3); } + + // Input + { + Counter.reset_counts(); + MovableCopyable mo = new MovableCopyable(222); + Counter.check_counts(1, 0, 0, 0, 0, 0); + MovableCopyable.take(mo); + Counter.check_counts(2, 0, 1, 1, 0, 2); + mo.delete(); + Counter.check_counts(2, 0, 1, 1, 0, 3); + } } } diff --git a/Examples/test-suite/python/cpp11_move_only_runme.py b/Examples/test-suite/python/cpp11_move_only_runme.py index 1c3183327..9727f3fcc 100644 --- a/Examples/test-suite/python/cpp11_move_only_runme.py +++ b/Examples/test-suite/python/cpp11_move_only_runme.py @@ -1,5 +1,6 @@ from cpp11_move_only import * +# Output Counter.reset_counts() mo = MoveOnly.create() del mo @@ -15,3 +16,12 @@ Counter.reset_counts() mo = MovableCopyable.createConst() del mo Counter.check_counts(2, 1, 1, 0, 0, 3) + +# Input +Counter.reset_counts() +mo = MovableCopyable(222) +Counter.check_counts(1, 0, 0, 0, 0, 0) +MovableCopyable.take(mo) +Counter.check_counts(2, 0, 1, 1, 0, 2) +del mo +Counter.check_counts(2, 0, 1, 1, 0, 3) diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index ebe9fa702..36e69332c 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -427,10 +427,14 @@ String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms) { String *rcaststr = SwigType_rcaststr(rpt, pname); if (comma) { - Printv(func, ",", rcaststr, NIL); - } else { - Append(func, rcaststr); + Append(func, ","); } + + if (cparse_cplusplus && SwigType_type(rpt) == T_USER) + Printv(func, "SWIG_STD_MOVE(", rcaststr, ")", NIL); + else + Printv(func, rcaststr, NIL); + Delete(rpt); Delete(pname); Delete(rcaststr);