Merge branch 'restore-compat-wrappers-names' into C

Merge with the latest master including PR #2371.
This commit is contained in:
Vadim Zeitlin 2022-09-17 14:36:37 +02:00
commit 864f32159a
851 changed files with 21837 additions and 7327 deletions

View file

@ -46,8 +46,8 @@ TARGET =
CC = @CC@
CXX = @CXX@
CPPFLAGS = $(SRCDIR_INCLUDE)
CFLAGS = @PLATCFLAGS@
CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@
CFLAGS = @PLATCFLAGS@ $(EXTRA_CFLAGS)
CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ $(EXTRA_CXXFLAGS)
LDFLAGS =
prefix = @prefix@
exec_prefix= @exec_prefix@
@ -191,7 +191,7 @@ tcl: $(SRCDIR_SRCS)
$(TCLLDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO) $(TCL_LINK)
# -----------------------------------------------------------
# Build a Tcl7.5 dynamic loadable module for C++
# Build a Tcl dynamic loadable module for C++
# -----------------------------------------------------------
tcl_cpp: $(SRCDIR_SRCS)
@ -309,7 +309,7 @@ perl5_clean:
PYTHON_FLAGS =
# Make sure these locate your Python installation
ifeq (,$(PY3))
ifneq (,$(PY2))
PYTHON_INCLUDE= $(DEFS) @PYINCLUDE@
PYTHON_LIB = @PYLIB@
PYTHON = @PYTHON@ $(PYTHON_FLAGS)
@ -320,7 +320,7 @@ else
endif
# Extra Python specific linking options
ifeq (,$(PY3))
ifneq (,$(PY2))
PYTHON_DLNK = @PYTHONDYNAMICLINKING@
PYTHON_LINK = @PYLINK@
else
@ -329,13 +329,6 @@ else
endif
PYTHON_SO = @PYTHON_SO@
# SWIG option for Python3
ifeq (,$(PY3))
SWIGOPTPY3 =
else
SWIGOPTPY3 = -py3
endif
PYCODESTYLE = @PYCODESTYLE@
PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,W291,W391
@ -344,7 +337,7 @@ PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,W291,W391
# ----------------------------------------------------------------
python: $(SRCDIR_SRCS)
$(SWIG) -python $(SWIGOPTPY3) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(SWIG) -python $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(PYTHON_INCLUDE)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
@ -353,7 +346,7 @@ python: $(SRCDIR_SRCS)
# -----------------------------------------------------------------
python_cpp: $(SRCDIR_SRCS)
$(SWIG) -python $(SWIGOPTPY3) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(SWIG) -python -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE)
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
@ -369,12 +362,12 @@ TKINTER =
PYTHON_LIBOPTS = $(PYTHON_LINK) @LIBS@ $(TKINTER) $(SYSLIBS)
python_static: $(SRCDIR_SRCS)
$(SWIG) -python $(SWIGOPTPY3) -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(SWIG) -python -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
python_static_cpp: $(SRCDIR_SRCS)
$(SWIG) -python $(SWIGOPTPY3) -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(SWIG) -python -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
@ -744,9 +737,9 @@ ifeq (node, $(ENGINE))
endif
ifeq (jsc, $(ENGINE))
@if [ "@JSCOREVERSION@" != "" ]; then \
echo "@JSCOREVERSION@"; \
echo "JavaScriptCore: @JSCOREVERSION@"; \
else \
echo "Unknown JavascriptCore version."; \
echo "Unknown JavaScriptCore version."; \
fi
endif
ifeq (v8, $(ENGINE))
@ -1078,7 +1071,7 @@ php_cpp: $(SRCDIR_SRCS)
# -----------------------------------------------------------------
php_run:
$(RUNTOOL) $(PHP) -n -d extension_dir=. -d extension=$(PHP_EXTENSION) -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});include($$argv[1]);' $(PHP_SCRIPT) $(RUNPIPE)
$(RUNTOOL) $(PHP) -n -d extension_dir=. -d extension=$(PHP_EXTENSION) -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});if(strlen($$argv[1]))include($$argv[1]);' '$(PHP_SCRIPT)' $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
@ -1423,6 +1416,7 @@ c_clean:
SCILAB = @SCILAB@
SCILAB_INC= @SCILABINCLUDE@
SCILAB_OPT = @SCILABOPT@
SCILAB_VERSION = @SCILAB_VERSION@
SCILAB_LIBPREFIX = lib
# ----------------------------------------------------------------
@ -1455,7 +1449,7 @@ scilab_run:
# -----------------------------------------------------------------
scilab_version:
echo `$(SCILAB) -version | head -1`
echo `$(SCILAB) -nwni -version | head -1`
# -----------------------------------------------------------------
# Cleaning the scilab examples
@ -1537,6 +1531,10 @@ go: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
CGO_LDFLAGS="$(LDFLAGS) -lm"; \
export CGO_LDFLAGS; \
(cd $(GOPATHDIR)/ && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o $(GOPACKAGE)); \
stat=$$?; \
if test $$stat != 0; then \
exit $$stat; \
fi; \
if $(GOGCC); then \
cp $(GOPATHDIR)/$(GOPACKAGE) $(GOPATHDIR)/$(GOPACKAGE:.a=.gox); \
fi; \
@ -1545,6 +1543,10 @@ go: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
mkdir gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=) 2>/dev/null || true; \
cp $(GOPATHDIR)/* gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=)/; \
(cd gopath/$(GOMOD)/src/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme $(RUNME).go); \
stat=$$?; \
if test $$stat != 0; then \
exit $$stat; \
fi; \
cp gopath/$(GOMOD)/src/runme/runme $(RUNME); \
fi
@ -1588,6 +1590,10 @@ go_cpp: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
CGO_LDFLAGS="$(LDFLAGS) -lm"; \
export CGO_LDFLAGS; \
(cd $(GOPATHDIR) && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o $(GOPACKAGE)); \
stat=$$?; \
if test $$stat != 0; then \
exit $$stat; \
fi; \
if $(GOGCC); then \
cp $(GOPATHDIR)/$(GOPACKAGE) $(GOPATHDIR)/$(GOPACKAGE:.a=.gox); \
fi; \
@ -1596,6 +1602,10 @@ go_cpp: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
mkdir gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=) 2>/dev/null || true; \
cp $(GOPATHDIR)/* gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=)/; \
(cd gopath/$(GOMOD)/src/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme $(RUNME).go); \
stat=$$?; \
if test $$stat != 0; then \
exit $$stat; \
fi; \
cp gopath/$(GOMOD)/src/runme/runme $(RUNME); \
fi
@ -1682,8 +1692,7 @@ d_run:
# -----------------------------------------------------------------
d_version:
# Needs improvement!
echo D version guess - $(D_VERSION)
($(DCOMPILER) --version 2> /dev/null || $(DCOMPILER)) | head -n 3
# -----------------------------------------------------------------
# Clean the D examples

View file

@ -12,3 +12,4 @@ reference
simple
template
variables
goin

18
Examples/go/goin/Makefile Normal file
View file

@ -0,0 +1,18 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS =
TARGET = example
INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' INTERFACE='$(INTERFACE)' go_clean

106
Examples/go/goin/example.i Normal file
View file

@ -0,0 +1,106 @@
%module(directors="1") example
%inline %{
// Helper functions for converting string arrays
#include <stdlib.h>
void *alloc_ptr_array(unsigned int len)
{
return calloc(len, sizeof(void *));
}
void set_ptr_array(void *ain, unsigned int pos, void *val)
{
void **a = (void **) ain;
a[pos] = val;
}
void *get_ptr_array(void *ain, unsigned int pos)
{
void **a = (void **) ain;
return a[pos];
}
void free_ptr_array(void *ain)
{
void **a = (void **) ain;
unsigned int i;
if (!a)
return;
for (i = 0; a[i]; i++) {
free(a[i]);
}
free(a);
}
char *uintptr_to_string(void *in)
{
return (char *) in;
}
void *string_to_uintptr(char *in)
{
return strdup(in);
}
%}
// These typemaps convert between an array of strings in Go and a
// const char** that is NULL terminated in C++.
%typemap(gotype) (const char * const *) "[]string"
%typemap(imtype) (const char * const *) "uintptr"
%typemap(goin) (const char * const *) {
if $input == nil || len($input) == 0 {
$result = 0
} else {
$result = Alloc_ptr_array(uint(len($input) + 1))
defer func() {
Free_ptr_array($result)
}()
var i uint
for i = 0; i < uint(len($input)); i++ {
Set_ptr_array($result, i, String_to_uintptr($input[i]))
}
}
}
%typemap(in) (const char * const *) {
$1 = (char **) $input;
}
%typemap(godirectorin) (const char * const *) {
if ($input == 0) {
$result = nil
} else {
var i uint
for i = 0; ; i++ {
var v uintptr = Get_ptr_array($input, i)
if v == 0 {
break
}
}
if i == 0 {
$result = nil
} else {
$result = make([]string, i)
for i = 0; ; i++ {
var v uintptr = Get_ptr_array($input, i)
if v == 0 {
break
}
$result[i] = Uintptr_to_string(v)
}
}
}
}
%feature("director") callbacks;
%inline %{
class callbacks {
public:
virtual bool call1(int v, const char * const *strarray);
virtual ~callbacks() {}
};
bool check1(callbacks *c, int v, const char * const *strarray) {
return c->call1(v, strarray);
}
bool callbacks::call1(int v, const char * const *strarray) {
return false;
}
%}

View file

@ -0,0 +1,26 @@
<html>
<head>
<title>SWIG:Examples:go:going</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/go/goin/</tt>
<hr>
<H2>Example of using goin and godirectorin</H2>
<p>
This example converts between a Go []string and a "const char * const *"
in C/C++. It does this for a director and for a normal call.
<p>
<ul>
<li><a href="example.i">example.i</a>. SWIG interface file.
<li><a href="runme.go">runme.go</a>. Sample Go program.
</ul>
<hr>
</body>
</html>

38
Examples/go/goin/runme.go Normal file
View file

@ -0,0 +1,38 @@
package main
import (
"fmt"
"swigtests/example"
)
type mycallbacks struct {
example.Callbacks
}
var tststrs = []string{ "A", "BCD", "EFGH" }
var tstint int = 5
func (v *mycallbacks) Call1(val int, strarray []string) bool {
var rv bool = true
for i, s := range strarray {
fmt.Printf("%d: %s\n", i, s)
if s != tststrs[i] {
fmt.Printf(" ***Mismatch, expected %s\n", tststrs[i])
rv = false
}
}
if val != tstint {
rv = false
}
return rv
}
func main() {
cbs := &mycallbacks{}
cbs.Callbacks = example.NewDirectorCallbacks(cbs)
worked := example.Check1(cbs, tstint, tststrs)
if !worked {
panic("Data mismatch")
}
}

View file

@ -24,6 +24,7 @@ certain C declarations are turned into constants.
<li><a href="callback/index.html">callback</a>. C++ callbacks using directors.
<li><a href="extend/index.html">extend</a>. Polymorphism using directors.
<li><a href="director/index.html">director</a>. Example how to utilize the director feature.
<li><a href="goin/index.html">director</a>. Example how to use goin and godirectorin.
</ul>
<h2>Compilation Issues</h2>

View file

@ -78,7 +78,7 @@ extern int count(char *bytes, int len, char c);
%typemap(argout) (char *str, int len) {
SWIG_APPEND_VALUE(scm_from_locale_stringn($1,$2));
if ($1) SWIG_free($1);
SWIG_free($1);
}
extern void capitalize(char *str, int len);

View file

@ -1,5 +1,5 @@
#ifndef _example_guardian_
#define _example_guardian_
#ifndef EXAMPLE_H
#define EXAMPLE_H
int module_function() { return 7; }
int module_variable = 9;

View file

@ -9,12 +9,12 @@ See the lua code for how they are called
%include <carrays.i> // array helpers
// this declares a batch of function for manipulating C integer arrays
// this declares a batch of functions for manipulating C integer arrays
%array_functions(int,int)
// this adds some lua code directly into the module
// warning: you need the example. prefix if you want it added into the module
// admittedly this code is a bit tedious, but its a one off effort
// admittedly this code is a bit tedious, but it's a one off effort
%luacode {
function example.sort_int2(t)
-- local len=table.maxn(t) -- the len - maxn deprecated in 5.3

View file

@ -30,6 +30,6 @@ function checkfail(fn)
end
-- these should fail
-- example.EXTERN is a nil value, so concatentatin will make it fail
-- example.EXTERN is a nil value, so concatenation will make it fail
checkfail(function() print("EXTERN = "..example.EXTERN) end)
checkfail(function() print("FOO = "..example.FOO) end)

View file

@ -23,7 +23,7 @@ We will be using the luaL_dostring()/lua_dostring() function to call into lua
#define lua_open luaL_newstate
#endif
/* the SWIG wrappered library */
/* the SWIG wrapped library */
extern int luaopen_example(lua_State*L);
/* a really simple way of calling lua from C

View file

@ -41,7 +41,7 @@ extern int luaopen_example(lua_State*L);
/* This is an example of how to call the Lua function
int add(int,int)
its very tedious, but gives you an idea of the issues involved.
it's very tedious, but gives you an idea of the issues involved.
(look below for a better idea)
*/
int call_add(lua_State *L,int a,int b,int* res) {
@ -75,7 +75,7 @@ int call_add(lua_State *L,int a,int b,int* res) {
return 1;
}
/* This is a variargs call function for calling from C into Lua.
/* This is a varargs call function for calling from C into Lua.
Original Code from Programming in Lua (PIL) by Roberto Ierusalimschy
ISBN 85-903798-1-7
http://www.lua.org/pil/25.3.html
@ -186,7 +186,7 @@ int main(int argc,char* argv[]) {
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
printf("[C] now loading the SWIG wrappered library\n");
printf("[C] now loading the SWIG wrapped library\n");
luaopen_example(L);
printf("[C] all looks ok\n");
printf("\n");
@ -226,8 +226,8 @@ int main(int argc,char* argv[]) {
printf("\n");
printf("[C] Note: no protection if you mess up the va-args, this is C\n");
printf("\n");
printf("[C] Finally we will call the wrappered gcd function gdc(6,9):\n");
printf("[C] This will pass the values to Lua, then call the wrappered function\n");
printf("[C] Finally we will call the wrapped gcd function gdc(6,9):\n");
printf("[C] This will pass the values to Lua, then call the wrapped function\n");
printf(" Which will get the values from Lua, call the C code \n");
printf(" and return the value to Lua and eventually back to C\n");
printf("[C] Certainly not the best way to do it :-)\n");

View file

@ -61,7 +61,7 @@ bool push_pointer(lua_State*L, void* ptr, const char* type_name, int owned = 0)
/* This is an example of how to call the Lua function
void onEvent(Event e)
its very tedious, but gives you an idea of the issues involed.
it's very tedious, but gives you an idea of the issues involved.
*/
int call_onEvent(lua_State *L, Event e) {
int top;
@ -105,7 +105,7 @@ int main(int argc, char* argv[]) {
/* this code will pass a pointer into lua, but C++ still owns the object
this is a little tedious, to do, but let's do it
we need to pass the pointer (obviously), the type name
and a flag which states if Lua should delete the pointer once its finished with it
and a flag which states if Lua should delete the pointer once it's finished with it
The type name is a class name string which is registered with SWIG
(normally, just look in the wrapper file to get this)
in this case we don't want Lua to delete the pointer so the ownership flag is 0

View file

@ -1,5 +1,5 @@
#ifndef _example_guardian_
#define _example_guardian_
#ifndef EXAMPLE_H
#define EXAMPLE_H
int module_function() { return 7; }
int module_variable = 9;

View file

@ -19,7 +19,8 @@ clear all
# load module in a function globally before base context
clear all;
function testme_1
assert(exist("swigexample") == 3);
% exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
assert(exist("swigexample"));
swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
@ -32,7 +33,8 @@ assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
clear all
function testme_2
assert(exist("swigexample") == 3);
% exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
assert(exist("swigexample"));
swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
@ -52,7 +54,8 @@ swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
function testme_3
assert(exist("swigexample") == 3);
% exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
assert(exist("swigexample"));
swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
@ -65,7 +68,8 @@ swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
function testme_4
assert(exist("swigexample") == 3);
% exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
assert(exist("swigexample"));
swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);

View file

@ -0,0 +1,6 @@
% test octaves concatenation operator
function ret=horzcat(a, b)
% return the concatenation of two ComplexVal values as a cell array.
% (not really useful but it tests the concatenation of swig_ref objects)
ret={a, b};
end

View file

@ -3,6 +3,9 @@ if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
scriptDir = fileparts(mfilename('fullpath'));
addpath(scriptDir);
# Operator overloading example
swigexample
@ -42,3 +45,8 @@ if swig_octave_prereq(3,8,0)
printf("conj(a) = %s\n", disp(conj(a)));
printf("exp(a) = %s\n", disp(exp(a)));
endif
# concatenation operator, note: calls @swig_ref/horzcat.m
# g = [a, b, c];
# printf("g = %s\n",disp(g));
# Above temporarily removed as broken in octave-7.2.0, see https://github.com/swig/swig/issues/2353

View file

@ -15,7 +15,7 @@ extern int squareCubed (int n, int *OUTPUT);
extern int gcd(int x, int y);
%typemap(arginit) (int argc, char *argv[]) "$2 = 0;";
%typemap(arginit) (int argc, char *argv[]) "$2 = 0;"
%typemap(in) (int argc, char *argv[]) {
AV *tempav;

View file

@ -39,7 +39,6 @@ double Square::perimeter(void) {
}
ShapeContainer::~ShapeContainer() {
iterator i=shapes.begin();
for( iterator i = shapes.begin(); i != shapes.end(); ++i ) {
delete *i;
}

View file

@ -84,14 +84,14 @@ x.B()
print("\nTesting some dynamic casts\n")
x = d.toBase()
y = foo.Foo_fromBase(x)
y = foo.Foo.fromBase(x)
print(" Spam -> Base -> Foo : {} swig".format("bad" if y else "good"))
y = bar.Bar_fromBase(x)
y = bar.Bar.fromBase(x)
print(" Spam -> Base -> Bar : {} swig".format("good" if y else "bad"))
y = spam.Spam_fromBase(x)
y = spam.Spam.fromBase(x)
print(" Spam -> Base -> Spam : {} swig".format("good" if y else "bad"))
y = spam.Spam_fromBase(b)
y = spam.Spam.fromBase(b)
print(" Foo -> Spam : {} swig".format("bad" if y else "good"))

View file

@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
ifeq (,$(PY3))
ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))

View file

@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
ifeq (,$(PY3))
ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))

View file

@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
ifeq (,$(PY3))
ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))

View file

@ -5,14 +5,6 @@ import sys
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print("Testing " + testname + " - module renamed as __init__.py")
if sys.version_info >= (3, 0, 0) and sys.version_info < (3, 3, 0):
print(" Not importing as Python version is >= 3.0 and < 3.3")
# Package detection does not work in these versions.
# Can be fixed by using this in the interface file:
# %module(moduleimport="from . import $module") foo # without -builtin
# %module(moduleimport="from .$module import *") foo # with -builtin
sys.exit(0)
import pkg1
print(" Finished importing pkg1")

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)

View file

@ -6,7 +6,7 @@ import zipfile
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)

View file

@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
ifeq (,$(PY3))
ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))

View file

@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
ifeq (,$(PY3))
ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))

View file

@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
ifeq (,$(PY3))
ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
@ -15,7 +15,7 @@ import pkg1.foo
print(" Finished importing pkg1.foo")
if not(pkg1.foo.count() == 3):
if not pkg1.foo.count() == 3:
raise RuntimeError("test failed")
commandline = sys.executable + " -m pkg1.foo"

View file

@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
# Strange failures on windows/cygin/mingw
# Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
@ -15,7 +15,7 @@ import pkg1.foo
print(" Finished importing pkg1.foo")
if not(pkg1.foo.count() == 3):
if not pkg1.foo.count() == 3:
raise RuntimeError("test failed")
commandline = sys.executable + " -m pkg1.foo"

View file

@ -84,14 +84,14 @@ x.B()
print("\nTesting some dynamic casts\n")
x = d.toBase()
y = foo.intFoo_fromBase(x)
y = foo.intFoo.fromBase(x)
print(" Spam -> Base -> Foo : {} swig".format("bad" if y else "good"))
y = bar.intBar_fromBase(x)
y = bar.intBar.fromBase(x)
print(" Spam -> Base -> Bar : {} swig".format("good" if y else "bad"))
y = spam.intSpam_fromBase(x)
y = spam.intSpam.fromBase(x)
print(" Spam -> Base -> Spam : {} swig".format("good" if y else "bad"))
y = spam.intSpam_fromBase(b)
y = spam.intSpam.fromBase(b)
print(" Foo -> Spam : {} swig".format("bad" if y else "good"))

View file

@ -88,7 +88,7 @@ to look at the <a href="http://www.python.org/sigs/distutils-sig/">distutils</a>
<h2>Compatibility</h2>
For Python 3, set the environment variable <tt>PY3=1</tt>.
For Python 2, set the environment variable <tt>PY2=1</tt>.
<p>
Your mileage may vary. If you experience a problem, please let us know by

View file

@ -39,12 +39,14 @@ extern int gcd(int x, int y);
%#if PY_VERSION_HEX >= 0x03000000
{
PyObject *utf8str = PyUnicode_AsUTF8String(s);
const char *cstr;
const char *strtmp = 0;
if (!utf8str) {
SWIG_fail;
}
cstr = PyBytes_AsString(utf8str);
$2[i] = strdup(cstr);
strtmp = PyBytes_AsString(utf8str);
$2[i] = (char *)malloc(strlen(strtmp) + 1);
if ($2[i])
strcpy($2[i], strtmp);
Py_DECREF(utf8str);
}
%#else

View file

@ -2,6 +2,8 @@
import example
print("Variables = " + str(example.cvar))
# Try to set the values of some global variables
example.cvar.ivar = 42
@ -22,7 +24,7 @@ example.cvar.name = "Bill"
# Now print out the values of the variables
print("Variables (values printed from Python)")
print("\nVariables (values printed from Python)")
print("ivar = %s" % example.cvar.ivar)
print("svar = %s" % example.cvar.svar)

View file

@ -16,7 +16,7 @@
/* The EmptyError doesn't appear in a throw declaration, and hence
we need to tell SWIG that the dequeue method throws it. This can
now be done via the %catchs feature. */
now be done via the %catches feature. */
%catches(FullError) *::enqueue;
%catches(EmptyError) *::dequeue();

View file

@ -1,5 +1,5 @@
#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_
#ifndef EXAMPLE_H
#define EXAMPLE_H
#include <vector>
#include <string>
@ -46,4 +46,4 @@ public:
Animal* get_animal(size_t i) const;
};
#endif /*_EXAMPLE_H_*/
#endif /* EXAMPLE_H */

View file

@ -1,5 +1,5 @@
#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_
#ifndef EXAMPLE_H
#define EXAMPLE_H
#include <vector>
#include <string>
@ -46,4 +46,4 @@ public:
Animal* get_animal(size_t i) const;
};
#endif /*_EXAMPLE_H_*/
#endif /* EXAMPLE_H */

View file

@ -14,7 +14,7 @@ extern int squareCubed (int n, int *OUTPUT);
extern int gcd(int x, int y);
%typemap(arginit) (int argc, char *argv[]) "$2 = 0;";
%typemap(arginit) (int argc, char *argv[]) "$2 = 0;"
%typemap(in) (int argc, char *argv[]) {
Tcl_Obj **listobjv = 0;

View file

@ -0,0 +1,20 @@
%module abstract_basecast
%inline %{
class BaseClass {
public:
virtual ~BaseClass() { }
virtual void g() = 0;
};
class DerivedClass : public BaseClass {
public:
virtual void g() { }
BaseClass& f() {
return *this;
}
};
%}

View file

@ -7,8 +7,8 @@
class abstract_foo
{
public:
abstract_foo() { };
virtual ~abstract_foo() { };
abstract_foo() { }
virtual ~abstract_foo() { }
virtual int meth(int meth_param) = 0;
};
@ -16,9 +16,9 @@ public:
class abstract_bar : public abstract_foo
{
public:
abstract_bar() { };
abstract_bar() { }
virtual ~abstract_bar() { };
virtual ~abstract_bar() { }
virtual int meth(int meth_param) = 0;
int meth(int meth_param_1, int meth_param_2) { return 0; }
};

View file

@ -6,7 +6,7 @@
To support contracts, you need to add a macro to the runtime.
For Python, it looks like this:
#define SWIG_contract_assert(expr, msg) if (!(expr)) { PyErr_SetString(PyExc_RuntimeError, (char *) msg #expr ); goto fail; } else
#define SWIG_contract_assert(expr, msg) do { if (!(expr)) { PyErr_SetString(PyExc_RuntimeError, (char *) msg #expr ); goto fail; } } while (0)
Note: It is used like this:
SWIG_contract_assert(x == 1, "Some kind of error message");

View file

@ -35,7 +35,5 @@
const char memberconstchar;
virtual ~DirectorTest() {}
private:
DirectorTest& operator=(const DirectorTest &);
};
%}

