summaryrefslogtreecommitdiff
path: root/Lib
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 /Lib
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 'Lib')
-rw-r--r--Lib/csharp/std_string_view.i113
-rw-r--r--Lib/java/std_string_view.i138
-rw-r--r--Lib/lua/std_string_view.i41
-rw-r--r--Lib/php/std_string_view.i69
-rw-r--r--Lib/swig.swg5
5 files changed, 366 insertions, 0 deletions
diff --git a/Lib/csharp/std_string_view.i b/Lib/csharp/std_string_view.i
new file mode 100644
index 000000000..b03c8461a
--- /dev/null
+++ b/Lib/csharp/std_string_view.i
@@ -0,0 +1,113 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * Typemaps for std::string_view and const std::string_view&
+ * These are mapped to a C# String and are passed around by value.
+ *
+ * To use non-const std::string_view references use the following %apply. Note
+ * that they are passed by value.
+ * %apply const std::string_view & {std::string_view &};
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <string_view>
+#include <string>
+%}
+
+namespace std {
+
+%naturalvar string_view;
+
+class string_view;
+
+// string_view
+%typemap(ctype) string_view "const char *"
+%typemap(imtype) string_view "string"
+%typemap(cstype) string_view "string"
+
+%typemap(csdirectorin) string_view "$iminput"
+%typemap(csdirectorout) string_view "$cscall"
+
+%typemap(in, canthrow=1) string_view
+%{ if (!$input) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+ return $null;
+ }
+ $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
+%{ if (!$input) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+ return $null;
+ }
+ $result = std::string_view($input); %}
+
+%typemap(directorin) string_view %{ $input = std::string($1).c_str(); %}
+
+%typemap(csin) string_view "$csinput"
+%typemap(csout, excode=SWIGEXCODE) string_view {
+ string ret = $imcall;$excode
+ return ret;
+ }
+
+%typemap(typecheck) string_view = char *;
+
+%typemap(throws, canthrow=1) string_view
+%{ SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, std::string($1).c_str());
+ return $null; %}
+
+// const string_view &
+%typemap(ctype) const string_view & "const char *"
+%typemap(imtype) const string_view & "string"
+%typemap(cstype) const string_view & "string"
+
+%typemap(csdirectorin) const string_view & "$iminput"
+%typemap(csdirectorout) const string_view & "$cscall"
+
+%typemap(in, canthrow=1) const string_view &
+%{ if (!$input) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+ return $null;
+ }
+ $*1_ltype $1_str($input);
+ $1 = &$1_str; %}
+%typemap(out) const string_view & %{ $result = SWIG_csharp_string_callback(std::string(*$1).c_str()); %}
+
+%typemap(csin) const string_view & "$csinput"
+%typemap(csout, excode=SWIGEXCODE) const string_view & {
+ string ret = $imcall;$excode
+ return ret;
+ }
+
+%typemap(directorout, canthrow=1, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const string_view &
+%{ if (!$input) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+ return $null;
+ }
+ /* possible thread/reentrant code problem */
+ static std::string $1_str;
+ $1_str = $input;
+ static $*1_ltype $1_strview;
+ $1_strview = $1_str;
+ $result = &$1_strview; %}
+
+%typemap(directorin) const string_view & %{ $input = std::string($1).c_str(); %}
+
+%typemap(csvarin, excode=SWIGEXCODE2) const string_view & %{
+ set {
+ $imcall;$excode
+ } %}
+%typemap(csvarout, excode=SWIGEXCODE2) const string_view & %{
+ get {
+ string ret = $imcall;$excode
+ return ret;
+ } %}
+
+%typemap(typecheck) const string_view & = char *;
+
+%typemap(throws, canthrow=1) const string_view &
+%{ SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, std::string($1).c_str());
+ return $null; %}
+
+}
diff --git a/Lib/java/std_string_view.i b/Lib/java/std_string_view.i
new file mode 100644
index 000000000..005b9c0f8
--- /dev/null
+++ b/Lib/java/std_string_view.i
@@ -0,0 +1,138 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * Typemaps for std::string_view and const std::string_view&
+ * These are mapped to a Java String and are passed around by value.
+ *
+ * To use non-const std::string_view references use the following %apply. Note
+ * that they are passed by value.
+ * %apply const std::string_view & {std::string_view &};
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <string_view>
+#include <string>
+%}
+
+namespace std {
+
+%naturalvar string_view;
+
+class string_view;
+
+// string_view
+%typemap(jni) string_view "jstring"
+%typemap(jtype) string_view "String"
+%typemap(jstype) string_view "String"
+%typemap(javadirectorin) string_view "$jniinput"
+%typemap(javadirectorout) string_view "$javacall"
+
+%typemap(in) string_view
+%{ if(!$input) {
+ SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string");
+ return $null;
+ }
+ const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0);
+ if (!$1_pstr) return $null;
+ $1 = std::string_view($1_pstr); %}
+
+/* std::string_view requires the string data to remain valid while the
+ * string_view is in use. */
+%typemap(freearg) string_view
+%{ jenv->ReleaseStringUTFChars($input, $1_pstr); %}
+
+%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) string_view
+%{ if(!$input) {
+ if (!jenv->ExceptionCheck()) {
+ SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string");
+ }
+ return $null;
+ }
+ const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0);
+ if (!$1_pstr) return $null;
+ /* possible thread/reentrant code problem */
+ static std::string $1_str;
+ $1_str = $1_pstr;
+ $result = std::string_view($1_str);
+ jenv->ReleaseStringUTFChars($input, $1_pstr); %}
+
+/* std::string_view::data() isn't zero-byte terminated, but NewStringUTF()
+ * requires a zero byte so it seems we have to make a copy (ick). The
+ * cleanest way to do that seems to be via a temporary std::string.
+ */
+%typemap(directorin,descriptor="Ljava/lang/String;") string_view
+%{ $input = jenv->NewStringUTF(std::string($1).c_str());
+ Swig::LocalRefGuard $1_refguard(jenv, $input); %}
+
+%typemap(out) string_view
+%{ $result = jenv->NewStringUTF(std::string($1).c_str()); %}
+
+%typemap(javain) string_view "$javainput"
+
+%typemap(javaout) string_view {
+ return $jnicall;
+ }
+
+%typemap(typecheck) string_view = char *;
+
+%typemap(throws) string_view
+%{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string($1).c_str());
+ return $null; %}
+
+// const string_view &
+%typemap(jni) const string_view & "jstring"
+%typemap(jtype) const string_view & "String"
+%typemap(jstype) const string_view & "String"
+%typemap(javadirectorin) const string_view & "$jniinput"
+%typemap(javadirectorout) const string_view & "$javacall"
+
+%typemap(in) const string_view &
+%{ if(!$input) {
+ SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string");
+ return $null;
+ }
+ const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0);
+ if (!$1_pstr) return $null;
+ $*1_ltype $1_str($1_pstr);
+ $1 = &$1_str; %}
+
+/* std::string_view requires the string data to remain valid while the
+ * string_view is in use. */
+%typemap(freearg) const string_view &
+%{ jenv->ReleaseStringUTFChars($input, $1_pstr); %}
+
+%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const string_view &
+%{ if(!$input) {
+ SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string");
+ return $null;
+ }
+ const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0);
+ if (!$1_pstr) return $null;
+ /* possible thread/reentrant code problem */
+ static std::string $1_str;
+ $1_str = $1_pstr;
+ static $*1_ltype $1_strview;
+ $1_strview = $1_str;
+ $result = &$1_str;
+ jenv->ReleaseStringUTFChars($input, $1_pstr); %}
+
+%typemap(directorin,descriptor="Ljava/lang/String;") const string_view &
+%{ $input = jenv->NewStringUTF(std::string($1).c_str());
+ Swig::LocalRefGuard $1_refguard(jenv, $input); %}
+
+%typemap(out) const string_view &
+%{ $result = jenv->NewStringUTF(std::string(*$1).c_str()); %}
+
+%typemap(javain) const string_view & "$javainput"
+
+%typemap(javaout) const string_view & {
+ return $jnicall;
+ }
+
+%typemap(typecheck) const string_view & = char *;
+
+%typemap(throws) const string_view &
+%{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string($1).c_str());
+ return $null; %}
+
+}
diff --git a/Lib/lua/std_string_view.i b/Lib/lua/std_string_view.i
new file mode 100644
index 000000000..f2a439eaa
--- /dev/null
+++ b/Lib/lua/std_string_view.i
@@ -0,0 +1,41 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * std::string_view typemaps for LUA
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <string_view>
+%}
+
+namespace std {
+
+%naturalvar string_view;
+
+%typemap(in,checkfn="lua_isstring") string_view
+%{$1 = std::string_view(lua_tostring(L,$input),lua_rawlen(L,$input));%}
+
+%typemap(out) string_view
+%{ lua_pushlstring(L,$1.data(),$1.size()); SWIG_arg++;%}
+
+%typemap(in,checkfn="lua_isstring") const string_view& ($*1_ltype temp)
+%{temp = std::string_view(lua_tostring(L,$input),lua_rawlen(L,$input)); $1=&temp;%}
+
+%typemap(out) const string_view&
+%{ lua_pushlstring(L,$1->data(),$1->size()); SWIG_arg++;%}
+
+// for throwing of any kind of string_view, string_view ref's and string_view pointers
+// we convert all to lua strings
+%typemap(throws) string_view, string_view&, const string_view&
+%{ lua_pushlstring(L,$1.data(),$1.size()); SWIG_fail;%}
+
+%typemap(throws) string_view*, const string_view*
+%{ lua_pushlstring(L,$1->data(),$1->size()); SWIG_fail;%}
+
+%typecheck(SWIG_TYPECHECK_STRINGVIEW) string_view, const string_view& {
+ $1 = lua_isstring(L,$input);
+}
+
+class string_view;
+
+}
diff --git a/Lib/php/std_string_view.i b/Lib/php/std_string_view.i
new file mode 100644
index 000000000..7f53f9e22
--- /dev/null
+++ b/Lib/php/std_string_view.i
@@ -0,0 +1,69 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * SWIG typemaps for std::string_view types
+ * ----------------------------------------------------------------------------- */
+
+%include <exception.i>
+
+%{
+#include <string_view>
+%}
+
+namespace std {
+
+ %naturalvar string_view;
+
+ class string_view;
+
+ %typemap(typecheck,precedence=SWIG_TYPECHECK_STRINGVIEW) string_view, const string_view& %{
+ $1 = (Z_TYPE($input) == IS_STRING) ? 1 : 0;
+ %}
+
+ %typemap(in, phptype="string") string_view %{
+ convert_to_string(&$input);
+ $1 = std::string_view(Z_STRVAL($input), Z_STRLEN($input));
+ %}
+
+ %typemap(directorout) string_view %{
+ convert_to_string($input);
+ $result = std::string_view(Z_STRVAL_P($input), Z_STRLEN_P($input));
+ %}
+
+ %typemap(out, phptype="string") string_view %{
+ ZVAL_STRINGL($result, $1.data(), $1.size());
+ %}
+
+ %typemap(directorin) string_view, const string_view& %{
+ ZVAL_STRINGL($input, $1.data(), $1.size());
+ %}
+
+ %typemap(out, phptype="string") const string_view& %{
+ ZVAL_STRINGL($result, $1->data(), $1->size());
+ %}
+
+ %typemap(throws) string_view, const string_view& %{
+ {
+ zval swig_exception;
+ ZVAL_STRINGL(&swig_exception, $1.data(), $1.size());
+ zend_throw_exception_object(&swig_exception);
+ goto fail;
+ }
+ %}
+
+ %typemap(throws) string_view*, const string_view* %{
+ {
+ zval swig_exception;
+ ZVAL_STRINGL(&swig_exception, $1->data(), $1->size());
+ zend_throw_exception_object(&swig_exception);
+ goto fail;
+ }
+ %}
+
+ %typemap(in, phptype="string") const string_view& ($*1_ltype temp) %{
+ convert_to_string(&$input);
+ temp = std::string_view(Z_STRVAL($input), Z_STRLEN($input));
+ $1 = &temp;
+ %}
+
+}
diff --git a/Lib/swig.swg b/Lib/swig.swg
index f904f53c6..696dc8145 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -361,6 +361,11 @@ static int NAME(TYPE x) {
%define SWIG_TYPECHECK_STDUNISTRING 115 %enddef
%define SWIG_TYPECHECK_UNISTRING 120 %enddef
%define SWIG_TYPECHECK_CHAR 130 %enddef
+/* Give std::string_view a slightly higher precedence because if there are
+ * overloaded forms then it may be more efficient to pass as std::string_view
+ * (e.g. to pass as std::string requires copying the data into a std::string).
+ */
+%define SWIG_TYPECHECK_STRINGVIEW 134 %enddef
%define SWIG_TYPECHECK_STDSTRING 135 %enddef
%define SWIG_TYPECHECK_STRING 140 %enddef
%define SWIG_TYPECHECK_PAIR 150 %enddef