mirror of https://github.com/swig/swig
Sort out directorout typemaps for std::string_view
With Perl the returned string is still being corrupted (the testcase flags this as "TODO" for Perl's test harness). Warnings aren't currently emitted for Perl, Ruby or Tcl as I'm not seeing where in the UTL maze the directorout typemap actually gets defined.
This commit is contained in:
parent
18afec7860
commit
ccf4f6ec72
|
@ -22,6 +22,9 @@ public class runme
|
|||
|
||||
cpp17_director_string_view_B b = new cpp17_director_string_view_B("hello");
|
||||
|
||||
s = b.get_first();
|
||||
if (s != "cpp17_director_string_view_B.get_first") throw new Exception("get_first() failed");
|
||||
|
||||
s = b.call_get_first();
|
||||
if (s != "cpp17_director_string_view_B.get_first") throw new Exception("call_get_first() failed");
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@ public class cpp17_director_string_view_runme {
|
|||
|
||||
cpp17_director_string_view_B b = new cpp17_director_string_view_B("hello");
|
||||
|
||||
s = b.get_first();
|
||||
if (!s.equals("cpp17_director_string_view_B.get_first")) throw new RuntimeException("get_first() failed");
|
||||
|
||||
s = b.call_get_first();
|
||||
if (!s.equals("cpp17_director_string_view_B.get_first")) throw new RuntimeException("call_get_first() failed");
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 5;
|
||||
use Test::More tests => 7;
|
||||
BEGIN { use_ok 'cpp17_director_string_view' }
|
||||
require_ok 'cpp17_director_string_view';
|
||||
|
||||
|
@ -11,8 +11,11 @@ require_ok 'cpp17_director_string_view';
|
|||
sub get_first { my($self) = @_;
|
||||
die "SUPER RESOLVE BAD" if $in_first;
|
||||
local $in_first = 1;
|
||||
# Since std::string_view contains a pointer into a string, the string
|
||||
# cannot be a temporary in order to avoid undefined behaviour.
|
||||
my $x = $self->SUPER::get_first();
|
||||
return $x . " world!";
|
||||
$self->{cached_string} = $x . " world!";
|
||||
return $self->{cached_string};
|
||||
}
|
||||
our $in_process_text = 0;
|
||||
sub process_text { my($self, $string) = @_;
|
||||
|
@ -26,10 +29,12 @@ require_ok 'cpp17_director_string_view';
|
|||
my $b = B->new("hello");
|
||||
isa_ok $b, 'B';
|
||||
|
||||
$b->get(0);
|
||||
is $b->get(0), "hello";
|
||||
|
||||
{ local $TODO = "Return value gets corrupted";
|
||||
is $b->get_first(), "hello world!"; }
|
||||
is $b->get_first(), "hello world!";
|
||||
is $b->call_get_first(), "hello world!";
|
||||
}
|
||||
|
||||
$b->call_process_func();
|
||||
|
||||
|
|
|
@ -12,8 +12,13 @@ check::globals(array());
|
|||
class B extends A {
|
||||
public $smem;
|
||||
|
||||
private $cached_string;
|
||||
|
||||
function get_first() {
|
||||
return parent::get_first() . " world!";
|
||||
// Since std::string_view contains a pointer into a string, the string
|
||||
// cannot be a temporary in order to avoid undefined behaviour.
|
||||
$this->cached_string = parent::get_first() . " world!";
|
||||
return $this->cached_string;
|
||||
}
|
||||
|
||||
function process_text($string) {
|
||||
|
@ -24,8 +29,11 @@ class B extends A {
|
|||
|
||||
$b = new B("hello");
|
||||
|
||||
$b->get(0);
|
||||
check::equal($b->get_first(),"hello world!", "get_first failed");
|
||||
check::equal($b->get(0), "hello", "get(0) failed");
|
||||
|
||||
check::equal($b->get_first(), "hello world!", "get_first failed");
|
||||
|
||||
check::equal($b->call_get_first(), "hello world!", "call_get_first failed");
|
||||
|
||||
$b->call_process_func();
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ class B(A):
|
|||
A.__init__(self, string)
|
||||
|
||||
def get_first(self):
|
||||
# Given std::string_view is just a pointer into a string, the string
|
||||
# cannot be a temporary in order to avoid undefined behaviour
|
||||
# Since std::string_view contains a pointer into a string, the string
|
||||
# cannot be a temporary in order to avoid undefined behaviour.
|
||||
self.cached_string = A.get_first(self) + " world!"
|
||||
return self.cached_string
|
||||
|
||||
|
@ -19,7 +19,9 @@ class B(A):
|
|||
|
||||
b = B("hello")
|
||||
|
||||
b.get(0)
|
||||
if b.get(0) != "hello":
|
||||
raise RuntimeError("b.get(0): {}".format(b.get(0)))
|
||||
|
||||
if b.get_first() != "hello world!":
|
||||
raise RuntimeError("b.get_first(): {}".format(b.get_first()))
|
||||
|
||||
|
|
|
@ -12,13 +12,31 @@ require 'swig_assert'
|
|||
require 'cpp17_director_string_view'
|
||||
|
||||
class B < Cpp17_director_string_view::A
|
||||
attr_accessor :smem
|
||||
|
||||
def initialize(some_string)
|
||||
super(some_string)
|
||||
end
|
||||
|
||||
def get_first()
|
||||
# Since std::string_view contains a pointer into a string, the string
|
||||
# cannot be a temporary in order to avoid undefined behaviour.
|
||||
@cached_string = super() + " world!"
|
||||
return @cached_string
|
||||
end
|
||||
|
||||
def process_text(string)
|
||||
super(string)
|
||||
@smem = "hello"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
b = B.new("hello")
|
||||
b.get_first
|
||||
b.get(0)
|
||||
raise RuntimeError if b.get(0) != "hello"
|
||||
raise RuntimeError if b.get_first() != "hello world!"
|
||||
raise RuntimeError if b.call_get_first() != "hello world!"
|
||||
|
||||
b.call_process_func()
|
||||
raise RuntimeError if b.smem != "hello"
|
||||
|
|
|
@ -36,12 +36,15 @@ class string_view;
|
|||
$1 = std::string_view($input); %}
|
||||
%typemap(out) string_view %{ $result = SWIG_csharp_string_callback(std::string($1).c_str()); %}
|
||||
|
||||
%typemap(directorout, canthrow=1) string_view
|
||||
%typemap(directorout, canthrow=1, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) string_view
|
||||
%{ if (!$input) {
|
||||
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
|
||||
return $null;
|
||||
}
|
||||
$result = std::string_view($input); %}
|
||||
/* possible thread/reentrant code problem */
|
||||
static std::string $1_str;
|
||||
$1_str = $input;
|
||||
$result = std::string_view($1_str); %}
|
||||
|
||||
%typemap(directorin) string_view %{ $input = std::string($1).c_str(); %}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ class string_view;
|
|||
$1_str = $1_pstr;
|
||||
static $*1_ltype $1_strview;
|
||||
$1_strview = $1_str;
|
||||
$result = &$1_str;
|
||||
$result = &$1_strview;
|
||||
jenv->ReleaseStringUTFChars($input, $1_pstr); %}
|
||||
|
||||
%typemap(directorin,descriptor="Ljava/lang/String;") const string_view &
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace std {
|
|||
$1 = &temp;
|
||||
%}
|
||||
|
||||
%typemap(directorout) string_view %{
|
||||
%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) string_view %{
|
||||
convert_to_string($input);
|
||||
$result = std::string_view(Z_STRVAL_P($input), Z_STRLEN_P($input));
|
||||
%}
|
||||
|
|
Loading…
Reference in New Issue