View file

@ -1,8 +1,10 @@
%module argcargvtest
#if !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGGO) && !defined(SWIGGUILE) && !defined(SWIGJAVA) && !defined(SWIGJAVASCRIPT) && !defined(SWIGMZSCHEME) && !defined(SWIGOCAML) && !defined(SWIGR) && !defined(SWIGSCILAB)
%include <argcargv.i>
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
#endif
%inline %{

View file

@ -5,8 +5,8 @@
%feature("autodoc");
// special typemap and its docs
%typemap(in) (int c, int d) "$1 = 0; $2 = 0;";
%typemap(doc,name="hello",type="Tuple") (int c, int d) "hello: int tuple[2]";
%typemap(in) (int c, int d) "$1 = 0; $2 = 0;"
%typemap(doc,name="hello",type="Tuple") (int c, int d) "hello: int tuple[2]"
// testing for different documentation levels
%feature("autodoc","0") A::func0; // names
@ -69,8 +69,8 @@
%typemap(doc) (int c, int d);
// docs for some parameters
%typemap(doc) int a "a: special comment for parameter a";
%typemap(doc) int b "b: another special comment for parameter b";
%typemap(doc) int a "a: special comment for parameter a"
%typemap(doc) int b "b: another special comment for parameter b"
%feature("autodoc","0") C::C(int a, int b, Hola h); // names
%feature("autodoc","1") D::D(int a, int b, Hola h); // names + types

View file

@ -62,8 +62,6 @@ struct BoolStructure {
m_rbool(m_bool2),
m_const_pbool(m_pbool),
m_const_rbool(m_rbool) {}
private:
BoolStructure& operator=(const BoolStructure &);
};
%}

