Add Octave support for std::unique_ptr and std::auto_ptr

Equivalent to Ruby/Python implementations.
This commit is contained in:
William S Fulton 2022-08-01 23:49:14 +01:00
commit 2ccc9bd060
8 changed files with 341 additions and 20 deletions

View file

@ -1,6 +1,6 @@
%module cpp11_std_unique_ptr
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL)
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL) || defined(SWIGOCTAVE)
%include "std_string.i"
%include "std_unique_ptr.i"

View file

@ -12,17 +12,28 @@
#endif
%}
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL)
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL) || defined(SWIGOCTAVE)
%include "std_string.i"
%include "std_auto_ptr.i"
%auto_ptr(Klass)
%inline %{
void show_cplusplus_version() {
printf("__cplusplus %d\n", (int)__cplusplus);
}
%}
%{
#if __cplusplus < 201703L
#include <memory>
#else
// If <memory> has already been include (Octave does) then unfortunately gcc incorrectly still provides
// std::auto_ptr when _GLIBCXX_USE_DEPRECATED is defined by the compiler configuration/OS/who knows what!!
#include <memory> // Now need to include it in case _GLIBCXX_USE_DEPRECATED is defined and <memory> has not been included, argh
#if !defined(_GLIBCXX_USE_DEPRECATED)
// Simple std::auto_ptr implementation for testing after its removal in C++17
namespace std {
template <class T> class auto_ptr {
@ -40,6 +51,8 @@ namespace std {
}
#endif
#endif
#include <string>
#include "swig_examples_lock.h"
%}

View file

@ -0,0 +1,109 @@
# do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
cpp11_std_unique_ptr
function checkCount(expected_count)
actual_count = Klass_getTotal_count();
if (actual_count != expected_count)
error("Counts incorrect, expected:%d actual:%d", expected_count, actual_count);
endif
end
# unique_ptr as input
kin = Klass("KlassInput");
checkCount(1);
s = takeKlassUniquePtr(kin);
checkCount(0);
if (!strcmp(s, "KlassInput"))
error("Incorrect string: %s", s);
endif
if (!is_nullptr(kin))
error("is_nullptr failed");
endif
clear kin; # Should not fail, even though already deleted
checkCount(0);
kin = Klass("KlassInput");
checkCount(1);
s = takeKlassUniquePtr(kin);
checkCount(0);
if (!strcmp(s, "KlassInput"))
error("Incorrect string: %s", s);
endif
if (!is_nullptr(kin))
error("is_nullptr failed");
endif
exception_thrown = false;
try
takeKlassUniquePtr(kin);
catch e
if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
error("incorrect exception message %s", e.message);
endif
exception_thrown = true;
end_try_catch
if (!exception_thrown)
error("double usage of takeKlassUniquePtr should have been an error");
endif
clear kin; # Should not fail, even though already deleted
checkCount(0);
kin = Klass("KlassInput");
exception_thrown = false;
try
notowned = get_not_owned_ptr(kin);
takeKlassUniquePtr(notowned);
catch e
if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
error("incorrect exception message %s", e.message);
endif
exception_thrown = true;
end_try_catch
if (!exception_thrown)
error("Should have thrown 'Cannot release ownership as memory is not owned' error");
endif
clear kin;
checkCount(0);
kini = KlassInheritance("KlassInheritanceInput");
checkCount(1);
s = takeKlassUniquePtr(kini);
checkCount(0);
if (!strcmp(s, "KlassInheritanceInput"))
error("Incorrect string: %s", s);
endif
if (!is_nullptr(kini))
error("is_nullptr failed");
endif
clear kini; # Should not fail, even though already deleted
checkCount(0);
# unique_ptr as output
k1 = makeKlassUniquePtr("first");
if (!strcmp(k1.getLabel(), "first"))
error("wrong object label");
endif
k2 = makeKlassUniquePtr("second");
if (Klass_getTotal_count() != 2)
error("number of objects should be 2");
endif
clear k1;
if (Klass.getTotal_count() != 1)
error("number of objects should be 1");
endif
if (!strcmp(k2.getLabel(), "second"))
error("wrong object label");
endif
clear k2;
if (Klass.getTotal_count() != 0)
error("no objects should be left");
endif

View file

@ -0,0 +1,108 @@
# do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
li_std_auto_ptr
function checkCount(expected_count)
actual_count = Klass_getTotal_count();
if (actual_count != expected_count)
error("Counts incorrect, expected:%d actual:%d", expected_count, actual_count);
endif
end
# auto_ptr as input
kin = Klass("KlassInput");
checkCount(1);
s = takeKlassAutoPtr(kin);
checkCount(0);
if (!strcmp(s, "KlassInput"))
error("Incorrect string: %s", s);
endif
if (!is_nullptr(kin))
error("is_nullptr failed");
endif
clear kin; # Should not fail, even though already deleted
checkCount(0);
kin = Klass("KlassInput");
checkCount(1);
s = takeKlassAutoPtr(kin);
checkCount(0);
if (!strcmp(s, "KlassInput"))
error("Incorrect string: %s", s);
endif
if (!is_nullptr(kin))
error("is_nullptr failed");
endif
exception_thrown = false;
try
takeKlassAutoPtr(kin);
catch e
if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
error("incorrect exception message %s", e.message);
endif
exception_thrown = true;
end_try_catch
if (!exception_thrown)
error("double usage of takeKlassAutoPtr should have been an error");
endif
clear kin; # Should not fail, even though already deleted
checkCount(0);
kin = Klass("KlassInput");
exception_thrown = false;
try
notowned = get_not_owned_ptr(kin);
takeKlassAutoPtr(notowned);
catch e
if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
error("incorrect exception message %s", e.message);
endif
exception_thrown = true;
end_try_catch
if (!exception_thrown)
error("Should have thrown 'Cannot release ownership as memory is not owned' error");
endif
clear kin;
checkCount(0);
kini = KlassInheritance("KlassInheritanceInput");
checkCount(1);
s = takeKlassAutoPtr(kini);
checkCount(0);
if (!strcmp(s, "KlassInheritanceInput"))
error("Incorrect string: %s", s);
endif
if (!is_nullptr(kini))
error("is_nullptr failed");
endif
clear kini; # Should not fail, even though already deleted
checkCount(0);
# auto_ptr as output
k1 = makeKlassAutoPtr("first");
if (!strcmp(k1.getLabel(), "first"))
error("wrong object label");
endif
k2 = makeKlassAutoPtr("second");
if (Klass_getTotal_count() != 2)
error("number of objects should be 2");
endif
clear k1;
if (Klass.getTotal_count() != 1)
error("number of objects should be 1");
endif
if (!strcmp(k2.getLabel(), "second"))
error("wrong object label");
endif
clear k2;
if (Klass.getTotal_count() != 0)
error("no objects should be left");
endif