summaryrefslogtreecommitdiff
path: root/Examples
diff options
context:
space:
mode:
authorOlly Betts <olly@survex.com>2023-05-08 15:56:37 +1200
committerOlly Betts <olly@survex.com>2023-05-08 15:56:37 +1200
commit6085a9661edd6bbfbe0dbffd187afda8be8aefd0 (patch)
tree747308c4a6a0008fe1ba2b5ab7b74b425b063f73 /Examples
parent0fa2ab8945ff40e770045dd86ed0380c006643fc (diff)
downloadswig-6085a9661edd6bbfbe0dbffd187afda8be8aefd0.tar.gz
Initial support for std::string_view
So far C#, Java, Lua and PHP are supported. Closes: #2540 See #1567
Diffstat (limited to 'Examples')
-rw-r--r--Examples/test-suite/common.mk1
-rw-r--r--Examples/test-suite/cpp17_string_view.i112
-rw-r--r--Examples/test-suite/csharp/cpp17_string_view_runme.cs84
-rw-r--r--Examples/test-suite/csharp/director_string_view_runme.cs52
-rw-r--r--Examples/test-suite/director_string_view.i56
-rw-r--r--Examples/test-suite/java/cpp17_string_view_runme.java92
-rw-r--r--Examples/test-suite/java/director_string_view_runme.java55
-rw-r--r--Examples/test-suite/lua/cpp17_string_view_runme.lua50
-rw-r--r--Examples/test-suite/php/cpp17_string_view_runme.php44
-rw-r--r--Examples/test-suite/php/director_string_view_runme.php34
10 files changed, 580 insertions, 0 deletions
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index c781bd930..7b007a2ac 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -657,6 +657,7 @@ CPP17_TEST_CASES += \
cpp17_hex_floating_literals \
cpp17_nested_namespaces \
cpp17_nspace_nested_namespaces \
+ cpp17_string_view \
cpp17_u8_char_literals \
# Broken C++17 test cases.
diff --git a/Examples/test-suite/cpp17_string_view.i b/Examples/test-suite/cpp17_string_view.i
new file mode 100644
index 000000000..864cc97eb
--- /dev/null
+++ b/Examples/test-suite/cpp17_string_view.i
@@ -0,0 +1,112 @@
+%module cpp17_string_view
+#if defined SWIGCSHARP || defined SWIGJAVA || defined SWIGLUA || defined SWIGPHP
+%include <std_string_view.i>
+
+// throw is invalid in C++17 and later, only SWIG to use it
+#define TESTCASE_THROW1(T1) throw(T1)
+%{
+#define TESTCASE_THROW1(T1)
+%}
+
+%inline %{
+
+std::string_view test_value(std::string_view x) {
+ return x;
+}
+
+const std::string_view& test_const_reference(const std::string_view &x) {
+ return x;
+}
+
+void test_const_reference_returning_void(const std::string_view &) {
+}
+
+void test_const_reference_returning_void(const std::string_view &, int) {
+}
+
+void test_pointer(std::string_view *x) {
+}
+
+std::string_view *test_pointer_out() {
+ static std::string_view x = "x";
+ return &x;
+}
+
+void test_const_pointer(const std::string_view *x) {
+}
+
+const std::string_view *test_const_pointer_out() {
+ static std::string_view x = "x";
+ return &x;
+}
+
+void test_reference(std::string_view &x) {
+}
+
+std::string_view& test_reference_out() {
+ static std::string_view x = "test_reference_out message";
+ return x;
+}
+
+std::string_view test_reference_input(std::string_view &input) {
+ return input;
+}
+
+void test_throw() TESTCASE_THROW1(std::string_view){
+ static std::string_view x = "test_throw message";
+ throw x;
+}
+
+void test_const_reference_throw() TESTCASE_THROW1(const std::string_view &){
+ static const std::string_view x = "test_const_reference_throw message";
+ throw x;
+}
+
+void test_pointer_throw() TESTCASE_THROW1(std::string_view *) {
+ throw new std::string_view("foo");
+}
+
+void test_const_pointer_throw() TESTCASE_THROW1(const std::string_view *) {
+ throw static_cast<const std::string_view*>(new std::string_view("foo"));
+}
+%}
+
+#ifdef SWIGSCILAB
+%rename(ConstStr) ConstMemberString;
+%rename(ConstStaticStr) ConstStaticMemberString;
+#endif
+
+%inline %{
+const std::string_view ConstGlobalString = "const global string";
+
+struct Structure {
+ const std::string_view ConstMemberString;
+ static const std::string_view ConstStaticMemberString;
+
+ Structure() : ConstMemberString("const member string") {}
+};
+%}
+
+%{
+ const std::string_view Structure::ConstStaticMemberString = "const static member string";
+%}
+
+
+%inline %{
+ std::string_view stdstring_empty() {
+ return std::string_view();
+ }
+
+ char *c_empty() {
+ return (char *)"";
+ }
+
+ char *c_null() {
+ return 0;
+ }
+
+ const char *get_null(const char *a) {
+ return a == 0 ? a : "non-null";
+ }
+%}
+#endif
diff --git a/Examples/test-suite/csharp/cpp17_string_view_runme.cs b/Examples/test-suite/csharp/cpp17_string_view_runme.cs
new file mode 100644
index 000000000..eba25f4de
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp17_string_view_runme.cs
@@ -0,0 +1,84 @@
+using System;
+using cpp17_string_viewNamespace;
+
+public class runme
+{
+ static void Main()
+ {
+ // Checking expected use of %typemap(in) std::string {}
+ cpp17_string_view.test_value("Fee");
+
+ // Checking expected result of %typemap(out) std::string {}
+ if (cpp17_string_view.test_value("Fi") != "Fi")
+ throw new Exception("Test 1 failed");
+
+ // Verify type-checking for %typemap(in) std::string {}
+ try {
+ cpp17_string_view.test_value(null);
+ throw new Exception("Test 2 failed");
+ } catch (ArgumentNullException) {
+ }
+
+ // Checking expected use of %typemap(in) const std::string & {}
+ cpp17_string_view.test_const_reference("Fo");
+
+ // Checking expected result of %typemap(out) const std::string& {}
+ if (cpp17_string_view.test_const_reference("Fum") != "Fum")
+ throw new Exception("Test 3 failed");
+
+ // Verify type-checking for %typemap(in) const std::string & {}
+ try {
+ cpp17_string_view.test_const_reference(null);
+ throw new Exception("Test 4 failed");
+ } catch (ArgumentNullException) {
+ }
+
+ //
+ // Input and output typemaps for pointers and non-const references to
+ // std::string are *not* supported; the following tests confirm
+ // that none of these cases are slipping through.
+ //
+
+ SWIGTYPE_p_std__string_view stringPtr = null;
+
+ stringPtr = cpp17_string_view.test_pointer_out();
+
+ cpp17_string_view.test_pointer(stringPtr);
+
+ stringPtr = cpp17_string_view.test_const_pointer_out();
+
+ cpp17_string_view.test_const_pointer(stringPtr);
+
+ stringPtr = cpp17_string_view.test_reference_out();
+
+ cpp17_string_view.test_reference(stringPtr);
+
+ // Check throw exception specification
+ try {
+ cpp17_string_view.test_throw();
+ throw new Exception("Test 5 failed");
+ } catch (ApplicationException e) {
+ if (e.Message != "test_throw message")
+ throw new Exception("Test 5 string check: " + e.Message);
+ }
+ try {
+ cpp17_string_view.test_const_reference_throw();
+ throw new Exception("Test 6 failed");
+ } catch (ApplicationException e) {
+ if (e.Message != "test_const_reference_throw message")
+ throw new Exception("Test 6 string check: " + e.Message);
+ }
+
+ // Global variables
+ if (cpp17_string_view.ConstGlobalString != "const global string")
+ throw new Exception("ConstGlobalString test");
+
+ // Member variables
+ Structure myStructure = new Structure();
+ if (myStructure.ConstMemberString != "const member string")
+ throw new Exception("ConstMemberString test");
+
+ if (Structure.ConstStaticMemberString != "const static member string")
+ throw new Exception("ConstStaticMemberString test");
+ }
+}
diff --git a/Examples/test-suite/csharp/director_string_view_runme.cs b/Examples/test-suite/csharp/director_string_view_runme.cs
new file mode 100644
index 000000000..7060b28a8
--- /dev/null
+++ b/Examples/test-suite/csharp/director_string_view_runme.cs
@@ -0,0 +1,52 @@
+using System;
+using director_string_viewNamespace;
+
+public class runme
+{
+ static void Main()
+ {
+ runme r = new runme();
+ r.run();
+ }
+
+ void run()
+ {
+ String s;
+
+ director_string_view_A c = new director_string_view_A("hi");
+ for (int i=0; i<3; i++) {
+ s = c.call_get(i);
+ Object ii = i;
+ if (s != ii.ToString()) throw new Exception("director_string_view_A.get(" + i + ") failed. Got:" + s);
+ }
+
+ director_string_view_B b = new director_string_view_B("hello");
+
+ s = b.call_get_first();
+ if (s != "director_string_view_B.get_first") throw new Exception("call_get_first() failed");
+
+ s = b.call_get(0);
+ if (s != "director_string_view_B.get: hello") throw new Exception("get(0) failed");
+ }
+}
+
+class director_string_view_B : A {
+ public director_string_view_B(String first) : base(first) {
+ }
+ public override String get_first() {
+ return "director_string_view_B.get_first";
+ }
+
+ public override String get(int n) {
+ return "director_string_view_B.get: " + base.get(n);
+ }
+}
+
+class director_string_view_A : A {
+ public director_string_view_A(String first) : base(first) {
+ }
+ public override String get(int n) {
+ Object nn = n;
+ return nn.ToString();
+ }
+}
diff --git a/Examples/test-suite/director_string_view.i b/Examples/test-suite/director_string_view.i
new file mode 100644
index 000000000..19c2dbf01
--- /dev/null
+++ b/Examples/test-suite/director_string_view.i
@@ -0,0 +1,56 @@
+%module(directors="1") director_string_view;
+
+#if defined SWIGCSHARP || defined SWIGJAVA || defined SWIGLUA || defined SWIGPHP
+
+%include std_string.i
+%include std_string_view.i
+
+// Using thread unsafe wrapping
+%warnfilter(SWIGWARN_TYPEMAP_THREAD_UNSAFE,SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) A;
+
+%{
+#include <vector>
+#include <string>
+#include <string_view>
+%}
+
+%feature("director") A;
+%inline %{
+
+struct A
+{
+ A(const std::string& first)
+ : m_strings(1, first)
+ {}
+
+ virtual ~A() {}
+
+ virtual std::string_view get_first() const
+ { return get(0); }
+
+ virtual std::string_view get(int n) const
+ { return m_strings[n]; }
+
+ virtual std::string_view call_get_first() const
+ { return get_first(); }
+
+ virtual std::string_view call_get(int n) const
+ { return get(n); }
+
+ virtual int string_length(std::string_view s) const
+ { return (int)s.size(); }
+
+
+ virtual void process_text(const char *text)
+ {
+ }
+
+ void call_process_func() { process_text("hello"); }
+
+private:
+ std::vector<std::string> m_strings;
+};
+
+%}
+
+#endif
diff --git a/Examples/test-suite/java/cpp17_string_view_runme.java b/Examples/test-suite/java/cpp17_string_view_runme.java
new file mode 100644
index 000000000..903970e39
--- /dev/null
+++ b/Examples/test-suite/java/cpp17_string_view_runme.java
@@ -0,0 +1,92 @@
+import cpp17_string_view.*;
+
+public class cpp17_string_view_runme {
+
+ static {
+ try {
+ System.loadLibrary("cpp17_string_view");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) throws Throwable
+ {
+ // Checking expected use of %typemap(in) std::string_view {}
+ cpp17_string_view.test_value("Fee");
+
+ // Checking expected result of %typemap(out) std::string_view {}
+ if (!cpp17_string_view.test_value("Fi").equals("Fi"))
+ throw new RuntimeException("Test 1 failed");
+
+ // Verify type-checking for %typemap(in) std::string_view {}
+ try {
+ cpp17_string_view.test_value(null);
+ throw new RuntimeException("Test 2 failed");
+ } catch (NullPointerException e) {
+ }
+
+ // Checking expected use of %typemap(in) const std::string_view & {}
+ cpp17_string_view.test_const_reference("Fo");
+
+ // Checking expected result of %typemap(out) const std::string_view& {}
+ if (!cpp17_string_view.test_const_reference("Fum").equals("Fum"))
+ throw new RuntimeException("Test 3 failed");
+
+ // Verify type-checking for %typemap(in) const std::string_view & {}
+ try {
+ cpp17_string_view.test_const_reference(null);
+ throw new RuntimeException("Test 4 failed");
+ } catch (NullPointerException e) {
+ }
+
+ //
+ // Input and output typemaps for pointers and non-const references to
+ // std::string_view are *not* supported; the following tests confirm
+ // that none of these cases are slipping through.
+ //
+
+ SWIGTYPE_p_std__string_view stringPtr = null;
+
+ stringPtr = cpp17_string_view.test_pointer_out();
+
+ cpp17_string_view.test_pointer(stringPtr);
+
+ stringPtr = cpp17_string_view.test_const_pointer_out();
+
+ cpp17_string_view.test_const_pointer(stringPtr);
+
+ stringPtr = cpp17_string_view.test_reference_out();
+
+ cpp17_string_view.test_reference(stringPtr);
+
+ // Check throw exception specification
+ try {
+ cpp17_string_view.test_throw();
+ throw new Throwable("Test 5 failed");
+ } catch (RuntimeException e) {
+ if (!e.getMessage().equals("test_throw message"))
+ throw new Exception("Test 5 string check: " + e.getMessage());
+ }
+ try {
+ cpp17_string_view.test_const_reference_throw();
+ throw new Throwable("Test 6 failed");
+ } catch (RuntimeException e) {
+ if (!e.getMessage().equals("test_const_reference_throw message"))
+ throw new Exception("Test 6 string check: " + e.getMessage());
+ }
+
+ // Global variables
+ if (!cpp17_string_view.getConstGlobalString().equals("const global string"))
+ throw new Exception("ConstGlobalString test");
+
+ // Member variables
+ Structure myStructure = new Structure();
+ if (!myStructure.getConstMemberString().equals("const member string"))
+ throw new Exception("ConstMemberString test");
+
+ if (!Structure.getConstStaticMemberString().equals("const static member string"))
+ throw new Exception("ConstStaticMemberString test");
+ }
+}
diff --git a/Examples/test-suite/java/director_string_view_runme.java b/Examples/test-suite/java/director_string_view_runme.java
new file mode 100644
index 000000000..7aabf7d96
--- /dev/null
+++ b/Examples/test-suite/java/director_string_view_runme.java
@@ -0,0 +1,55 @@
+
+import director_string_view.*;
+
+public class director_string_view_runme {
+
+ static {
+ try {
+ System.loadLibrary("director_string_view");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+
+ String s;
+
+ director_string_view_A c = new director_string_view_A("hi");
+ for (int i=0; i<3; i++) {
+ s = c.call_get(i);
+ if (!s.equals(Integer.valueOf(i).toString())) throw new RuntimeException("director_string_view_A.get(" + i + ") failed. Got:" + s);
+ }
+
+ director_string_view_B b = new director_string_view_B("hello");
+
+ s = b.call_get_first();
+ if (!s.equals("director_string_view_B.get_first")) throw new RuntimeException("call_get_first() failed");
+
+ s = b.call_get(0);
+ if (!s.equals("director_string_view_B.get: hello")) throw new RuntimeException("get(0) failed");
+ }
+}
+
+class director_string_view_B extends A {
+ public director_string_view_B(String first) {
+ super(first);
+ }
+ public String get_first() {
+ return "director_string_view_B.get_first";
+ }
+
+ public String get(int n) {
+ return "director_string_view_B.get: " + super.get(n);
+ }
+}
+
+class director_string_view_A extends A {
+ public director_string_view_A(String first) {
+ super(first);
+ }
+ public String get(int n) {
+ return Integer.valueOf(n).toString();
+ }
+}
diff --git a/Examples/test-suite/lua/cpp17_string_view_runme.lua b/Examples/test-suite/lua/cpp17_string_view_runme.lua
new file mode 100644
index 000000000..b30d99273
--- /dev/null
+++ b/Examples/test-suite/lua/cpp17_string_view_runme.lua
@@ -0,0 +1,50 @@
+require("import") -- the import fn
+import("cpp17_string_view") -- import lib
+
+for k,v in pairs(cpp17_string_view) do _G[k]=v end -- move to global
+
+-- 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})
+
+-- Checking expected use of %typemap(in) std::string_view {}
+test_value("Fee")
+
+-- Checking expected result of %typemap(out) std::string_view {}
+s=test_value("Fi")
+assert(type(s)=="string" and s =="Fi")
+
+-- Checking expected use of %typemap(in) const std::string_view & {}
+test_const_reference("Fo")
+
+-- Checking expected result of %typemap(out) const std::string_view& {}
+s=test_const_reference("Fum")
+assert(type(s)=="string" and s =="Fum")
+
+-- Input and output typemaps for pointers and non-const references to
+-- std::string_view are *not* supported; the following tests confirm
+-- that none of these cases are slipping through.
+
+stringPtr = test_pointer_out()
+
+test_pointer(stringPtr)
+
+stringPtr = test_const_pointer_out()
+
+test_const_pointer(stringPtr)
+
+stringPtr = test_reference_out()
+
+test_reference(stringPtr)
+
+-- Global variables
+assert(cpp17_string_view.ConstGlobalString=="const global string")
+
+-- Member variables
+myStructure = Structure()
+assert(myStructure.ConstMemberString=="const member string")
+
+assert(Structure.ConstStaticMemberString=="const static member string")
+
+test_const_reference_returning_void("foo")
diff --git a/Examples/test-suite/php/cpp17_string_view_runme.php b/Examples/test-suite/php/cpp17_string_view_runme.php
new file mode 100644
index 000000000..5f756bb36
--- /dev/null
+++ b/Examples/test-suite/php/cpp17_string_view_runme.php
@@ -0,0 +1,44 @@
+<?php
+
+require "tests.php";
+
+# Checking expected use of %typemap(in) std::string_view {}
+cpp17_string_view::test_value("Fee");
+
+# Checking expected result of %typemap(out) std::string_view {}
+check::equal(cpp17_string_view::test_value("Fi"), "Fi", "Test 1");
+
+# Checking expected use of %typemap(in) const std::string_view & {}
+cpp17_string_view::test_const_reference("Fo");
+
+# Checking expected result of %typemap(out) const std::string_view& {}
+check::equal(cpp17_string_view::test_const_reference("Fum"), "Fum", "Test 3");
+
+# Input and output typemaps for pointers and non-const references to
+# std::string_view are *not* supported; the following tests confirm
+# that none of these cases are slipping through.
+
+$stringPtr = cpp17_string_view::test_pointer_out();
+
+cpp17_string_view::test_pointer($stringPtr);
+
+$stringPtr = cpp17_string_view::test_const_pointer_out();
+
+cpp17_string_view::test_const_pointer($stringPtr);
+
+$stringPtr = cpp17_string_view::test_reference_out();
+
+cpp17_string_view::test_reference($stringPtr);
+
+// Global variables
+check::equal(ConstGlobalString_get(), "const global string", "ConstGlobalString test");
+
+// Member variables
+$myStructure = new Structure();
+check::equal($myStructure->ConstMemberString, "const member string", "ConstMemberString test");
+
+check::equal(Structure::ConstStaticMemberString(), "const static member string", "ConstStaticMemberString test");
+
+cpp17_string_view::test_const_reference_returning_void("foo");
+
+check::done();
diff --git a/Examples/test-suite/php/director_string_view_runme.php b/Examples/test-suite/php/director_string_view_runme.php
new file mode 100644
index 000000000..ae3c10d11
--- /dev/null
+++ b/Examples/test-suite/php/director_string_view_runme.php
@@ -0,0 +1,34 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+// New classes
+check::classes(array('A'));
+// No new vars
+check::globals(array());
+
+class B extends A {
+ public $smem;
+
+ function get_first() {
+ return parent::get_first() . " world!";
+ }
+
+ function process_text($string) {
+ parent::process_text($string);
+ $this->smem = "hello";
+ }
+}
+
+$b = new B("hello");
+
+$b->get(0);
+check::equal($b->get_first(),"hello world!", "get_first failed");
+
+$b->call_process_func();
+
+check::equal($b->smem, "hello", "smem failed");
+
+check::done();