View file

@ -13,6 +13,7 @@
%callback("%s") A::foom;
#endif
%callback("%(uppercase)s_Cb_Ptr") foo_T; // this works in Python too
%callback("%s_cb") identity_finger;
%inline %{
@ -85,6 +86,15 @@
const T& ident(const T& x) {
return x;
}
// Test callbacks for enum types
typedef enum {One, Two, Three, Four, Five} finger;
typedef finger (*finger_finger)(finger);
finger identity_finger(finger f) { return f; }
finger apply_finger_cb(finger f, finger_finger cb) {
return cb(f);
}
%}
%template(foo_i) foo_T<int>;

View file

@ -6,6 +6,10 @@ LANGUAGE = cffi
CFFI = @CFFIBIN@
SCRIPTSUFFIX = _runme.lisp
HAVE_CXX11 = @HAVE_CXX11@
HAVE_CXX14 = @HAVE_CXX14@
HAVE_CXX17 = @HAVE_CXX17@
HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
@ -43,7 +47,7 @@ run_testcase = \
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CFFI) -batch -s $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
fi
# Clean: (does nothing, we dont generate extra cffi code)
# Clean: (does nothing, we don't generate extra cffi code)
%.clean:
@exit 0

View file

@ -11,6 +11,7 @@ below.
%{
#include <stdio.h>
#include <string.h>
#define OTHERLAND_MSG "Little message from the safe world."
#define CPLUSPLUS_MSG "A message from the deep dark world of C++, where anything is possible."
@ -150,11 +151,11 @@ const char global_const_char_array2[sizeof(CPLUSPLUS_MSG)+1] = CPLUSPLUS_MSG;
%inline {
struct Formatpos;
struct OBFormat;
static int GetNextFormat(Formatpos& itr, const char*& str,OBFormat*& pFormat) {
return 0;
}
}

View file

@ -0,0 +1,18 @@
%module class_case
// Regression test for SWIG/Go bug #676
%inline %{
class ClassA {};
class classB {};
class classB2 : public classB {};
int Test1(ClassA* a) { return 1; }
int Test1(int i) { return 0; }
int Test2(classB* a) { return 1; }
int Test2(int i) { return 0; }
%}

View file

@ -15,6 +15,7 @@ namespace Space1 {
void aaa(Space1::SubSpace1::A, SubSpace1::A, A) {}
}
}
void global_namespace_a(A*) {}
namespace Space2 {
struct B;

View file

@ -6,7 +6,7 @@ class A {
typedef A tA;
void test_A(A *a) {}
void test_tA(tA *a) {}
inline void test_A(A *a) {}
inline void test_tA(tA *a) {}
tA *new_tA() { return new tA(); }
inline tA *new_tA() { return new tA(); }

View file

@ -0,0 +1,7 @@
%module command_line_define
// Test handling of -D without a value specified.
#if FOO-0 != 1
# error "-DFOO didn't set FOO to 1"
#endif

View file

@ -88,11 +88,13 @@ CPP_TEST_BROKEN += \
extend_variable \
li_boost_shared_ptr_template \
nested_private \
rename_camel \
template_default_pointer \
template_private_assignment \
template_expr \
$(CPP11_TEST_BROKEN)
$(CPP11_TEST_BROKEN) \
$(CPP14_TEST_BROKEN) \
$(CPP17_TEST_BROKEN) \
$(CPP20_TEST_BROKEN)
# Broken C test cases. (Can be run individually using: make testcase.ctest)
@ -102,6 +104,7 @@ C_TEST_BROKEN += \
# C++ test cases. (Can be run individually using: make testcase.cpptest)
CPP_TEST_CASES += \
abstract_access \
abstract_basecast \
abstract_inherit \
abstract_inherit_ok \
abstract_signature \
@ -117,6 +120,7 @@ CPP_TEST_CASES += \
anonymous_bitfield \
apply_signed_char \
apply_strings \
argcargvtest \
argout \
array_member \
array_typedef_memberin \
@ -134,6 +138,7 @@ CPP_TEST_CASES += \
char_binary \
char_strings \
chartest \
class_case \
class_scope_namespace \
class_forward \
class_ignore \
@ -141,6 +146,7 @@ CPP_TEST_CASES += \
compactdefaultargs \
const_const_2 \
constant_directive \
constant_expr \
constant_pointers \
constover \
constructor_copy \
@ -162,11 +168,6 @@ CPP_TEST_CASES += \
cpp_parameters \
cpp_static \
cpp_typedef \
cpp14_binary_integer_literals \
cpp17_hex_floating_literals \
cpp17_nested_namespaces \
cpp17_nspace_nested_namespaces \
cpp17_u8_char_literals \
curiously_recurring_template_pattern \
default_args \
default_arg_expressions \
@ -197,6 +198,7 @@ CPP_TEST_CASES += \
director_frob \
director_ignore \
director_keywords \
director_multiple_inheritance \
director_namespace_clash \
director_nested \
director_nspace \
@ -211,10 +213,12 @@ CPP_TEST_CASES += \
director_protected_overloaded \
director_redefined \
director_ref \
director_simple \
director_smartptr \
director_thread \
director_unroll \
director_using \
director_using_member_scopes \
director_void \
director_wombat \
disown \
@ -232,6 +236,7 @@ CPP_TEST_CASES += \
evil_diamond_ns \
evil_diamond_prop \
exception_classname \
exception_memory_leak \
exception_order \
extend \
extend_constructor_destructor \
@ -303,6 +308,7 @@ CPP_TEST_CASES += \
multiple_inheritance_abstract \
multiple_inheritance_interfaces \
multiple_inheritance_nspace \
multiple_inheritance_overload \
multiple_inheritance_shared_ptr \
name_cxx \
name_warnings \
@ -313,6 +319,7 @@ CPP_TEST_CASES += \
namespace_forward_declaration \
namespace_nested \
namespace_spaces \
namespace_struct \
namespace_template \
namespace_typedef_class \
namespace_typemap \
@ -371,6 +378,7 @@ CPP_TEST_CASES += \
rename2 \
rename3 \
rename4 \
rename_camel \
rename_rstrip_encoder \
rename_scope \
rename_simple \
@ -547,6 +555,8 @@ CPP_TEST_CASES += \
using_directive_and_declaration_forward \
using_extend \
using_inherit \
using_member \
using_member_scopes \
using_namespace \
using_namespace_loop \
using_pointers \
@ -572,6 +582,7 @@ CPP11_TEST_CASES += \
cpp11_alias_nested_template_scoping \
cpp11_alignment \
cpp11_alternate_function_syntax \
cpp11_attribute_specifiers \
cpp11_constexpr \
cpp11_decltype \
cpp11_default_delete \
@ -586,6 +597,9 @@ CPP11_TEST_CASES += \
cpp11_initializer_list \
cpp11_initializer_list_extend \
cpp11_lambda_functions \
cpp11_move_only \
cpp11_move_typemaps \
cpp11_move_only_valuewrapper \
cpp11_noexcept \
cpp11_null_pointer_constant \
cpp11_raw_string_literals \
@ -596,9 +610,11 @@ CPP11_TEST_CASES += \
cpp11_rvalue_reference \
cpp11_rvalue_reference2 \
cpp11_rvalue_reference3 \
cpp11_rvalue_reference_move \
cpp11_sizeof_object \
cpp11_static_assert \
cpp11_std_array \
cpp11_std_unique_ptr \
cpp11_strongly_typed_enumerations \
cpp11_thread_local \
cpp11_template_double_brackets \
@ -615,6 +631,31 @@ CPP11_TEST_BROKEN = \
# cpp11_variadic_templates \ # Broken for some languages (such as Java)
# cpp11_reference_wrapper \ # No typemaps
# C++14 test cases.
CPP14_TEST_CASES += \
cpp14_binary_integer_literals \
# Broken C++14 test cases.
CPP14_TEST_BROKEN = \
# C++17 test cases.
CPP17_TEST_CASES += \
cpp17_hex_floating_literals \
cpp17_nested_namespaces \
cpp17_nspace_nested_namespaces \
cpp17_u8_char_literals \
# Broken C++17 test cases.
CPP17_TEST_BROKEN = \
# C++20 test cases.
CPP20_TEST_CASES += \
cpp20_lambda_template \
cpp20_spaceship_operator \
# Broken C++20 test cases.
CPP20_TEST_BROKEN = \
# Doxygen support test cases: can only be used with languages supporting
# Doxygen comment translation (currently Python and Java) and only if not
# disabled by configure via SKIP_DOXYGEN_TEST_CASES.
@ -628,6 +669,7 @@ endif
ifdef HAS_DOXYGEN
DOXYGEN_TEST_CASES += \
doxygen_alias \
doxygen_autodoc_docstring \
doxygen_basic_notranslate \
doxygen_basic_translate \
doxygen_basic_translate_style2 \
@ -681,6 +723,18 @@ ifeq (1,$(HAVE_CXX11))
CPP_TEST_CASES += $(CPP11_TEST_CASES)
endif
ifeq (1,$(HAVE_CXX14))
CPP_TEST_CASES += $(CPP14_TEST_CASES)
endif
ifeq (1,$(HAVE_CXX17))
CPP_TEST_CASES += $(CPP17_TEST_CASES)
endif
ifeq (1,$(HAVE_CXX20))
CPP_TEST_CASES += $(CPP20_TEST_CASES)
endif
# C test cases. (Can be run individually using: make testcase.ctest)
C_TEST_CASES += \
arrays \
@ -688,8 +742,10 @@ C_TEST_CASES += \
c_delete \
c_delete_function \
char_constant \
command_line_define \
const_const \
constant_expr \
constant_expr_c \
contract_c \
default_args_c \
empty_c \
enums \
@ -726,6 +782,7 @@ C_TEST_CASES += \
preproc \
preproc_constants_c \
preproc_defined \
preproc_expr \
preproc_gcc_output \
preproc_include \
preproc_line_file \
@ -757,10 +814,15 @@ MULTI_CPP_TEST_CASES += \
# Custom tests - tests with additional commandline options
wallkw.cpptest: SWIGOPT += -Wallkw
preproc_include.ctest: SWIGOPT += -includeall
command_line_define.ctest: SWIGOPT += -DFOO
# Allow modules to define temporarily failing tests.
C_TEST_CASES := $(filter-out $(FAILING_C_TESTS),$(C_TEST_CASES))
CPP_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP_TEST_CASES))
CPP11_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP11_TEST_CASES))
CPP14_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP14_TEST_CASES))
CPP17_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP17_TEST_CASES))
CPP20_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP20_TEST_CASES))
MULTI_CPP_TEST_CASES := $(filter-out $(FAILING_MULTI_CPP_TESTS),$(MULTI_CPP_TEST_CASES))
@ -773,6 +835,10 @@ BROKEN_TEST_CASES = $(CPP_TEST_BROKEN:=.cpptest) \
$(C_TEST_BROKEN:=.ctest)
ALL_CLEAN = $(CPP_TEST_CASES:=.clean) \
$(CPP11_TEST_CASES:=.clean) \
$(CPP14_TEST_CASES:=.clean) \
$(CPP17_TEST_CASES:=.clean) \
$(CPP20_TEST_CASES:=.clean) \
$(C_TEST_CASES:=.clean) \
$(MULTI_CPP_TEST_CASES:=.clean) \
$(CPP_TEST_BROKEN:=.clean) \
@ -801,6 +867,14 @@ check-cpp: $(CPP_TEST_CASES:=.cpptest)
check-cpp11: $(CPP11_TEST_CASES:=.cpptest)
check-cpp14: $(CPP14_TEST_CASES:=.cpptest)
check-cpp17: $(CPP17_TEST_CASES:=.cpptest)
check-cpp20: $(CPP20_TEST_CASES:=.cpptest)
check-multicpp: $(MULTI_CPP_TEST_CASES:=.multicpptest)
ifdef HAS_DOXYGEN
check-doxygen: $(DOXYGEN_TEST_CASES:=.cpptest)
endif
@ -818,6 +892,13 @@ endif
partialcheck:
$(MAKE) check CC=true CXX=true LDSHARED=true CXXSHARED=true RUNTOOL=true COMPILETOOL=true
swig_and_compile_cpp_helper = \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT=$(2) NOLINK=true \
TARGET="$(TARGETPREFIX)$(1)$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$(1).i" \
$(LANGUAGE)$(VARIANT)_cpp
swig_and_compile_cpp = \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
@ -834,11 +915,7 @@ swig_and_compile_c = \
swig_and_compile_multi_cpp = \
for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
$(LANGUAGE)$(VARIANT)_cpp; \
$(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)'); \
done
swig_and_compile_external = \

View file

@ -1,11 +1,37 @@
%module constant_expr;
/* Tests of constant expressions. */
/* Tests of constant expressions (C++ version). */
%include "constant_expr_c.i"
%inline %{
/* % didn't work in SWIG 1.3.40 and earlier. */
const int X = 123%7;
#define FOO 12 % 9
double d_array[12 % 9];
// Testcase from https://sourceforge.net/p/swig/bugs/1139/
template<typename Tp>
struct SizeInfo {
enum {
isLarge = (sizeof(Tp)>sizeof(void*)),
isPointer = false
};
};
/* Regression test for #300, fixed in 4.1.0.
*
* Now `a%b` without a space after the `%` is handled as a modulus operator,
* but it gave a cryptic `Syntax error in input(1)` before SWIG 3.0.4, and from
* SWIG 3.0.4 until 4.1.0, `Unknown directive '%a'`.
*/
int a;
int test2(int b = 9%a) { return b; }
/* Example from manual, adapted to avoid C++11 requirement. */
namespace fakestd {
template<typename T, unsigned N>
class array {
T a[N];
public:
array() {}
};
}
void bar(fakestd::array<int, (1<2? 100 : 50)> *x) { }
%}

View file

@ -0,0 +1,56 @@
%module constant_expr_c;
/* Tests of constant expressions (C version). */
%inline %{
/* % didn't work in SWIG 1.3.40 and earlier. */
const int X = 123%7;
#define FOO 12 % 9
double d_array[12 % 9];
/* `<` and `>` in constant expressions caused parse errors before SWIG 4.1.0.
* They're now supported if inside parentheses (and with some restrictions
* on the LHS of `<`.
*/
// Testcase from https://github.com/swig/swig/issues/635
#define TEST_A 1
#define TEST_B 2
#define TEST_C (TEST_A < TEST_B)
#define TEST_D (TEST_A > TEST_B)
// These have been supported since 1.3.41.
#define TEST_E (TEST_A <= TEST_B)
#define TEST_F (TEST_A >= TEST_B)
// For completeness
#define TEST_G (TEST_A == TEST_B)
#define TEST_H (TEST_A != TEST_B)
// No warning
#if (TEST_A < TEST_B)
#define TEST_I 1
#else
#define TEST_I 0
#endif
/* sizeof didn't work on an expression before SWIG 4.1.0 except for cases where
* the expression was in parentheses and looked syntactically like a type (so
* sizeof(X) worked because X could be a type syntactically).
*/
const int s1a = sizeof(X); /* worked before 4.1.0 */
//const int s1b = sizeof X; /* not currently supported */
const int s2a = sizeof("a string" );
const int s2b = sizeof "a string";
const int s3a = sizeof('c');
const int s3b = sizeof('c');
const int s4a = sizeof(L"a wstring");
const int s4b = sizeof L"a wstring";
const int s5a = sizeof(L'C');
const int s5b = sizeof L'C';
const int s6a = sizeof(sizeof(X));
const int s6b = sizeof sizeof(X);
const int s7a = sizeof(3.14);
const int s7b = sizeof 3.14;
const int s8a = sizeof(2.1e-6);
const int s8b = sizeof 2.1e-6;
%}

View file

@ -53,8 +53,6 @@ public:
int* array_member1[ARRAY_SIZE];
ParametersTest* array_member2[ARRAY_SIZE];
MemberVariablesTest() : member3(NULL), member4(NULL) {}
private:
MemberVariablesTest& operator=(const MemberVariablesTest&);
};
void foofunction(const int *const i) {}
@ -80,8 +78,6 @@ public:
void ret8(int*const& a) {}
int*const& ret9() {return GlobalIntPtr;}
ReturnValuesTest() : int3(NULL) {}
private:
ReturnValuesTest& operator=(const ReturnValuesTest&);
};
const int* globalRet1() {return &GlobalInt;}
@ -113,8 +109,6 @@ int* const globalRet2() {return &GlobalInt;}
A* ap;
const A* cap;
Acptr acptr;
private:
B& operator=(const B&);
};
const B* bar(const B* b) {

View file

@ -48,6 +48,7 @@ int test_prepost(int x, int y) {
}
%}
#ifdef __cplusplus
/* Class tests */
%contract Foo::test_preassert(int x, int y) {
@ -235,4 +236,4 @@ class myClass
};
}
#endif

View file

@ -0,0 +1,5 @@
%module contract_c;
%include <exception.i>
%include "contract.i"

View file

@ -3,6 +3,8 @@
%module cpp11_alternate_function_syntax
%inline %{
struct Hello {};
struct SomeStruct {
int addNormal(int x, int y);
auto addAlternate(int x, int y) -> int;
@ -14,6 +16,9 @@ struct SomeStruct {
auto addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int;
#endif // !SWIGC
// Returning a reference didn't parse in SWIG < 4.1.0 (#231)
auto output() -> Hello&;
virtual auto addFinal(int x, int y) const noexcept -> int final { return x + y; }
virtual ~SomeStruct() = default;
};
@ -30,6 +35,7 @@ auto SomeStruct::addAlternateMemberPtrParm(int x, int (SomeStruct::*mp)(int, int
auto SomeStruct::addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int {
return 1000*x + (this->*mp)(x, x);
}
auto SomeStruct::output() -> Hello& { static Hello h; return h; }
#endif // !SWIGC
%}

View file

@ -0,0 +1,54 @@
%module cpp11_attribute_specifiers
%inline %{
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // We're using a deprecated attribute here...
#pragma GCC diagnostic ignored "-Wattributes" // likely is C++20
#pragma GCC diagnostic ignored "-Wunused-variable" // We are using an unused variable on purpose here
#pragma GCC diagnostic ignored "-Wunused-parameter" // We are using an unused param on purpose here
#endif
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wattributes"
#pragma clang diagnostic ignored "-Wunused-variable"
#pragma clang diagnostic ignored "-Wunused-parameter"
#endif
#if defined(_MSC_VER)
#pragma warning(disable : 4996) // For the deprecated attributes in this testcase
#endif
[[noreturn]] void noReturn() { throw; }
[[nodiscard]] bool noDiscard() { return true; }
[[nodiscard, deprecated("This has been replaced")]] bool noDiscardDeprecated() { return true; }
void maybeUnused1([[maybe_unused]] bool b) { }
bool maybeUnused2(bool a, [[maybe_unused]] bool b) { return a; }
[[deprecated, nodiscard]] bool likely([[maybe_unused]] bool a, bool b) {
[[maybe_unused]] bool c = b;
if (b) [[likely]] {
return true;
} else [[unlikely]] {
if(a) {
return true;
}
}
return false;
}
struct [[nodiscard]] S { };
const char *test_string_literal() { return "Test [[ and ]] in string literal"; }
#if 0
// Check that SWIG doesn't choke on ]] when it's not part of an attribute.
// FIXME: SWIG's parser doesn't handle this case currently.
int *a;
int b = a[a[0]];
#endif
%}

View file

@ -53,3 +53,12 @@ int Array300[ConstExpressions::LLL];
//int Array400[ConstExpressions::MMM()];
//int Array500[ConstExpressions::NNN()];
%}
%{
// Test handling of ID PERIOD ID in constant expressions (supported since 4.1.0).
struct A {
int i;
};
constexpr A a{42};
constexpr int N = a.i;
%}

View file

@ -10,7 +10,7 @@
$1 = {"Ab", "Fab"};
%}
%begin %{
%runtime %{
#if __GNUC__ >= 9
/* warning: new of initializer_list does not extend the lifetime of the underlying array [-Winit-list-lifetime] */
/* incorrect warning for C::C(std::initializer_list<const char *>) */

View file

@ -0,0 +1,57 @@
%module cpp11_move_only
%include "cpp11_move_only_helper.i"
%ignore MoveOnly::operator=;
//%valuewrapper MoveOnly; // SWIG sets %valuewrapper by default for move-only types
%inline %{
#include <iostream>
using namespace std;
bool trace = false;
struct MoveOnly {
int val;
MoveOnly(int i = 0) : val(i) { if (trace) cout << "MoveOnly(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
MoveOnly(const MoveOnly &other) = delete;
MoveOnly & operator=(const MoveOnly &other) = delete;
MoveOnly(MoveOnly &&other) noexcept : val(std::move(other.val)) { if (trace) cout << "MoveOnly(MoveOnly &&)" << " " << this << endl; Counter::move_constructor++; }
MoveOnly & operator=(MoveOnly &&other) noexcept { if (trace) cout << "operator=(MoveOnly &&)" << " " << this << endl; Counter::move_assignment++; if (this != &other) { val = std::move(other.val); } return *this; }
~MoveOnly() { if (trace) cout << "~MoveOnly()" << " " << this << endl; Counter::destructor++; }
static MoveOnly create() { return MoveOnly(111); }
// static const MoveOnly createConst() { return MoveOnly(111); } // not supported by default
// compile error by default, see cpp11_move_typemaps.i
#if defined(WRAP_TAKE_METHOD)
static void take(MoveOnly mo) { if (trace) cout << "take(MoveOnly)" << " " << &mo << endl; }
#endif
};
%}
%ignore MovableCopyable::operator=;
%ignore MovableCopyable::MovableCopyable(MovableCopyable &&);
// %valuewrapper MovableCopyable; // SWIG does not use valuewrapper by default for copyable types with a default constructor
%inline %{
// Movable and Copyable
struct MovableCopyable {
int val;
MovableCopyable(int i = 0) : val(i) { if (trace) cout << "MovableCopyable(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
MovableCopyable(const MovableCopyable &other) : val(other.val) { if (trace) cout << "MovableCopyable(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
MovableCopyable & operator=(const MovableCopyable &other) { if (trace) cout << "operator=(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; if (this != &other) { val = other.val; } return *this; }
MovableCopyable(MovableCopyable &&other) noexcept : val(std::move(other.val)) { if (trace) cout << "MovableCopyable(MovableCopyable &&)" << " " << this << endl; Counter::move_constructor++; }
MovableCopyable & operator=(MovableCopyable &&other) noexcept { if (trace) cout << "operator=(MovableCopyable &&)" << " " << this << endl; Counter::move_assignment++; if (this != &other) { val = std::move(other.val); } return *this; }
~MovableCopyable() { if (trace) cout << "~MovableCopyable()" << " " << this << endl; Counter::destructor++; }
static MovableCopyable create() { return MovableCopyable(111); }
static const MovableCopyable createConst() { return MovableCopyable(111); }
static void take(MovableCopyable mc) { if (trace) cout << "take(MovableCopyable)" << " " << &mc << endl; }
};
%}

View file

@ -0,0 +1,71 @@
// Helper interface for cpp11_move_only.i and others
%include <std_string.i>
%catches(std::string) Counter::check_counts;
%inline %{
#include <sstream>
using namespace std;
struct Counter {
static int normal_constructor;
static int copy_constructor;
static int copy_assignment;
static int move_constructor;
static int move_assignment;
static int destructor;
static void reset_counts() {
normal_constructor = 0;
copy_constructor = 0;
copy_assignment = 0;
move_constructor = 0;
move_assignment = 0;
destructor = 0;
}
// Check against expected counts of constructor, assignment operators etc.
// Not observed during development, but compiler optimisation could change the expected values.
// Throws exception if not correct (use %catches to catch them)
static void check_counts(
int normal_constructor,
int copy_constructor,
int copy_assignment,
int move_constructor,
int move_assignment,
int destructor) {
bool match = (
normal_constructor == Counter::normal_constructor &&
copy_constructor == Counter::copy_constructor &&
copy_assignment == Counter::copy_assignment &&
move_constructor == Counter::move_constructor &&
move_assignment == Counter::move_assignment &&
destructor == Counter::destructor);
if (!match) {
std::stringstream ss;
ss << "check_counts failed" << std::endl <<
Counter::normal_constructor << " " <<
Counter::copy_constructor << " " <<
Counter::copy_assignment << " " <<
Counter::move_constructor << " " <<
Counter::move_assignment << " " <<
Counter::destructor << " " <<
" (actual)" << std::endl <<
normal_constructor << " " <<
copy_constructor << " " <<
copy_assignment << " " <<
move_constructor << " " <<
move_assignment << " " <<
destructor << " " <<
" (expected)" << std::endl;
throw ss.str();
}
}
};
int Counter::normal_constructor = 0;
int Counter::copy_constructor = 0;
int Counter::copy_assignment = 0;
int Counter::move_constructor = 0;
int Counter::move_assignment = 0;
int Counter::destructor = 0;
%}

View file

@ -0,0 +1,180 @@
%module cpp11_move_only_valuewrapper
/*
* This test case checks SwigValueWrapper and move assignment.
* Although not necessary, the test case was developed testing with C++98 compatibility for comparing improvements.
* C++11 and later is of course required for the move assignment support.
* C++98 is not actually necesary now as the test-suite only runs this test with compilers that support C++11 and later.
*/
%{
#include <iostream>
#include <sstream>
using std::cout;
using std::endl;
#if __cplusplus >= 201103L
#include <memory>
#else
namespace std {
// just something that will compile and vaguely work for when c++11 is not supported
template <class T> class unique_ptr {
T *ptr;
public:
unique_ptr(T *ptr = 0) : ptr(ptr) {}
unique_ptr(const unique_ptr &a) : ptr(a.ptr) { /*please look away*/ const_cast<unique_ptr &>(a).ptr = 0;}
~unique_ptr() { delete ptr; }
unique_ptr& operator=(const unique_ptr &a) {
if (&a != this) {
delete ptr;
ptr = a.ptr;
/*please look away*/ const_cast<unique_ptr &>(a).ptr = 0;
}
return *this;
}
};
}
#endif
%}
%include "cpp11_move_only_helper.i"
%valuewrapper XXX;
%ignore XXX::operator=;
%inline %{
bool trace = false;
struct XXX {
XXX(int i = 0) { if (trace) cout << "XXX(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
XXX(const XXX &other) { if (trace) cout << "XXX(const XXX &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
XXX & operator=(const XXX &other) { if (trace) cout << "operator=(const XXX &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
#if defined(__cplusplus) && __cplusplus >= 201103L
XXX(XXX &&other) noexcept { if (trace) cout << "XXX(XXX &&)" << " " << this << endl; Counter::move_constructor++; }
XXX & operator=(XXX &&other) noexcept { if (trace) cout << "operator=(XXX &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
#endif
~XXX() { if (trace) cout << "~XXX()" << " " << this << endl; Counter::destructor++; }
};
bool has_cplusplus11() {
#if __cplusplus >= 201103L
return true;
#else
return false;
#endif
}
%}
std::unique_ptr<XXX> makeUniqueXXX();
void cleanup(std::unique_ptr<XXX>* p);
%{
std::unique_ptr<XXX> makeUniqueXXX() {
if (trace) cout << "makeUniqueXXX()" << endl;
return std::unique_ptr<XXX>(new XXX(11));
}
void cleanup(std::unique_ptr<XXX>* p) {
delete p;
}
typedef XXX UUU;
%}
%inline %{
XXX createXXX() {
if (trace) cout << "createXXX()" << endl;
return XXX(111);
}
XXX createXXX2() {
if (trace) cout << "createXXX2()" << endl;
return XXX(222);
}
UUU createUnknownType() {
if (trace) cout << "createXXX2()" << endl;
return XXX(222);
}
struct YYY {};
void inputByValue(UUU uuu, XXX xxx, YYY yyy) {}
%}
%catches(std::string) test1;
%catches(std::string) test2;
%catches(std::string) test3;
%catches(std::string) test4;
%catches(std::string) test5;
%catches(std::string) test6;
%inline %{
// 'unit tests' for SwigValueWrapper
void test1() {
Counter::reset_counts();
{
SwigValueWrapper<XXX> x;
x = XXX();
}
#if __cplusplus >= 201103L
Counter::check_counts(1, 0, 0, 1, 0, 2); // was same as < c++11 counts below before move assignment operator added to SwigValueWrapper
#else
Counter::check_counts(1, 1, 0, 0, 0, 2);
#endif
}
void test2() {
Counter::reset_counts();
{
SwigValueWrapper<XXX> x;
x = XXX();
x = XXX();
}
#if __cplusplus >= 201103L
Counter::check_counts(2, 0, 0, 2, 0, 4);
#else
Counter::check_counts(2, 2, 0, 0, 0, 4);
#endif
}
void test3() {
Counter::reset_counts();
{
SwigValueWrapper<XXX> x;
XXX a(999);
#if __cplusplus >= 201103L
x = std::move(a);
#endif
}
#if __cplusplus >= 201103L
Counter::check_counts(1, 0, 0, 1, 0, 2);
#endif
}
void test4() {
Counter::reset_counts();
{
SwigValueWrapper<std::unique_ptr<XXX> > x;
x = std::unique_ptr<XXX>(new XXX(444));
}
Counter::check_counts(1, 0, 0, 0, 0, 1);
}
void test5() {
#if __cplusplus >= 201103L
Counter::reset_counts();
{
SwigValueWrapper<std::unique_ptr<XXX> > x;
x = std::unique_ptr<XXX>(new XXX(550));
std::unique_ptr<XXX> x2(new XXX(555));
x = std::move(x2);
}
Counter::check_counts(2, 0, 0, 0, 0, 2);
#endif
}
void test6() {
#if __cplusplus >= 201103L
Counter::reset_counts();
{
// emulates how std::unique_ptr typemaps could be wrapped with SwigValueWrapper
void *ptr = 0;
SwigValueWrapper<std::unique_ptr<XXX> > x; // SWIG generated if std::unique_ptr<> definition not parsed
x = makeUniqueXXX(); // SWIG generated code wrapping function returning std::unique_ptr
ptr = new std::unique_ptr<XXX>(x); // 'out' typemap (move std::unique_ptr from stack to the heap)
delete (std::unique_ptr<XXX> *)ptr; // Final cleanup (user needs to call this)
}
Counter::check_counts(1, 0, 0, 0, 0, 1);
#endif
}
%}

View file

@ -0,0 +1,12 @@
%module cpp11_move_typemaps
%include <swigmove.i>
%apply SWIGTYPE MOVE { MoveOnly mo }
%valuewrapper MovableCopyable;
%apply SWIGTYPE MOVE { MovableCopyable mc }
%inline %{
#define WRAP_TAKE_METHOD
%}
%include "cpp11_move_only.i"

View file

@ -1,7 +1,7 @@
/* This module tests whether SWIG correctly parses:
- ordinary strings (char_t)
- ordinary strings (char)
- L wide strings (wchar_t)
- u8 unicode8 strings (char_t)
- u8 unicode8 strings (char / char8_t since C++20)
- u unicode16 strings (char16_t)
- U unicode32 strings (char32_t)
@ -49,7 +49,8 @@ struct URStruct {
// New string literals
wstring aa = L"Wide string";
const char *bb = u8"UTF-8 string";
// u8"" is const char8_t[N] in C++20; const char[N] from C++11 until then.
const char *bb = reinterpret_cast<const char*>(u8"UTF-8 string");
const char16_t *cc = u"UTF-16 string";
const char32_t *dd = U"UTF-32 string";
// New char literals
@ -62,7 +63,7 @@ char32_t char32_t_char = U'b';
const char *xx = ")I'm an \"ascii\" \\ string.";
const char *ee = R"XXX()I'm an "ascii" \ string.)XXX";
wstring ff = LR"XXX(I'm a "raw wide" \ string.)XXX";
const char *gg = u8R"XXX(I'm a "raw UTF-8" \ string.)XXX";
const char *gg = reinterpret_cast<const char*>(u8R"XXX(I'm a "raw UTF-8" \ string.)XXX");
const char16_t *hh = uR"XXX(I'm a "raw UTF-16" \ string.)XXX";
const char32_t *ii = UR"XXX(I'm a "raw UTF-32" \ string.)XXX";
%}

View file

@ -2,11 +2,28 @@
and its templating capabilities introduced in C++11. */
%module cpp11_result_of
// std::result_of is deprecated in C++17
// Replace std implementation with a simple implementation in order to continue testing with C++17 compilers and later
%inline %{
#include <functional>
typedef double(*fn_ptr)(double);
%}
%{
#if __cplusplus >= 201703L
namespace std {
// Forward declaration of result_of
template<typename Func> struct result_of;
// Add in the required partial specialization of result_of
template<> struct result_of< fn_ptr(double) > {
typedef double type;
};
}
#else
#include <functional>
#endif
%}
namespace std {
// Forward declaration of result_of
template<typename Func> struct result_of;
@ -34,22 +51,14 @@ std::result_of< fn_ptr(double) >::type test_result_alternative1(double(*fun)(dou
}
%}
%{
// Another alternative approach using decltype (not very SWIG friendly)
std::result_of< decltype(square)&(double) >::type test_result_alternative2(double(*fun)(double), double arg) {
return fun(arg);
}
%}
%inline %{
#include <iostream>
void cpp_testing() {
std::cout << "result: " << test_result_impl(square, 3) << std::endl;
std::cout << "result: " << test_result_impl<double(*)(double), double>(square, 4) << std::endl;
std::cout << "result: " << test_result_impl< fn_ptr, double >(square, 5) << std::endl;
std::cout << "result: " << test_result_alternative1(square, 6) << std::endl;
std::cout << "result: " << test_result_alternative2(square, 7) << std::endl;
std::cout << "result: " << test_result_impl(square, 3.0) << std::endl;
std::cout << "result: " << test_result_impl<double(*)(double), double>(square, 4.0) << std::endl;
std::cout << "result: " << test_result_impl< fn_ptr, double >(square, 5.0) << std::endl;
std::cout << "result: " << test_result_alternative1(square, 6.0) << std::endl;
}
%}

View file

@ -20,10 +20,10 @@ static const bool PublicGlobalTrue = true;
static const UserDef PublicUserDef = UserDef();
struct Thingy {
typedef int Integer;
int val;
int valval;
int &lvalref;
int &&rvalref;
Thingy(int v, int &&rvalv) : val(v), lvalref(val), rvalref(std::move(rvalv)) {}
Thingy(int v, int &&rvalv) : valval(v), lvalref(valval), rvalref(std::move(rvalv)) {}
void refIn(long &i) {}
void rvalueIn(long &&i) {}
short && rvalueInOut(short &&i) { return std::move(i); }
@ -31,10 +31,10 @@ struct Thingy {
// test both primitive and user defined rvalue reference default arguments and compactdefaultargs
void compactDefaultArgs(const bool &&b = (const bool &&)PublicGlobalTrue, const UserDef &&u = (const UserDef &&)PublicUserDef) {}
void privateDefaultArgs(const bool &&b = (const bool &&)PrivateTrue) {}
operator int &&() { return std::move(val); }
Thingy(const Thingy& rhs) : val(rhs.val), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {}
operator int &&() { return std::move(valval); }
Thingy(const Thingy& rhs) : valval(rhs.valval), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {}
Thingy& operator=(const Thingy& rhs) {
val = rhs.val;
valval = rhs.valval;
lvalref = rhs.lvalref;
rvalref = rhs.rvalref;
return *this;

View file

@ -0,0 +1,52 @@
%module cpp11_rvalue_reference_move
// Testcase for testing rvalue reference input typemaps which assume the object is moved during a function call
%include "cpp11_move_only_helper.i"
%catches(std::string) MovableCopyable::check_numbers_match;
%rename(MoveAssign) MovableCopyable::operator=(MovableCopyable &&);
%ignore MovableCopyable::operator=(const MovableCopyable &); // ignore copy assignment operator, keep move assignment operator
%ignore MovableCopyable::MovableCopyable(const MovableCopyable &); // ignore copy constructor, keep the move constructor
%inline %{
#include <iostream>
using namespace std;
bool trace = false;
class MovableCopyable {
int num;
public:
MovableCopyable(int i = 0) : num(i) { if (trace) cout << "MovableCopyable(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
MovableCopyable(const MovableCopyable &other) : num(other.num) { if (trace) cout << "MovableCopyable(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
MovableCopyable & operator=(const MovableCopyable &other) { if (trace) cout << "operator=(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; num = other.num; return *this; }
MovableCopyable(MovableCopyable &&other) noexcept : num(std::move(other.num)) { if (trace) cout << "MovableCopyable(MovableCopyable &&)" << " " << this << endl; Counter::move_constructor++; }
MovableCopyable & operator=(MovableCopyable &&other) noexcept { if (trace) cout << "operator=(MovableCopyable &&)" << " " << this << endl; Counter::move_assignment++; num = std::move(other.num); return *this; }
~MovableCopyable() { if (trace) cout << "~MovableCopyable()" << " " << this << endl; Counter::destructor++; }
int getNum() { return num; }
static void movein(MovableCopyable &&mcin) {
MovableCopyable mc = std::move(mcin);
}
static MovableCopyable && moveout(int i) {
static MovableCopyable instance;
instance = MovableCopyable(i);
return std::move(instance);
}
static bool is_nullptr(MovableCopyable *p) {
return p == nullptr;
}
static void check_numbers_match(MovableCopyable *p, int expected_num) {
if (p->num != expected_num)
throw std::string("Numbers don't match");
}
};
%}

View file

@ -1,6 +1,6 @@
%module cpp11_std_array
#if defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGJAVA) || defined(SWIGCSHARP)
#if defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGGO)
%{
#include <array>

View file

@ -0,0 +1,107 @@
%module cpp11_std_unique_ptr
#if !(defined(SWIGGO) || defined(SWIGOCAML) || defined(SWIGR) || defined(SWIGSCILAB))
%warnfilter(509, 516) overloadTest(Klass);
%include "std_string.i"
%include "std_unique_ptr.i"
%unique_ptr(Klass)
%inline %{
#include <memory>
#include <string>
//#include <iostream>
#include "swig_examples_lock.h"
class Klass {
public:
explicit Klass(const char* label) :
m_label(label)
{
SwigExamples::Lock lock(critical_section);
total_count++;
}
const char* getLabel() const { return m_label.c_str(); }
virtual ~Klass()
{
SwigExamples::Lock lock(critical_section);
total_count--;
}
static int getTotal_count() { return total_count; }
private:
static SwigExamples::CriticalSection critical_section;
static int total_count;
std::string m_label;
};
SwigExamples::CriticalSection Klass::critical_section;
int Klass::total_count = 0;
%}
%inline %{
// Virtual inheritance used as this usually results in different values for Klass* and KlassInheritance*
// for testing class inheritance and unique_ptr
struct KlassInheritance : virtual Klass {
KlassInheritance(const char* label) : Klass(label) {
// std::cout << "ptrs.... " << std::hex << (Klass*)this << " " << (KlassInheritance*)this << std::endl;
}
};
std::string useKlassRawPtr(Klass* k) {
// std::cout << "useKlassRawPtr " << std::hex << (Klass*)k << std::endl;
std::string s(k->getLabel());
// std::cout << "useKlassRawPtr string: " << s << std::endl;
return s;
}
std::string takeKlassUniquePtr(std::unique_ptr<Klass> k) {
// std::cout << "takeKlassUniquePtr " << std::hex << (Klass*)k.get() << std::endl;
std::string s(k ? k->getLabel() : "null smart pointer");
// std::cout << "takeKlassUniquePtr string: " << s << std::endl;
return s;
}
Klass *make_null() {
return nullptr;
}
bool is_nullptr(Klass *p) {
return p == nullptr;
}
Klass *get_not_owned_ptr(Klass *p) {
return p;
}
std::unique_ptr<Klass> makeKlassUniquePtr(const char* label) {
return std::unique_ptr<Klass>(new Klass(label));
}
std::unique_ptr<Klass> makeNullUniquePtr() {
return std::unique_ptr<Klass>();
}
int overloadTest() {
return 0;
}
int overloadTest(std::unique_ptr<Klass> kover) {
return 1;
}
int overloadTest(Klass k) {
return 2;
}
%}
#endif

View file

@ -4,13 +4,15 @@
*/
%module cpp11_template_explicit
/* Suppress SWIG warnings related to explicit template instantiation and extern templates */
#pragma SWIG nowarn=SWIGWARN_PARSE_EXPLICIT_TEMPLATE
#pragma SWIG nowarn=SWIGWARN_PARSE_EXTERN_TEMPLATE
%inline %{
template<typename T> class Temper {
public:
T val;
T valu;
};
class A {
@ -33,6 +35,30 @@ extern template class Temper<B*>;
template class Temper<int>;
extern template class Temper<short>;
/* Templated function to check support for extern template functions */
template <typename T>
T my_templated_function(int a, double b)
{
return T();
}
/* Explicit extern function template instantiation with simple type */
extern template int my_templated_function<int>(int, double);
template int my_templated_function<int>(int, double);
/* Explicit extern function template instantiation with more complex types */
extern template A my_templated_function<A>(int, double);
template A my_templated_function<A>(int, double);
extern template Temper<int> my_templated_function<Temper<int>>(int, double);
template Temper<int> my_templated_function<Temper<int>>(int, double);
%}
%template(TemperInt) Temper<int>;
/* Enable several versions of the templated function */
%template(my_templated_function_int ) my_templated_function<int>;
%template(my_templated_function_A ) my_templated_function<A>;
%template(my_templated_function_TemperInt) my_templated_function<Temper<int>>;

View file

@ -16,7 +16,9 @@ thread_local static int tsval;
extern thread_local int etval;
thread_local extern int teval;
extern "C" thread_local int ectval;
extern "C" { thread_local int ectval2 = 56; }
extern "C++" thread_local int ecpptval;
extern "C++" { thread_local int ecpptval2 = 67; }
thread_local int ThreadLocals::stval = 11;
thread_local int ThreadLocals::tsval = 22;
@ -30,6 +32,10 @@ thread_local const int ThreadLocals::tscval99;
// externs
thread_local int etval = 33;
thread_local int teval = 44;
extern "C" {
thread_local int ectval = 55;
}
extern "C++" {
thread_local int ecpptval = 66;
}
%}

View file

@ -17,8 +17,8 @@
#include <iostream>
struct OutputType {
int val;
OutputType(int v) : val(v) {}
int valu;
OutputType(int v) : valu(v) {}
};
// Raw literal
@ -30,6 +30,9 @@ OutputType operator "" _mySuffixFloat(long double) { return OutputType(30); }
// Cooked string literals
OutputType operator "" _mySuffix1(const char * string_values, size_t num_chars) { return OutputType(100); }
#ifdef __cpp_lib_char8_t // For C++20
OutputType operator "" _mySuffix1(const char8_t * string_values, size_t num_chars) { return OutputType(100); }
#endif
OutputType operator "" _mySuffix2(const wchar_t * string_values, size_t num_chars) { return OutputType(200); }
OutputType operator "" _mySuffix3(const char16_t * string_values, size_t num_chars) { return OutputType(300); }
OutputType operator "" _mySuffix4(const char32_t * string_values, size_t num_chars) { return OutputType(400); }

View file

@ -1,31 +1,17 @@
%module cpp14_binary_integer_literals
// Tests are designed so that code compiles with C++98 compilers
%{
#if __cplusplus >= 201402L
#define CPP14 1
#if 0b100 < 4
# error binary constant in preprocessor expression failed
#endif
%}
%inline %{
int b1 = 0b1;
int b2 = 0b10;
long b3 = 0b11l;
unsigned long b4 = 0b100ul;
unsigned long b5 = 0B101UL;
%{
#if defined(CPP14)
int b1 = 0b1;
int b2 = 0b10;
long b3 = 0b11l;
unsigned long b4 = 0b100ul;
unsigned long b5 = 0B101UL;
#else
int b1 = 1;
int b2 = 2;
long b3 = 3;
unsigned long b4 = 4;
unsigned long b5 = 5;
#endif
#define b6 0b110
const int b7 = 0b111;
%}
%constant int b8 = 0b1000;

View file

@ -1,13 +1,6 @@
%module cpp17_hex_floating_literals
// Tests are designed so that code compiles with C++98 compilers
%{
#if __cplusplus >= 201703L
#define CPP17 1
#endif
%}
%inline %{
double f1 = 0x.0p1;
double f2 = 0x0.p1;
double f3 = 0x0.0p-1;
@ -17,27 +10,4 @@ double f6 = 0x0.10P+10;
double f7 = 0xb2F.p2;
float f8 = 0x1234AP1F;
float f9 = 0x45A1.D1A2p+10f;
%{
#if defined(CPP17)
double f1 = 0x.0p1;
double f2 = 0x0.p1;
double f3 = 0x0.0p-1;
double f4 = 0xf.p-1;
double f5 = 0xA.0p1;
double f6 = 0x0.10P+10;
double f7 = 0xb2F.p2;
float f8 = 0x1234AP1F;
float f9 = 0x45A1.D1A2p+10f;
#else
double f1 = 0.;
double f2 = 0.;
double f3 = 0.;
double f4 = 7.5;
double f5 = 20.;
double f6 = 64.;
double f7 = 11452.;
float f8 = 149140.f;
float f9 = 18253638.f;
#endif
%}

View file

@ -1,13 +1,5 @@
%module cpp17_nested_namespaces
// Tests c++17 style nested namespaces
// Tests are designed so that code compiles with C++98 compilers
#define CPP17 1
%{
#if __cplusplus >= 201703L
#define CPP17 1
#endif
%}
%inline %{
// Tests with namespaces already defined using C++98 style (non-nested) namespaces
@ -21,20 +13,10 @@ namespace A1 {
};
}
}
#if defined(CPP17)
namespace A1::B1 {
#else
namespace A1 {
namespace B1 {
#endif
A1Struct createA1Struct() { return ::A1::A1Struct(); }
B1Struct createB1Struct() { return ::A1::B1::B1Struct(); }
#if !defined(CPP17)
}
}
#else
}
#endif
namespace A1 {
namespace B1 {
@ -46,154 +28,54 @@ namespace A1 {
}
}
#if defined(CPP17)
namespace A1::B1::C1 {
#else
namespace A1 {
namespace B1 {
namespace C1 {
#endif
C1Struct createC1Struct() { return ::A1::B1::C1::C1Struct(); }
#if !defined(CPP17)
}
}
}
#else
}
#endif
%}
%inline %{
// Tests with namespaces already defined using C++17 style (nested) namespaces
#if defined(CPP17)
namespace A2::B2 {
#else
namespace A2 {
namespace B2 {
#endif
struct B2Struct {
void B2Method() {}
};
#if !defined(CPP17)
}
}
#else
}
#endif
#if defined(CPP17)
namespace A2::B2 {
#else
namespace A2 {
namespace B2 {
#endif
B2Struct createB2Struct() { return ::A2::B2::B2Struct(); }
#if !defined(CPP17)
}
}
#else
}
#endif
#if defined(CPP17)
namespace A2::B2::C2 {
#else
namespace A2 {
namespace B2 {
namespace C2 {
#endif
struct C2Struct {
void C2Method() {}
};
#if !defined(CPP17)
}
}
}
#else
}
#endif
#if defined(CPP17)
namespace A2::B2::C2 {
#else
namespace A2 {
namespace B2 {
namespace C2 {
#endif
C2Struct createC2Struct() { return ::A2::B2::C2::C2Struct(); }
#if !defined(CPP17)
}
}
}
#else
}
#endif
%}
%inline %{
// Tests with namespaces already defined using C++17 style (nested) namespaces to 3 levels
#if defined(CPP17)
namespace A3::B3::C3 {
#else
namespace A3 {
namespace B3 {
namespace C3 {
#endif
struct C3Struct {
void C3Method() {}
};
#if !defined(CPP17)
}
}
}
#else
}
#endif
#if defined(CPP17)
namespace A3::B3::C3 {
#else
namespace A3 {
namespace B3 {
namespace C3 {
#endif
C3Struct createC3Struct() { return ::A3::B3::C3::C3Struct(); }
#if !defined(CPP17)
}
}
}
#else
}
#endif
#if defined(CPP17)
namespace A3::B3 {
#else
namespace A3 {
namespace B3 {
#endif
struct B3Struct {
void B3Method() {}
};
#if !defined(CPP17)
}
}
#else
}
#endif
#if defined(CPP17)
namespace A3::B3 {
#else
namespace A3 {
namespace B3 {
#endif
B3Struct createB3Struct() { return ::A3::B3::B3Struct(); }
#if !defined(CPP17)
}
}
#else
}
#endif
%}

View file

@ -1,26 +1,9 @@
%module cpp17_u8_char_literals
// Tests are designed so that code compiles with C++98 compilers
%{
#if __cplusplus >= 201703L
#define CPP17 1
#endif
%}
// UTF-8 character literals will (apparently) have type char8_t in C++20.
// UTF-8 character literals are type `char` in C++17 but `char8_t` in C++20,
// but the latter can be assigned to `char`.
%inline %{
char a = u8'a';
char u = u8'u';
char u8 = u8'8';
%{
#if defined(CPP17)
char a = u8'a';
char u = u8'u';
char u8 = u8'8';
#else
char a = 'a';
char u = 'u';
char u8 = '8';
#endif
%}

View file

@ -0,0 +1,12 @@
%module cpp20_lambda_template
// We just want to test that SWIG doesn't choke parsing this so suppress:
// Warning 340: Lambda expressions and closures are not fully supported yet.
%warnfilter(SWIGWARN_CPP11_LAMBDA);
%include <std_vector.i>
%inline %{
#include <vector>
auto templated_lambda = []<typename T>(std::vector<T> t){};
%}

View file

@ -0,0 +1,28 @@
%module cpp20_spaceship_operator
%rename(spaceship) operator<=>;
%inline %{
#include <compare>
int v = (-1 <=> 1 > 0) ? 7 : 42;
// We use !(a >= b) here due to limited support for (a < b) in SWIG's parser.
#define ALIEN !(0 <=> 1 >= 0)
const int SPACE = 3 <=> 3 == 0;
struct A {
int v;
explicit A(int v_) : v(v_) { }
};
int operator<=>(const A& a, const A& b) {
return a.v - b.v;
}
int f(int v = (-1 <=> 1 > 0) ? 7 : 42) { return v; }
%}
%constant int COMET = (4 <=> 2 > 0);

View file

@ -47,6 +47,9 @@ class FooSubSub : public FooSub {
const char* __str__() const { return "FooSubSub"; }
};
Foo& get_reference(Foo& other) { return other; }
const Foo& get_const_reference(const Foo& other) { return other; }
%}
%{
@ -76,8 +79,16 @@ class Bar {
Foo *testFoo(int a, Foo *f) {
return new Foo(2 * a + (f ? f->num : 0) + fval.num);
}
/* Const member data and references mean this class can't be assigned.
private:
Bar& operator=(const Bar&);
*/
};
// This class is valid C++ but cannot be assigned to because it has const member data.
struct JustConst {
explicit JustConst(int i_inp) : i(i_inp) {}
const int i;
};
%}

View file

@ -3,7 +3,7 @@
%module cpp_typedef
%{
#if defined(_MSC_VER)
#if defined(_MSC_VER) && _MSC_VER >= 1900
#pragma warning( disable : 5208) // warning C5208: unnamed class used in typedef name cannot declare members other than non-static data members, member enumerations, or member classes
#endif
@ -30,7 +30,6 @@ public:
// Test that the correct types are used for typedef struct declarations
typedef struct {
int something;
void m() {}
} UnnamedStruct;
typedef struct NamedStruct {

View file

@ -8,6 +8,10 @@ CSHARPCILINTERPRETER = @CSHARPCILINTERPRETER@
CSHARPCILINTERPRETER_FLAGS = @CSHARPCILINTERPRETER_FLAGS@
CSHARPCONVERTPATH = @top_srcdir@/@CSHARPCONVERTPATH@
HAVE_CXX11 = @HAVE_CXX11@
HAVE_CXX14 = @HAVE_CXX14@
HAVE_CXX17 = @HAVE_CXX17@
HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = ../@top_srcdir@
top_builddir = ../@top_builddir@
@ -24,6 +28,7 @@ CPP_TEST_CASES = \
csharp_namespace_system_collision \
csharp_prepost \
csharp_typemaps \
director_wstring \
enum_thorough_simple \
enum_thorough_typesafe \
exception_partial_info \

View file

@ -0,0 +1,34 @@
using System;
using cpp11_move_onlyNamespace;
public class cpp11_move_only_runme {
public static void Main() {
// Output
Counter.reset_counts();
using (MoveOnly mo = MoveOnly.create()) {
}
Counter.check_counts(1, 0, 0, 2, 0, 3);
Counter.reset_counts();
using (MovableCopyable mo = MovableCopyable.create()) {
}
Counter.check_counts(2, 1, 0, 0, 1, 3);
// Move semantics not used
Counter.reset_counts();
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);
}
}

View file

@ -0,0 +1,33 @@
using System;
using cpp11_move_only_valuewrapperNamespace;
public class cpp11_move_only_valuewrapper_runme {
public static void Main() {
Counter.reset_counts();
using (XXX xxx = cpp11_move_only_valuewrapper.createXXX()) {
}
if (cpp11_move_only_valuewrapper.has_cplusplus11())
// Was (1, 2, 0, 0, 0, 3) before SwigValueWrapper::operator=(T &&) was added.
// Was (1, 1, 0, 1, 0, 3) before SwigValueWrapper::operator T&&() was added with new "out" typemaps
Counter.check_counts(1, 0, 0, 2, 0, 3);
Counter.reset_counts();
using (XXX xxx = cpp11_move_only_valuewrapper.createXXX2()) {
}
if (cpp11_move_only_valuewrapper.has_cplusplus11())
Counter.check_counts(1, 0, 0, 2, 0, 3);
cpp11_move_only_valuewrapper.test1();
cpp11_move_only_valuewrapper.test2();
cpp11_move_only_valuewrapper.test3();
cpp11_move_only_valuewrapper.test4();
cpp11_move_only_valuewrapper.test5();
cpp11_move_only_valuewrapper.test6();
// Tests SwigValueWrapper, std::unique_ptr (SWIG not parsing a type that is move-only)
Counter.reset_counts();
SWIGTYPE_p_std__unique_ptrT_XXX_t ptr = cpp11_move_only_valuewrapper.makeUniqueXXX();
cpp11_move_only_valuewrapper.cleanup(ptr);
Counter.check_counts(1, 0, 0, 0, 0, 1);
}
}

View file

@ -0,0 +1,37 @@
using System;
using cpp11_move_typemapsNamespace;
public class cpp11_move_typemaps_runme {
public static void Main() {
Counter.reset_counts();
using (MoveOnly mo = new MoveOnly(111)) {
Counter.check_counts(1, 0, 0, 0, 0, 0);
MoveOnly.take(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
Counter.reset_counts();
using (MovableCopyable mo = new MovableCopyable(111)) {
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable.take(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
using (MoveOnly mo = new MoveOnly(222)) {
MoveOnly.take(mo);
bool exception_thrown = false;
try {
MoveOnly.take(mo);
} catch (ApplicationException e) {
if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
throw new ApplicationException("incorrect exception message");
exception_thrown = true;
}
if (!exception_thrown)
throw new ApplicationException("double usage of take should have been an error");
}
}
}

Some files were not shown because too many files have changed in this diff Show more