Merge branch 'master' into doxygen
Fix the usual conflicts in autodoc unit test due to fixing the divergences in autodoc generation between builtin and default cases in this branch.
This commit is contained in:
commit
db65ae5aea
371 changed files with 9815 additions and 3191 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -66,6 +66,7 @@ CCache/ccache_swig_config.h
|
||||||
CCache/config.h
|
CCache/config.h
|
||||||
CCache/config.log
|
CCache/config.log
|
||||||
CCache/config.status
|
CCache/config.status
|
||||||
|
CCache/config_win32.h
|
||||||
Examples/Makefile
|
Examples/Makefile
|
||||||
Examples/d/example.mk
|
Examples/d/example.mk
|
||||||
Examples/guile/Makefile
|
Examples/guile/Makefile
|
||||||
|
|
@ -85,6 +86,8 @@ swig.spec
|
||||||
# Build Artifacts
|
# Build Artifacts
|
||||||
.dirstamp
|
.dirstamp
|
||||||
CCache/ccache-swig
|
CCache/ccache-swig
|
||||||
|
CCache/ccache-swig.1
|
||||||
|
CCache/web/ccache-swig-man.html
|
||||||
Lib/swigwarn.swg
|
Lib/swigwarn.swg
|
||||||
Source/CParse/parser.c
|
Source/CParse/parser.c
|
||||||
Source/CParse/parser.h
|
Source/CParse/parser.h
|
||||||
|
|
|
||||||
50
.travis.yml
50
.travis.yml
|
|
@ -6,9 +6,6 @@ matrix:
|
||||||
env: SWIGLANG=
|
env: SWIGLANG=
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
- compiler: gcc
|
|
||||||
os: linux
|
|
||||||
env: SWIGLANG=
|
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=
|
env: SWIGLANG=
|
||||||
|
|
@ -55,6 +52,8 @@ matrix:
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=javascript ENGINE=node
|
env: SWIGLANG=javascript ENGINE=node
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=javascript ENGINE=jsc
|
env: SWIGLANG=javascript ENGINE=jsc
|
||||||
|
|
@ -75,6 +74,11 @@ matrix:
|
||||||
env: SWIGLANG=lua VER=5.3
|
env: SWIGLANG=lua VER=5.3
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
- compiler: gcc
|
||||||
|
os: linux
|
||||||
|
env: SWIGLANG=ocaml
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=octave SWIGJOBS=-j2 # 3.8
|
env: SWIGLANG=octave SWIGJOBS=-j2 # 3.8
|
||||||
|
|
@ -160,6 +164,14 @@ matrix:
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-builtin
|
env: SWIGLANG=python SWIG_FEATURES=-builtin
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
- os: linux
|
||||||
|
env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
- os: linux
|
||||||
|
env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 PY3=3 VER=3.5
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.4
|
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.4
|
||||||
|
|
@ -219,6 +231,10 @@ matrix:
|
||||||
env: SWIGLANG=csharp SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
env: SWIGLANG=csharp SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
- os: linux
|
||||||
|
env: SWIGLANG=go SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- os: linux
|
- os: linux
|
||||||
env: SWIGLANG=java SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
env: SWIGLANG=java SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||||
sudo: required
|
sudo: required
|
||||||
|
|
@ -227,10 +243,26 @@ matrix:
|
||||||
env: SWIGLANG=python SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
env: SWIGLANG=python SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
- os: linux
|
||||||
|
env: SWIGLANG=r CPP11=1 # Note: making 'R CMD SHLIB' use a different compiler is non-trivial
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
- os: linux
|
||||||
|
env: SWIGLANG=ruby SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
- os: linux
|
||||||
|
env: SWIGLANG=tcl SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- os: linux
|
- os: linux
|
||||||
env: SWIGLANG=csharp SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
env: SWIGLANG=csharp SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
- os: linux
|
||||||
|
env: SWIGLANG=go SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- os: linux
|
- os: linux
|
||||||
env: SWIGLANG=java SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
env: SWIGLANG=java SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||||
sudo: required
|
sudo: required
|
||||||
|
|
@ -239,6 +271,14 @@ matrix:
|
||||||
env: SWIGLANG=python SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
env: SWIGLANG=python SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
- os: linux
|
||||||
|
env: SWIGLANG=ruby SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
- os: linux
|
||||||
|
env: SWIGLANG=tcl SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: osx
|
os: osx
|
||||||
env: SWIGLANG=
|
env: SWIGLANG=
|
||||||
|
|
@ -280,6 +320,10 @@ matrix:
|
||||||
env: SWIGLANG=tcl
|
env: SWIGLANG=tcl
|
||||||
|
|
||||||
allow_failures:
|
allow_failures:
|
||||||
|
# Started failing after upgrade from Guile 2.0.14 to Guile 2.2.0
|
||||||
|
- compiler: clang
|
||||||
|
os: osx
|
||||||
|
env: SWIGLANG=guile
|
||||||
# Lots of failing tests currently
|
# Lots of failing tests currently
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
|
|
|
||||||
8
ANNOUNCE
8
ANNOUNCE
|
|
@ -1,8 +1,8 @@
|
||||||
*** ANNOUNCE: SWIG 3.0.13 (in progress) ***
|
*** ANNOUNCE: SWIG 4.0.0 (in progress) ***
|
||||||
|
|
||||||
http://www.swig.org
|
http://www.swig.org
|
||||||
|
|
||||||
We're pleased to announce SWIG-3.0.13, the latest SWIG release.
|
We're pleased to announce SWIG-4.0.0, the latest SWIG release.
|
||||||
|
|
||||||
What is SWIG?
|
What is SWIG?
|
||||||
=============
|
=============
|
||||||
|
|
@ -27,11 +27,11 @@ Availability
|
||||||
============
|
============
|
||||||
The release is available for download on Sourceforge at
|
The release is available for download on Sourceforge at
|
||||||
|
|
||||||
http://prdownloads.sourceforge.net/swig/swig-3.0.13.tar.gz
|
http://prdownloads.sourceforge.net/swig/swig-4.0.0.tar.gz
|
||||||
|
|
||||||
A Windows version is also available at
|
A Windows version is also available at
|
||||||
|
|
||||||
http://prdownloads.sourceforge.net/swig/swigwin-3.0.13.zip
|
http://prdownloads.sourceforge.net/swig/swigwin-4.0.0.zip
|
||||||
|
|
||||||
Please report problems with this release to the swig-devel mailing list,
|
Please report problems with this release to the swig-devel mailing list,
|
||||||
details at http://www.swig.org/mail.html.
|
details at http://www.swig.org/mail.html.
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ bindir=@bindir@
|
||||||
mandir=@mandir@
|
mandir=@mandir@
|
||||||
INSTALLCMD=@INSTALL@
|
INSTALLCMD=@INSTALL@
|
||||||
PACKAGE_NAME=@PACKAGE_NAME@
|
PACKAGE_NAME=@PACKAGE_NAME@
|
||||||
|
PROGRAM_NAME=@PROGRAM_NAME@
|
||||||
# Soft link test can be skipped on systems that don't support soft linking
|
# Soft link test can be skipped on systems that don't support soft linking
|
||||||
NOSOFTLINKSTEST=
|
NOSOFTLINKSTEST=
|
||||||
|
|
||||||
|
|
@ -17,13 +18,10 @@ SWIG=swig
|
||||||
SWIG_LIB=../$(srcdir)/../Lib
|
SWIG_LIB=../$(srcdir)/../Lib
|
||||||
EXEEXT=@EXEEXT@
|
EXEEXT=@EXEEXT@
|
||||||
|
|
||||||
# Use standard autoconf approach to transform executable name using --program-prefix and --program-suffix
|
|
||||||
transform = @program_transform_name@
|
|
||||||
|
|
||||||
LIBS= @LIBS@
|
LIBS= @LIBS@
|
||||||
OBJS= ccache.o mdfour.o hash.o execute.o util.o args.o stats.o \
|
OBJS= ccache.o mdfour.o hash.o execute.o util.o args.o stats.o \
|
||||||
cleanup.o snprintf.o unify.o
|
cleanup.o snprintf.o unify.o
|
||||||
HEADERS = ccache.h mdfour.h
|
HEADERS = ccache.h mdfour.h config.h config_win32.h
|
||||||
|
|
||||||
all: $(PACKAGE_NAME)$(EXEEXT)
|
all: $(PACKAGE_NAME)$(EXEEXT)
|
||||||
|
|
||||||
|
|
@ -32,7 +30,7 @@ Makefile: $(srcdir)/Makefile.in ./config.status
|
||||||
$(SHELL) ./config.status
|
$(SHELL) ./config.status
|
||||||
|
|
||||||
# Note that HTML documentation is actually generated and used from the main SWIG documentation Makefile
|
# Note that HTML documentation is actually generated and used from the main SWIG documentation Makefile
|
||||||
docs: $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/ccache-man.html
|
docs: $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html
|
||||||
|
|
||||||
$(PACKAGE_NAME)$(EXEEXT): $(OBJS) $(HEADERS)
|
$(PACKAGE_NAME)$(EXEEXT): $(OBJS) $(HEADERS)
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||||
|
|
@ -40,40 +38,43 @@ $(PACKAGE_NAME)$(EXEEXT): $(OBJS) $(HEADERS)
|
||||||
$(srcdir)/$(PACKAGE_NAME).1: $(srcdir)/ccache.yo
|
$(srcdir)/$(PACKAGE_NAME).1: $(srcdir)/ccache.yo
|
||||||
-yodl2man -o $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/ccache.yo
|
-yodl2man -o $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/ccache.yo
|
||||||
|
|
||||||
$(srcdir)/web/ccache-man.html: $(srcdir)/ccache.yo
|
$(srcdir)/web/$(PACKAGE_NAME)-man.html: $(srcdir)/ccache.yo
|
||||||
yodl2html -o $(srcdir)/web/ccache-man.html $(srcdir)/ccache.yo
|
yodl2html -o $(srcdir)/web/$(PACKAGE_NAME)-man.html $(srcdir)/ccache.yo
|
||||||
|
|
||||||
install: $(PACKAGE_NAME)$(EXEEXT)
|
install: $(PACKAGE_NAME)$(EXEEXT)
|
||||||
@echo "Installing $(PACKAGE_NAME)"
|
@echo "Installing $(PACKAGE_NAME)"
|
||||||
@echo "Installing $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)"
|
@echo "Installing $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT)"
|
||||||
${INSTALLCMD} -d $(DESTDIR)${bindir}
|
${INSTALLCMD} -d $(DESTDIR)${bindir}
|
||||||
${INSTALLCMD} -m 755 $(PACKAGE_NAME)$(EXEEXT) $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)
|
${INSTALLCMD} -m 755 $(PACKAGE_NAME)$(EXEEXT) $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT)
|
||||||
|
|
||||||
install-docs: $(srcdir)/$(PACKAGE_NAME).1
|
install-docs: $(srcdir)/$(PACKAGE_NAME).1
|
||||||
@echo "Installing $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1"
|
@echo "Installing $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1"
|
||||||
${INSTALLCMD} -d $(DESTDIR)${mandir}/man1
|
${INSTALLCMD} -d $(DESTDIR)${mandir}/man1
|
||||||
${INSTALLCMD} -m 644 $(srcdir)/$(PACKAGE_NAME).1 $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1
|
${INSTALLCMD} -m 644 $(srcdir)/$(PACKAGE_NAME).1 $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1
|
||||||
|
|
||||||
uninstall: $(PACKAGE_NAME)$(EXEEXT)
|
uninstall: $(PACKAGE_NAME)$(EXEEXT)
|
||||||
rm -f $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)
|
rm -f $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT)
|
||||||
|
|
||||||
uninstall-docs: $(srcdir)/$(PACKAGE_NAME).1
|
uninstall-docs: $(srcdir)/$(PACKAGE_NAME).1
|
||||||
rm -f $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1
|
rm -f $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1
|
||||||
|
|
||||||
clean:
|
clean: clean-docs
|
||||||
/bin/rm -f $(OBJS) *~ $(PACKAGE_NAME)$(EXEEXT)
|
/bin/rm -f $(OBJS) *~ $(PACKAGE_NAME)$(EXEEXT)
|
||||||
|
|
||||||
|
clean-docs:
|
||||||
|
rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html
|
||||||
|
|
||||||
test: test.sh
|
test: test.sh
|
||||||
SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' NOSOFTLINKSTEST='$(NOSOFTLINKSTEST)' $(srcdir)/test.sh
|
SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' NOSOFTLINKSTEST='$(NOSOFTLINKSTEST)' CCACHE='../$(PACKAGE_NAME)' CCACHE_PROG=$(PROGRAM_NAME) $(srcdir)/test.sh
|
||||||
|
|
||||||
check: test
|
check: test
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
/bin/rm -f Makefile config.h config.sub config.log build-stamp config.status ccache_swig_config.h
|
/bin/rm -f Makefile config.h config.sub config.log build-stamp config.status ccache_swig_config.h config_win32.h
|
||||||
/bin/rm -rf autom4te.cache
|
/bin/rm -rf autom4te.cache
|
||||||
|
|
||||||
maintainer-clean: distclean
|
maintainer-clean: distclean
|
||||||
/bin/rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/ccache-man.html
|
/bin/rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html
|
||||||
|
|
||||||
|
|
||||||
# FIXME: To fix this, test.sh needs to be able to take ccache from the
|
# FIXME: To fix this, test.sh needs to be able to take ccache from the
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#else
|
#else
|
||||||
#include <sys/locking.h>
|
#include <sys/locking.h>
|
||||||
#define PACKAGE_NAME "ccache-swig.exe"
|
#include "config_win32.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
#define STATUS_FATAL 4
|
#define STATUS_FATAL 4
|
||||||
#define STATUS_NOCACHE 5
|
#define STATUS_NOCACHE 5
|
||||||
|
|
||||||
#define MYNAME PACKAGE_NAME
|
#define MYNAME PROGRAM_NAME
|
||||||
|
|
||||||
#define LIMIT_MULTIPLE 0.8
|
#define LIMIT_MULTIPLE 0.8
|
||||||
|
|
||||||
|
|
|
||||||
3
CCache/config_win32.h.in
Normal file
3
CCache/config_win32.h.in
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#if !defined(PROGRAM_NAME)
|
||||||
|
#define PROGRAM_NAME "@PROGRAM_NAME@.exe"
|
||||||
|
#endif
|
||||||
|
|
@ -7,6 +7,7 @@ AC_CONFIG_SRCDIR([ccache.h])
|
||||||
AC_MSG_NOTICE([Configuring ccache])
|
AC_MSG_NOTICE([Configuring ccache])
|
||||||
|
|
||||||
AC_CONFIG_HEADER(config.h)
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
AC_CONFIG_FILES([config_win32.h])
|
||||||
|
|
||||||
dnl Checks for programs.
|
dnl Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
|
@ -14,6 +15,20 @@ AC_PROG_CPP
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_ARG_PROGRAM # for program_transform_name
|
AC_ARG_PROGRAM # for program_transform_name
|
||||||
|
|
||||||
|
AC_SUBST(PROGRAM_NAME)
|
||||||
|
if test "x$program_prefix" != "xNONE" -a "x$program_prefix" != "x"
|
||||||
|
then
|
||||||
|
PROGRAM_NAME="$program_prefix$PACKAGE_NAME"
|
||||||
|
else
|
||||||
|
PROGRAM_NAME="$PACKAGE_NAME"
|
||||||
|
fi
|
||||||
|
if test "x$program_suffix" != "xNONE" -a "x$program_suffix" != "x"
|
||||||
|
then
|
||||||
|
PROGRAM_NAME="$PROGRAM_NAME$program_suffix"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_DEFINE_UNQUOTED(PROGRAM_NAME, "$PROGRAM_NAME", [Define my program name])
|
||||||
|
|
||||||
AC_DEFINE([_GNU_SOURCE], 1,
|
AC_DEFINE([_GNU_SOURCE], 1,
|
||||||
[Define _GNU_SOURCE so that we get all necessary prototypes])
|
[Define _GNU_SOURCE so that we get all necessary prototypes])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,12 @@ fi
|
||||||
PATH="`echo $PATH | \
|
PATH="`echo $PATH | \
|
||||||
sed -e 's!:/usr\(/local\)*/lib\([0-9]\)*/ccache\(/\)*!!g'`"
|
sed -e 's!:/usr\(/local\)*/lib\([0-9]\)*/ccache\(/\)*!!g'`"
|
||||||
|
|
||||||
CCACHE=../ccache-swig
|
if test -n "$CCACHE"; then
|
||||||
|
CCACHE="$CCACHE"
|
||||||
|
else
|
||||||
|
CCACHE=../ccache-swig
|
||||||
|
fi
|
||||||
|
|
||||||
TESTDIR=test.$$
|
TESTDIR=test.$$
|
||||||
|
|
||||||
test_failed() {
|
test_failed() {
|
||||||
|
|
@ -406,6 +411,10 @@ swigtests() {
|
||||||
# main program
|
# main program
|
||||||
rm -rf $TESTDIR
|
rm -rf $TESTDIR
|
||||||
mkdir $TESTDIR
|
mkdir $TESTDIR
|
||||||
|
if test -n "$CCACHE_PROG"; then
|
||||||
|
ln -s $CCACHE $TESTDIR/$CCACHE_PROG
|
||||||
|
CCACHE=./$CCACHE_PROG
|
||||||
|
fi
|
||||||
cd $TESTDIR || exit 1
|
cd $TESTDIR || exit 1
|
||||||
|
|
||||||
unset CCACHE_DIR
|
unset CCACHE_DIR
|
||||||
|
|
|
||||||
4
CHANGES
4
CHANGES
|
|
@ -5,7 +5,7 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
Issue # numbers mentioned below can be found on Github. For more details, add
|
Issue # numbers mentioned below can be found on Github. For more details, add
|
||||||
the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
|
|
||||||
Version 3.0.13 (27 Jan 2017)
|
Version 3.0.12 (27 Jan 2017)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
2017-01-27: wsfulton
|
2017-01-27: wsfulton
|
||||||
|
|
@ -21116,7 +21116,7 @@ Version 1.3.7 (September 3, 2001)
|
||||||
typedef __name vector<T>;
|
typedef __name vector<T>;
|
||||||
%enddef
|
%enddef
|
||||||
|
|
||||||
An a specific instantiation is created in exactly the same way:
|
A specific instantiation is created in exactly the same way:
|
||||||
|
|
||||||
%template(intvec) vector<int>;
|
%template(intvec) vector<int>;
|
||||||
|
|
||||||
|
|
|
||||||
435
CHANGES.current
435
CHANGES.current
|
|
@ -4,6 +4,437 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
Issue # numbers mentioned below can be found on Github. For more details, add
|
Issue # numbers mentioned below can be found on Github. For more details, add
|
||||||
the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
|
|
||||||
Version 3.0.13 (in progress)
|
Version 4.0.0 (in progress)
|
||||||
============================
|
===========================
|
||||||
|
|
||||||
|
2017-09-18: wsfulton
|
||||||
|
Fix type promotion wrapping constant expressions of the form:
|
||||||
|
# define EXPR_MIXED1 (0x80 + 11.1) - 1
|
||||||
|
This was previously an integral type instead of a floating point type.
|
||||||
|
|
||||||
|
2017-09-17: wsfulton
|
||||||
|
Fix generated code for constant expressions containing wchar_t L literals such as:
|
||||||
|
# define __WCHAR_MAX (0x7fffffff + L'\0')
|
||||||
|
# define __WCHAR_MIN (-__WCHAR_MAX - 1)
|
||||||
|
|
||||||
|
2017-09-10: mlamarre
|
||||||
|
[Python] Patch #1083. Define_DEBUG to 1 to do exactly like Visual Studio
|
||||||
|
/LDd, /MDd or /MTd compiler options.
|
||||||
|
|
||||||
|
2017-08-25: wsfulton
|
||||||
|
Issue #1059. Add support for C++11 ref-qualifiers on non-static member functions.
|
||||||
|
Members with lvalue ref-qualifiers such as:
|
||||||
|
|
||||||
|
struct RQ {
|
||||||
|
void m1(int x) &;
|
||||||
|
void m2(int x) const &;
|
||||||
|
};
|
||||||
|
|
||||||
|
are wrapped like any other member function. Member functions with rvalue ref-qualifiers
|
||||||
|
are ignored by default, such as:
|
||||||
|
|
||||||
|
struct RQ {
|
||||||
|
void m3(int x) &&;
|
||||||
|
void m4(int x) const &&;
|
||||||
|
};
|
||||||
|
|
||||||
|
example.i:7: Warning 405: Method with rvalue ref-qualifier m3(int) && ignored.
|
||||||
|
example.i:8: Warning 405: Method with rvalue ref-qualifier m4(int) const && ignored.
|
||||||
|
|
||||||
|
These can be unignored and exposed to the target language, see further documentation in
|
||||||
|
CPlusPlus11.html.
|
||||||
|
|
||||||
|
2017-08-16: wsfulton
|
||||||
|
Fix #1063. Add using declarations to templates into typedef table.
|
||||||
|
|
||||||
|
Using declarations to templates were missing in SWIG's internal typedef tables.
|
||||||
|
This led to a few problems, such as, templates that did not instantiate and generated
|
||||||
|
C++ code that did not compile as SWIG did not know what scope the template was
|
||||||
|
in. This happened mostly when a using declaration was used on a template type in a
|
||||||
|
completely unrelated namespace.
|
||||||
|
|
||||||
|
2017-08-16: wsfulton
|
||||||
|
Fix type lookup in the presence of using directives and using declarations.
|
||||||
|
|
||||||
|
Fix some cases of type lookup failure via a combination of both using directives and
|
||||||
|
using declarations resulting in C++ code that did not compile as the generated type was
|
||||||
|
not fully qualified for use in the global namespace. Example below:
|
||||||
|
|
||||||
|
namespace Space5 {
|
||||||
|
namespace SubSpace5 {
|
||||||
|
namespace SubSubSpace5 {
|
||||||
|
struct F {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
using namespace SubSpace5;
|
||||||
|
using SubSubSpace5::F;
|
||||||
|
void func(SubSubSpace5::F f);
|
||||||
|
}
|
||||||
|
|
||||||
|
2017-08-16: wsfulton
|
||||||
|
Issue #1051. %template scope enforcement and class definition fixes.
|
||||||
|
|
||||||
|
The scoping rules around %template have been specified and enforced.
|
||||||
|
The %template directive for a class template is the equivalent to an
|
||||||
|
explicit instantiation of a C++ class template. The scope for a valid
|
||||||
|
%template instantiation is now the same as the scope required for a
|
||||||
|
valid explicit instantiation of a C++ template. A definition of the
|
||||||
|
template for the explicit instantiation must be in scope where the
|
||||||
|
instantiation is declared and must not be enclosed within a different
|
||||||
|
namespace.
|
||||||
|
|
||||||
|
For example, a few %template and C++ explicit instantiations of std::vector
|
||||||
|
are shown below:
|
||||||
|
|
||||||
|
// valid
|
||||||
|
namespace std {
|
||||||
|
%template(vin) vector<int>;
|
||||||
|
template class vector<int>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// valid
|
||||||
|
using namespace std;
|
||||||
|
%template(vin) vector<int>;
|
||||||
|
template class vector<int>;
|
||||||
|
|
||||||
|
// valid
|
||||||
|
using std::vector;
|
||||||
|
%template(vin) vector<int>;
|
||||||
|
template class vector<int>;
|
||||||
|
|
||||||
|
// ill-formed
|
||||||
|
namespace unrelated {
|
||||||
|
using std::vector;
|
||||||
|
%template(vin) vector<int>;
|
||||||
|
template class vector<int>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ill-formed
|
||||||
|
namespace unrelated {
|
||||||
|
using namespace std;
|
||||||
|
%template(vin) vector<int>;
|
||||||
|
template class vector<int>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ill-formed
|
||||||
|
namespace unrelated {
|
||||||
|
namespace std {
|
||||||
|
%template(vin) vector<int>;
|
||||||
|
template class vector<int>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ill-formed
|
||||||
|
namespace unrelated {
|
||||||
|
%template(vin) std::vector<int>;
|
||||||
|
template class std::vector<int>;
|
||||||
|
}
|
||||||
|
|
||||||
|
When the scope is incorrect, an error now occurs such as:
|
||||||
|
|
||||||
|
cpp_template_scope.i:34: Error: 'vector' resolves to 'std::vector' and
|
||||||
|
was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'.
|
||||||
|
|
||||||
|
Previously SWIG accepted the ill-formed examples above but this led to
|
||||||
|
numerous subtle template scope problems especially in the presence of
|
||||||
|
using declarations and using directives as well as with %feature and %typemap.
|
||||||
|
|
||||||
|
Actually, a valid instantiation is one which conforms to the C++03
|
||||||
|
standard as C++11 made a change to disallow using declarations and
|
||||||
|
using directives to find a template.
|
||||||
|
|
||||||
|
// valid C++03, ill-formed C++11
|
||||||
|
using std::vector;
|
||||||
|
template class vector<int>;
|
||||||
|
|
||||||
|
Similar fixes for defining classes using forward class references have
|
||||||
|
also been put in place. For example:
|
||||||
|
|
||||||
|
namespace Space1 {
|
||||||
|
struct A;
|
||||||
|
}
|
||||||
|
namespace Space2 {
|
||||||
|
struct Space1::A {
|
||||||
|
void x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
will now error out with:
|
||||||
|
|
||||||
|
cpp_class_definition.i:5: Error: 'Space1::A' resolves to 'Space1::A' and
|
||||||
|
was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'.
|
||||||
|
|
||||||
|
2017-08-16: wsfulton
|
||||||
|
Fix scope lookup for template parameters containing unary scope operators.
|
||||||
|
|
||||||
|
Fixes cases like:
|
||||||
|
|
||||||
|
namespace Alloc {
|
||||||
|
template<typename T> struct Rebind {
|
||||||
|
typedef int Integer;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
%template(RebindBucket) Alloc::Rebind< Bucket >;
|
||||||
|
OR
|
||||||
|
%template(RebindBucket) Alloc::Rebind< ::Bucket >;
|
||||||
|
|
||||||
|
Alloc::Rebind< Bucket >::Integer Bucket1();
|
||||||
|
Alloc::Rebind< ::Bucket >::Integer Bucket2();
|
||||||
|
Alloc::Rebind<::template TemplateBucket<double>>::Integer Bucket3();
|
||||||
|
|
||||||
|
2017-08-16: wsfulton
|
||||||
|
For templates only, the template parameters are fully resolved when
|
||||||
|
handling typemaps. Without this, it is too hard to have decent rules
|
||||||
|
to apply typemaps when parameter types are typedef'd and template
|
||||||
|
parameters have default values.
|
||||||
|
|
||||||
|
Fixes %clear for typedefs in templates, eg:
|
||||||
|
|
||||||
|
%typemap("in") XXX<int>::Long "..."
|
||||||
|
template typename<T> struct XXX {
|
||||||
|
typedef long Long;
|
||||||
|
};
|
||||||
|
%clear XXX<int>::Long;
|
||||||
|
|
||||||
|
as the typemap was previously incorrectly stored as a typemap for long
|
||||||
|
instead of XXX<int>::Long.
|
||||||
|
|
||||||
|
2017-08-05: olly
|
||||||
|
[C++11] Allow static_assert at the top level (and disallow it right
|
||||||
|
after template<T>). Fixes https://github.com/swig/swig/issues/1031
|
||||||
|
reported by Artem V L.
|
||||||
|
|
||||||
|
2017-08-02: wsfulton
|
||||||
|
Fix incorrectly shown warning when an empty template instantiation was used on a
|
||||||
|
class used as a base class and that base class was explicitly ignored with %ignore.
|
||||||
|
Example of the warning which will no longer appear:
|
||||||
|
|
||||||
|
Warning 401: Base class 'Functor< int,int >' has no name as it is an empty
|
||||||
|
template instantiated with '%template()'. Ignored.
|
||||||
|
|
||||||
|
2017-07-17: fflexo
|
||||||
|
[Java] #674 Add std_list.i to add support for std::list containers. The Java proxy
|
||||||
|
extends java.util.AbstractSequentialList and makes the C++ std::list container look
|
||||||
|
and feel much like a java.util.LinkedList from Java.
|
||||||
|
|
||||||
|
2017-07-07: wsfulton
|
||||||
|
[Python] Fix display of documented template types when using the autodoc
|
||||||
|
feature. For example when wrapping:
|
||||||
|
|
||||||
|
%feature("autodoc");
|
||||||
|
template<typename X> struct T {};
|
||||||
|
%template(TInteger) T<int>;
|
||||||
|
|
||||||
|
the generated documentation contains:
|
||||||
|
"""Proxy of C++ T< int > class."""
|
||||||
|
instead of:
|
||||||
|
"""Proxy of C++ T<(int)> class."""
|
||||||
|
and
|
||||||
|
"""__init__(TInteger self) -> TInteger"""
|
||||||
|
instead of
|
||||||
|
"""__init__(T<(int)> self) -> TInteger"""
|
||||||
|
|
||||||
|
2017-06-27: nihaln
|
||||||
|
[PHP] Update the OUTPUT Typemap to add return statement to the
|
||||||
|
PHP Wrapper.
|
||||||
|
|
||||||
|
2017-06-27: nihaln
|
||||||
|
[PHP] Update the enum and value examples to use the OO wrappers
|
||||||
|
rather than the flat functions produced with -noproxy. There's
|
||||||
|
not been a good reason to use -noproxy for since PHP5 OO wrapping
|
||||||
|
was fixed back in 2005.
|
||||||
|
|
||||||
|
2017-06-23: m7thon
|
||||||
|
[Python] fix and improve default argument handling:
|
||||||
|
|
||||||
|
1. Fix negative octals. Currently not handled correctly by `-py3`
|
||||||
|
(unusual case, but incorrect).
|
||||||
|
2. Fix arguments of type "octal + something" (e.g. `0640 | 04`).
|
||||||
|
Currently drops everything after the first octal. Nasty!
|
||||||
|
3. Fix bool arguments "0 + something" (e.g. `0 | 1`) are always
|
||||||
|
"False" (unusual case, but incorrect).
|
||||||
|
4. Remove special handling of "TRUE" and "FALSE" from
|
||||||
|
`convertValue` since there's no reason these have to match
|
||||||
|
"true" and "false".
|
||||||
|
5. Remove the Python 2 vs. Python 3 distinction based on the
|
||||||
|
`-py3` flag. Now the same python code is produced for default
|
||||||
|
arguments for Python 2 and Python 3. For this, octal default
|
||||||
|
arguments, e.g. 0644, are now wrapped as `int('644', 8)`. This
|
||||||
|
is required, as Python 2 and Python 3 have incompatible syntax
|
||||||
|
for octal literals.
|
||||||
|
|
||||||
|
Fixes #707
|
||||||
|
|
||||||
|
2017-06-21: futatuki
|
||||||
|
#1004 - Fix ccache-swig executable name to respect configure's --program-prefix and
|
||||||
|
--program-suffix values if used.
|
||||||
|
|
||||||
|
2017-06-21: tamuratak
|
||||||
|
[Ruby] #911 - Add std::wstring support.
|
||||||
|
|
||||||
|
2017-06-19: wsfulton
|
||||||
|
[Python] Fix handling of rich comparisons when wrapping overloaded operators:
|
||||||
|
|
||||||
|
operator< operator<= operator> operator>= operator== operator!=
|
||||||
|
|
||||||
|
Previously a TypeError was always thrown if the type was not correct. NotImplemented
|
||||||
|
is now returned from these wrapped functions if the type being compared with is
|
||||||
|
not correct. The subsequent behaviour varies between different versions of Python
|
||||||
|
and the comparison function being used, but is now consistent with normal Python
|
||||||
|
behaviour. For example, for the first 4 operator overloads above, a TypeError
|
||||||
|
'unorderable types' is thrown in Python 3, but Python 2 will return True or False.
|
||||||
|
NotImplemented should be returned when the comparison cannot be done, see PEP 207 and
|
||||||
|
https://docs.python.org/3/library/constants.html#NotImplemented
|
||||||
|
|
||||||
|
Note that the bug was only present when overloaded operators did not also have a
|
||||||
|
function overload.
|
||||||
|
|
||||||
|
Fixes SF bug #1208 (3441262) and SF patch #303.
|
||||||
|
|
||||||
|
*** POTENTIAL INCOMPATIBILITY ***
|
||||||
|
|
||||||
|
2017-06-17: fabrice102
|
||||||
|
[Go] Fix Go callback example. Fixes github #600, #955, #1000.
|
||||||
|
|
||||||
|
2017-06-16: wsfulton
|
||||||
|
Make sure warning and error messages are not split up by other processes writing to
|
||||||
|
stdout at the same time.
|
||||||
|
|
||||||
|
2017-06-16: wsfulton
|
||||||
|
[R] Fix wrapping function pointers containing rvalue and lvalue reference parameters.
|
||||||
|
|
||||||
|
2017-06-13: olly
|
||||||
|
[Perl] Fix testsuite to work without . in @INC - it was removed in
|
||||||
|
Perl 5.26 for security reasons, and has also been removed from
|
||||||
|
older versions in some distros. Fixes
|
||||||
|
https://github.com/swig/swig/issues/997 reported by lfam.
|
||||||
|
|
||||||
|
2017-06-03: wsfulton
|
||||||
|
Fix %import on a file containing a file scope %fragment forced inclusion to not
|
||||||
|
generate the fragment contents as %import should not result in code being generated.
|
||||||
|
The behaviour is now the same as importing code insertion blocks.
|
||||||
|
Wrapping FileC.i in the following example will result in no generated code, whereas
|
||||||
|
previously "#include <limits.h>" was generated:
|
||||||
|
|
||||||
|
// FileA.i
|
||||||
|
%fragment("<limits.h>", "header") %{
|
||||||
|
#include <limits.h>
|
||||||
|
%}
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
%}
|
||||||
|
%fragment("<limits.h>");
|
||||||
|
|
||||||
|
// FileC.i
|
||||||
|
%import "FileA.i"
|
||||||
|
|
||||||
|
*** POTENTIAL INCOMPATIBILITY ***
|
||||||
|
|
||||||
|
2017-05-26: Volker Diels-Grabsch, vadz
|
||||||
|
[Java] #842 Extend from java.util.AbstractList<> and implement java.util.RandomAccess for
|
||||||
|
std::vector wrappers. This notably allows to iterate over wrapped vectors in a natural way.
|
||||||
|
2017-05-30: davidcl
|
||||||
|
[Scilab] #994 Undefined symbol error when loading in Scilab 6
|
||||||
|
|
||||||
|
2017-05-25: asibross
|
||||||
|
[Java] #370 #417 Missing smart pointer handling in Java director extra methods
|
||||||
|
swigReleaseOwnership() and swigTakeOwnership().
|
||||||
|
|
||||||
|
2017-05-23: wsfulton
|
||||||
|
[Java] #230 #759 Fix Java shared_ptr and directors for derived classes java compilation
|
||||||
|
error.
|
||||||
|
|
||||||
|
For shared_ptr proxy proxy classes, add a protected method swigSetCMemOwn for modifying
|
||||||
|
the swigCMemOwn and swigCMemOwnDerived member variables which are used by various other
|
||||||
|
methods for controlling memory ownership.
|
||||||
|
|
||||||
|
2017-05-21: Sghirate
|
||||||
|
[Java, C#, D] #449 Remove unnecessary use of dynamic_cast in directors to enable
|
||||||
|
non-RTTI compilation.
|
||||||
|
|
||||||
|
2017-05-21: wsfulton
|
||||||
|
[Python] #993 Fix handling of default -ve unsigned values, such as:
|
||||||
|
void f(unsigned = -1U);
|
||||||
|
|
||||||
|
2017-05-20: jschueller
|
||||||
|
[Python] #991 Fix E731 PEP8 warning: do not assign a lambda expression
|
||||||
|
|
||||||
|
2017-05-16: nihal95
|
||||||
|
[PHP] Add %pragma version directive to allow the version of the
|
||||||
|
extension to be set. Patch #970, fixes #360.
|
||||||
|
|
||||||
|
2017-05-13: yag00
|
||||||
|
Patch #975 - Add support for noexcept on director methods.
|
||||||
|
|
||||||
|
2017-04-27: redbrain
|
||||||
|
Issue #974, Patch #976 - Fix preprocessor handling of macros with commas in a comment.
|
||||||
|
|
||||||
|
2017-04-25: jleveque
|
||||||
|
[Lua] #959 - Fix Visual Studio C4244 conversion warnings in Lua wrappers.
|
||||||
|
|
||||||
|
2017-04-21: tamuratak
|
||||||
|
[Ruby] #964 - Add shared_ptr director typemaps.
|
||||||
|
|
||||||
|
2017-04-20: wsfulton
|
||||||
|
[Ruby] #586, #935 Add assert for invalid NULL type parameter when calling SWIG_Ruby_NewPointerObj.
|
||||||
|
|
||||||
|
2017-04-20: tamuratak
|
||||||
|
[Ruby] #930, #937 - Fix containers of std::shared_ptr.
|
||||||
|
Upcasting, const types (eg vector<shared_ptr<const T>>) and NULL/nullptr support added.
|
||||||
|
|
||||||
|
2017-04-12: smarchetto
|
||||||
|
[Scilab] New parameter targetversion to specify the Scilab target version (5, 6, ..) for code generation
|
||||||
|
With Scilab 6 target specified, identifier names truncation is disabled (no longer necessary)
|
||||||
|
|
||||||
|
2017-03-24: tamuratak
|
||||||
|
[Ruby] Fix #939 - Wrapping std::vector<bool> fix due to incorrect null checks
|
||||||
|
on VALUE obj.
|
||||||
|
|
||||||
|
2017-03-17: vadz
|
||||||
|
[C#] #947 Add support for std::complex<T>
|
||||||
|
|
||||||
|
2017-03-17: wsfulton
|
||||||
|
[Go] Fix handling of typedef'd function pointers and typedef'd member function pointers
|
||||||
|
such as:
|
||||||
|
|
||||||
|
typedef int (*FnPtr_td)(int, int);
|
||||||
|
int do_op(int x, int y, FnPtr_td op);
|
||||||
|
|
||||||
|
2017-03-16: wsfulton
|
||||||
|
Add support for member const function pointers such as:
|
||||||
|
|
||||||
|
int fn(short (Funcs::* parm)(bool)) const;
|
||||||
|
|
||||||
|
Also fix parsing of references/pointers and qualifiers to member
|
||||||
|
pointers such as:
|
||||||
|
|
||||||
|
int fn(short (Funcs::* const parm)(bool));
|
||||||
|
int fn(short (Funcs::* & parm)(bool));
|
||||||
|
|
||||||
|
2017-03-10: wsfulton
|
||||||
|
Extend C++11 alternate function syntax parsing to support const and noexcept, such as:
|
||||||
|
|
||||||
|
auto sum1(int x, int y) const -> int { return x + y; }
|
||||||
|
auto sum2(int x, int y) noexcept -> int { return x + y; }
|
||||||
|
|
||||||
|
2017-02-29: tamuratak
|
||||||
|
[Ruby] #917 - Add Enumerable module to all container class wrappers. It was missing
|
||||||
|
for std::list, std::multiset, std::unordered_multiset and std::unordered_map.
|
||||||
|
|
||||||
|
2017-02-27: assambar
|
||||||
|
[C++11] Extend parser to support throw specifier in combination
|
||||||
|
with override and/or final.
|
||||||
|
|
||||||
|
2017-02-10: tamuratak
|
||||||
|
[Ruby] #883 - Add support for C++11 hash tables:
|
||||||
|
std::unordered_map
|
||||||
|
std::unordered_set
|
||||||
|
std::unordered_multimap
|
||||||
|
std::unordered_multiset
|
||||||
|
|
||||||
|
2017-02-08: jcsharp
|
||||||
|
[C#] #887 Improve std::vector<T> wrapper constructors -
|
||||||
|
Replace constructor taking ICollection with IEnumerable and also add IEnumerable<T>
|
||||||
|
constructor to avoid the boxing and unboxing overhead of the original constructor,
|
||||||
|
when the type parameter is a value type.
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ SWIG directives. SWIG can be furnished with a header file, but an
|
||||||
interface can also be generated without library headers by supplying a
|
interface can also be generated without library headers by supplying a
|
||||||
simple text file--called the interface file, which is typically named
|
simple text file--called the interface file, which is typically named
|
||||||
with a <tt>.i</tt> extension--containing any foreign declarations of
|
with a <tt>.i</tt> extension--containing any foreign declarations of
|
||||||
identifiers you wish to use. The most common approach is to use a an
|
identifiers you wish to use. The most common approach is to use an
|
||||||
interface file with directives to parse the needed headers. A straight
|
interface file with directives to parse the needed headers. A straight
|
||||||
parse of library headers will result in usable code, but SWIG
|
parse of library headers will result in usable code, but SWIG
|
||||||
directives provides much freedom in how a user might tailor the
|
directives provides much freedom in how a user might tailor the
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,7 @@ All the steps required to compile and use a simple hierarchy of classes for shap
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
First create an Android project called <tt>SwigClass</tt> in a subdirectory called <tt>class</tt>.
|
First create an Android project called <tt>SwigClass</tt> in a subdirectory called <tt>class</tt>.
|
||||||
The steps below create and build a the JNI C++ app.
|
The steps below create and build the JNI C++ app.
|
||||||
Adjust the <tt>--target</tt> id as mentioned earlier in the <a href="Android.html#Android_examples_intro">Examples introduction</a>.
|
Adjust the <tt>--target</tt> id as mentioned earlier in the <a href="Android.html#Android_examples_intro">Examples introduction</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -411,7 +411,7 @@ following conditions need to be met:
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
ccache was inspired by the compilercache shell script script written
|
ccache was inspired by the compilercache shell script written
|
||||||
by Erik Thiele and I would like to thank him for an excellent piece of
|
by Erik Thiele and I would like to thank him for an excellent piece of
|
||||||
work. See
|
work. See
|
||||||
<a href="http://www.erikyyy.de/compilercache/">http://www.erikyyy.de/compilercache/</a>
|
<a href="http://www.erikyyy.de/compilercache/">http://www.erikyyy.de/compilercache/</a>
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
<li><a href="#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
|
<li><a href="#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
|
||||||
<li><a href="#CPlusPlus11_alignment">Control and query object alignment</a>
|
<li><a href="#CPlusPlus11_alignment">Control and query object alignment</a>
|
||||||
<li><a href="#CPlusPlus11_attributes">Attributes</a>
|
<li><a href="#CPlusPlus11_attributes">Attributes</a>
|
||||||
|
<li><a href="#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
<li><a href="#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
@ -877,7 +878,8 @@ so in this case it is entirely possible to pass an int instead of a double to <t
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
SWIG correctly parses the new <tt>static_assert</tt> declarations.
|
SWIG correctly parses the new <tt>static_assert</tt> declarations (though 3.0.12 and earlier
|
||||||
|
had a bug which meant this wasn't accepted at file scope).
|
||||||
This is a C++ compile time directive so there isn't anything useful that SWIG can do with it.
|
This is a C++ compile time directive so there isn't anything useful that SWIG can do with it.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -970,6 +972,104 @@ int [[attr1]] i [[attr2, attr3]];
|
||||||
[[noreturn, nothrow]] void f [[noreturn]] ();
|
[[noreturn, nothrow]] void f [[noreturn]] ();
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
||||||
|
<H3><a name="CPlusPlus11_ref_qualifiers">7.2.29 Methods with ref-qualifiers</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
C++11 non-static member functions can be declared with ref-qualifiers.
|
||||||
|
Member functions declared with a <tt>&</tt> lvalue ref-qualifiers are wrapped like any other function without ref-qualifiers.
|
||||||
|
Member functions declared with a <tt>&&</tt> rvalue ref-qualifiers are ignored by default
|
||||||
|
as they are unlikely to be required from non-C++ languages where the concept of <i>rvalue-ness</i>
|
||||||
|
for the implied *this pointer does not apply.
|
||||||
|
The warning is hidden by default, but can be displayed as described in the section on <a href="Warnings.html#Warnings_nn4">Enabling extra warnings</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Consider:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code"><pre>
|
||||||
|
struct RQ {
|
||||||
|
void m1(int x) &;
|
||||||
|
void m2(int x) &&;
|
||||||
|
};
|
||||||
|
</pre></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The only wrapped method will be the lvalue ref-qualified method <tt>m1</tt>
|
||||||
|
and if SWIG is run with the <tt>-Wextra</tt> command-line option, the following warning will be issued indicating <tt>m2</tt> is not wrapped:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="shell">
|
||||||
|
<pre>
|
||||||
|
example.i:7: Warning 405: Method with rvalue ref-qualifier m2(int) && ignored.
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you unignore the method as follows, wrappers for <tt>m2</tt> will be generated:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code"><pre>
|
||||||
|
%feature("ignore", "0") RQ::m2(int x) &&;
|
||||||
|
struct RQ {
|
||||||
|
void m1(int x) &;
|
||||||
|
void m2(int x) &&;
|
||||||
|
};
|
||||||
|
</pre></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Inspection of the generated C++ code, will show that <tt>std::move</tt> is used on the instance
|
||||||
|
of the <tt>RQ *</tt> class:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code"><pre>
|
||||||
|
RQ *arg1 = (RQ *) 0 ;
|
||||||
|
int arg2 ;
|
||||||
|
|
||||||
|
arg1 = ...marshalled from target language...
|
||||||
|
arg2 = ...marshalled from target language...
|
||||||
|
|
||||||
|
std::move(*arg1).m2(arg2);
|
||||||
|
</pre></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This will compile but when run, the move effects may not be what you want.
|
||||||
|
As stated earlier, rvalue ref-qualifiers aren't really applicable outside the world of C++.
|
||||||
|
However, if you really know what you are doing, full control over the call to the method is
|
||||||
|
possible via the low-level "action" feature.
|
||||||
|
This feature completely replaces the call to the underlying function, that is, the last line in the snippet of code above.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code"><pre>
|
||||||
|
%feature("ignore", "0") RQ::m2(int x) &&;
|
||||||
|
%feature("action") RQ::m2(int x) && %{
|
||||||
|
RQ().m2(arg2);
|
||||||
|
%}
|
||||||
|
struct RQ {
|
||||||
|
void m1(int x) &;
|
||||||
|
void m2(int x) &&;
|
||||||
|
};
|
||||||
|
</pre></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
resulting in:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code"><pre>
|
||||||
|
RQ *arg1 = (RQ *) 0 ;
|
||||||
|
int arg2 ;
|
||||||
|
|
||||||
|
arg1 = ...marshalled from target language...
|
||||||
|
arg2 = ...marshalled from target language...
|
||||||
|
|
||||||
|
RQ().m2(arg2);
|
||||||
|
</pre></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Compatibility note:</b> SWIG-4.0.0 was the first version to support ref-qualifiers.
|
||||||
|
</p>
|
||||||
<H2><a name="CPlusPlus11_standard_library_changes">7.3 Standard library changes</a></H2>
|
<H2><a name="CPlusPlus11_standard_library_changes">7.3 Standard library changes</a></H2>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -994,7 +1094,8 @@ Variadic template support requires further work to provide substantial tuple wra
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The new hash tables in the STL are <tt>unordered_set</tt>, <tt>unordered_multiset</tt>, <tt>unordered_map</tt>, <tt>unordered_multimap</tt>.
|
The new hash tables in the STL are <tt>unordered_set</tt>, <tt>unordered_multiset</tt>, <tt>unordered_map</tt>, <tt>unordered_multimap</tt>.
|
||||||
These are not available in SWIG, but in principle should be easily implemented by adapting the current STL containers.
|
These are not available in all target languages.
|
||||||
|
Any missing support can in principle be easily implemented by adapting the current STL containers.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H3><a name="CPlusPlus11_regular_expressions">7.3.4 Regular expressions</a></H3>
|
<H3><a name="CPlusPlus11_regular_expressions">7.3.4 Regular expressions</a></H3>
|
||||||
|
|
@ -1175,5 +1276,6 @@ Phew, that is a lot of hard work to get a callback working.
|
||||||
You could just go with the more attractive option of just using <tt>double</tt> as the return type in the function declaration instead of <tt>result_of</tt>!
|
You could just go with the more attractive option of just using <tt>double</tt> as the return type in the function declaration instead of <tt>result_of</tt>!
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1772,7 +1772,7 @@ should pass the call on to <tt>CSharpDefaults.DefaultMethod(int)</tt>using the C
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
When using <a href="Modules.html#Modules">multiple modules</a> it is is possible to compile each SWIG generated wrapper
|
When using <a href="Modules.html#Modules">multiple modules</a> it is possible to compile each SWIG generated wrapper
|
||||||
into a different assembly.
|
into a different assembly.
|
||||||
However, by default the generated code may not compile if
|
However, by default the generated code may not compile if
|
||||||
generated classes in one assembly use generated classes in another assembly.
|
generated classes in one assembly use generated classes in another assembly.
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,6 @@
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn12">Static members</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn12">Static members</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_member_data">Member data</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_member_data">Member data</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_default_args">Default arguments</a>
|
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn15">Protection</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn15">Protection</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn16">Enums and constants</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn16">Enums and constants</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn17">Friends</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn17">Friends</a>
|
||||||
|
|
@ -236,16 +235,27 @@
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn20">Inheritance</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn20">Inheritance</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn21">A brief discussion of multiple inheritance, pointers, and type checking</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn21">A brief discussion of multiple inheritance, pointers, and type checking</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_default_args">Default arguments</a>
|
||||||
|
<li><a href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn24">Dispatch function generation</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn24">Dispatch function generation</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn25">Ambiguity in Overloading</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn25">Ambiguity in overloading</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn27">Comments on overloading</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn27">Comments on overloading</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn28">Wrapping overloaded operators</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn28">Overloaded operators</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_class_extension">Class extension</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_class_extension">Class extension</a>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn30">Templates</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn30">Templates</a>
|
||||||
|
<ul>
|
||||||
|
<li><a href="SWIGPlus.html#SWIGPlus_template_directive">The %template directive</a>
|
||||||
|
<li><a href="SWIGPlus.html#SWIGPlus_template_functions">Function templates</a>
|
||||||
|
<li><a href="SWIGPlus.html#SWIGPlus_template_classes">Default template arguments</a>
|
||||||
|
<li><a href="SWIGPlus.html#SWIGPlus_template_class_inheritance">Template base classes</a>
|
||||||
|
<li><a href="SWIGPlus.html#SWIGPlus_template_specialization">Template specialization</a>
|
||||||
|
<li><a href="SWIGPlus.html#SWIGPlus_template_member">Member templates</a>
|
||||||
|
<li><a href="SWIGPlus.html#SWIGPlus_template_scoping">Scoping and templates</a>
|
||||||
|
<li><a href="SWIGPlus.html#SWIGPlus_template_more">More on templates</a>
|
||||||
|
</ul>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_namespaces">Namespaces</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_namespaces">Namespaces</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nspace">The nspace feature for namespaces</a>
|
<li><a href="SWIGPlus.html#SWIGPlus_nspace">The nspace feature for namespaces</a>
|
||||||
|
|
@ -300,6 +310,7 @@
|
||||||
<li><a href="CPlusPlus11.html#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
|
<li><a href="CPlusPlus11.html#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
|
||||||
<li><a href="CPlusPlus11.html#CPlusPlus11_alignment">Control and query object alignment</a>
|
<li><a href="CPlusPlus11.html#CPlusPlus11_alignment">Control and query object alignment</a>
|
||||||
<li><a href="CPlusPlus11.html#CPlusPlus11_attributes">Attributes</a>
|
<li><a href="CPlusPlus11.html#CPlusPlus11_attributes">Attributes</a>
|
||||||
|
<li><a href="CPlusPlus11.html#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="CPlusPlus11.html#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
<li><a href="CPlusPlus11.html#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
@ -347,26 +358,32 @@
|
||||||
<div class="sectiontoc">
|
<div class="sectiontoc">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="Library.html#Library_nn2">The %include directive and library search path</a>
|
<li><a href="Library.html#Library_nn2">The %include directive and library search path</a>
|
||||||
<li><a href="Library.html#Library_nn3">C Arrays and Pointers</a>
|
<li><a href="Library.html#Library_nn3">C arrays and pointers</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="Library.html#Library_nn4">cpointer.i</a>
|
<li><a href="Library.html#Library_nn4">cpointer.i</a>
|
||||||
<li><a href="Library.html#Library_carrays">carrays.i</a>
|
<li><a href="Library.html#Library_carrays">carrays.i</a>
|
||||||
<li><a href="Library.html#Library_nn6">cmalloc.i</a>
|
<li><a href="Library.html#Library_nn6">cmalloc.i</a>
|
||||||
<li><a href="Library.html#Library_nn7">cdata.i</a>
|
<li><a href="Library.html#Library_nn7">cdata.i</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="Library.html#Library_nn8">C String Handling</a>
|
<li><a href="Library.html#Library_nn8">C string handling</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="Library.html#Library_nn9">Default string handling</a>
|
<li><a href="Library.html#Library_nn9">Default string handling</a>
|
||||||
<li><a href="Library.html#Library_nn10">Passing binary data</a>
|
<li><a href="Library.html#Library_nn10">Passing binary data</a>
|
||||||
<li><a href="Library.html#Library_nn11">Using %newobject to release memory</a>
|
<li><a href="Library.html#Library_nn11">Using %newobject to release memory</a>
|
||||||
<li><a href="Library.html#Library_nn12">cstring.i</a>
|
<li><a href="Library.html#Library_nn12">cstring.i</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="Library.html#Library_stl_cpp_library">STL/C++ Library</a>
|
<li><a href="Library.html#Library_stl_cpp_library">STL/C++ library</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="Library.html#Library_std_string">std::string</a>
|
<li><a href="Library.html#Library_std_string">std::string</a>
|
||||||
<li><a href="Library.html#Library_std_vector">std::vector</a>
|
<li><a href="Library.html#Library_std_vector">std::vector</a>
|
||||||
<li><a href="Library.html#Library_stl_exceptions">STL exceptions</a>
|
<li><a href="Library.html#Library_stl_exceptions">STL exceptions</a>
|
||||||
<li><a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a>
|
<li><a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a>
|
||||||
|
<ul>
|
||||||
|
<li><a href="Library.html#Library_shared_ptr_basics">shared_ptr basics</a>
|
||||||
|
<li><a href="Library.html#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
|
||||||
|
<li><a href="Library.html#Library_shared_ptr_templates">shared_ptr and templates</a>
|
||||||
|
<li><a href="Library.html#Library_shared_ptr_directors">shared_ptr and directors</a>
|
||||||
|
</ul>
|
||||||
<li><a href="Library.html#Library_std_auto_ptr">auto_ptr smart pointer</a>
|
<li><a href="Library.html#Library_std_auto_ptr">auto_ptr smart pointer</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="Library.html#Library_nn16">Utility Libraries</a>
|
<li><a href="Library.html#Library_nn16">Utility Libraries</a>
|
||||||
|
|
@ -1614,6 +1631,11 @@
|
||||||
<li><a href="Python.html#Python_nn77">Byte string output conversion</a>
|
<li><a href="Python.html#Python_nn77">Byte string output conversion</a>
|
||||||
<li><a href="Python.html#Python_2_unicode">Python 2 Unicode</a>
|
<li><a href="Python.html#Python_2_unicode">Python 2 Unicode</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
<li><a href="Python.html#Python_multithreaded">Support for Multithreaded Applications</a>
|
||||||
|
<ul>
|
||||||
|
<li><a href="Python.html#Python_thread_UI">UI for Enabling Multithreading Support</a>
|
||||||
|
<li><a href="Python.html#Python_thread_performance">Multithread Performance</a>
|
||||||
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<!-- INDEX -->
|
<!-- INDEX -->
|
||||||
|
|
|
||||||
|
|
@ -356,7 +356,7 @@ In this case, the exception handler is only attached to declarations
|
||||||
named "allocate". This would include both global and member
|
named "allocate". This would include both global and member
|
||||||
functions. The names supplied to <tt>%exception</tt> follow the same
|
functions. The names supplied to <tt>%exception</tt> follow the same
|
||||||
rules as for <tt>%rename</tt> described in the section on
|
rules as for <tt>%rename</tt> described in the section on
|
||||||
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>.
|
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>.
|
||||||
For example, if you wanted to define
|
For example, if you wanted to define
|
||||||
an exception handler for a specific class, you might write this:
|
an exception handler for a specific class, you might write this:
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -796,7 +796,7 @@ involving <tt>%feature</tt>:
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The name matching rules outlined in the <a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
|
The name matching rules outlined in the <a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
|
||||||
section applies to all <tt>%feature</tt> directives.
|
section applies to all <tt>%feature</tt> directives.
|
||||||
In fact the <tt>%rename</tt> directive is just a special form of <tt>%feature</tt>.
|
In fact the <tt>%rename</tt> directive is just a special form of <tt>%feature</tt>.
|
||||||
The matching rules mean that features are very flexible and can be applied with
|
The matching rules mean that features are very flexible and can be applied with
|
||||||
|
|
|
||||||
|
|
@ -280,7 +280,7 @@ class SomeClass : AnInterface, AnotherInterface {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
<p>For this to work, <tt>AnInterface</tt> and <tt>AnotherInterface</tt> have to be in scope. If SWIG is not in split proxy mode, this is already the case, but it it is, they have to be added to the import list via the <tt>dimports</tt> typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.</p>
|
<p>For this to work, <tt>AnInterface</tt> and <tt>AnotherInterface</tt> have to be in scope. If SWIG is not in split proxy mode, this is already the case, but if it is, they have to be added to the import list via the <tt>dimports</tt> typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.</p>
|
||||||
<p>The <tt>$importtype</tt> macro helps you to elegantly solve this problem:</p>
|
<p>The <tt>$importtype</tt> macro helps you to elegantly solve this problem:</p>
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
%typemap(dimports) RemoteMpe %{
|
%typemap(dimports) RemoteMpe %{
|
||||||
|
|
|
||||||
|
|
@ -729,7 +729,7 @@ For instance, the following example uses <tt>%rename</tt> in reverse to generate
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%rename(foo) foo_i(int);
|
%rename(foo) foo_i(int);
|
||||||
%rename(foo) foo_d(double;
|
%rename(foo) foo_d(double);
|
||||||
|
|
||||||
void foo_i(int);
|
void foo_i(int);
|
||||||
void foo_d(double);
|
void foo_d(double);
|
||||||
|
|
@ -1576,7 +1576,7 @@ return the node for the first class member.
|
||||||
|
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
Returns the last child node. You might use this if you wanted to append a new
|
Returns the last child node. You might use this if you wanted to append a new
|
||||||
node to the of a class.
|
node to the children of a class.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -3164,7 +3164,7 @@ these kinds of problems.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<dt> <b>Examples/Makefile.in</b>
|
<dt> <b>Examples/Makefile.in</b>
|
||||||
<dd> Nothing special here; see comments at top the of this file
|
<dd> Nothing special here; see comments at the top of this file
|
||||||
and look to the existing languages for examples.
|
and look to the existing languages for examples.
|
||||||
|
|
||||||
<dt> <b>Examples/qux99/check.list</b>
|
<dt> <b>Examples/qux99/check.list</b>
|
||||||
|
|
|
||||||
|
|
@ -639,7 +639,7 @@ public:
|
||||||
virtual ~FooBarAbstract() {};
|
virtual ~FooBarAbstract() {};
|
||||||
|
|
||||||
std::string FooBar() {
|
std::string FooBar() {
|
||||||
return this->Foo() + ", " + this->Bar();
|
return this->Foo() + ", " + this->Bar();
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -3923,12 +3923,24 @@ is used in the feature code. Consider the following, which also happens to be th
|
||||||
if ($error) {
|
if ($error) {
|
||||||
jenv->ExceptionClear();
|
jenv->ExceptionClear();
|
||||||
$directorthrowshandlers
|
$directorthrowshandlers
|
||||||
throw Swig::DirectorException(jenv, $error);
|
Swig::DirectorException::raise(jenv, $error);
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
where <tt>Swig::DirectorException::raise</tt> is a helper method in the DirectorException class to throw a C++ exception (implemented in director.swg):
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
static void raise(JNIEnv *jenv, jthrowable throwable) {
|
||||||
|
throw DirectorException(jenv, throwable);
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>The code generated using the <code>director:except</code> feature
|
<p>The code generated using the <code>director:except</code> feature
|
||||||
replaces the <code>$directorthrowshandlers</code> special variable with the code in
|
replaces the <code>$directorthrowshandlers</code> special variable with the code in
|
||||||
the "directorthrows" typemaps, for each and every exception defined for the method.
|
the "directorthrows" typemaps, for each and every exception defined for the method.
|
||||||
|
|
@ -3963,7 +3975,7 @@ if (swigerror) {
|
||||||
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message());
|
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Swig::DirectorException(jenv, swigerror);
|
Swig::DirectorException::raise(jenv, swigerror);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -4093,7 +4105,7 @@ the exception specification or <code>%catches</code> feature.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>Note that the "directorthrows" typemaps are important
|
<p>Note that the "directorthrows" typemaps are important
|
||||||
only if it is important for the the exceptions passed through the C++
|
only if it is important for the exceptions passed through the C++
|
||||||
layer to be mapped to distinct C++ exceptions. If director methods
|
layer to be mapped to distinct C++ exceptions. If director methods
|
||||||
are being called by C++ code that is itself wrapped in a
|
are being called by C++ code that is itself wrapped in a
|
||||||
SWIG generated Java wrapper and access is always through this wrapper,
|
SWIG generated Java wrapper and access is always through this wrapper,
|
||||||
|
|
@ -5681,6 +5693,17 @@ The most important of these implement the mapping of C/C++ types to Java types:
|
||||||
In other words the typemap provides the conversion from the native method call return type. </td>
|
In other words the typemap provides the conversion from the native method call return type. </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>jboxtype</td>
|
||||||
|
<td>Java boxed type.
|
||||||
|
These are Java code typemaps to provide the Java boxed type, such as, <tt>Integer</tt> for C type <tt>int</tt>.
|
||||||
|
As autoboxing is only relevant to the Java primitive types, these are only provided for the
|
||||||
|
C types that map to Java primitive types.
|
||||||
|
This typemap is usually only used by C++ STL container wrappers that are wrapped by Java generic
|
||||||
|
types as the boxed type must be used instead of the unboxed/primitive type when declaring a Java generic type.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>javadirectorin</td>
|
<td>javadirectorin</td>
|
||||||
<td>Conversion from jtype to jstype for director methods.
|
<td>Conversion from jtype to jstype for director methods.
|
||||||
|
|
|
||||||
|
|
@ -12,26 +12,32 @@
|
||||||
<div class="sectiontoc">
|
<div class="sectiontoc">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#Library_nn2">The %include directive and library search path</a>
|
<li><a href="#Library_nn2">The %include directive and library search path</a>
|
||||||
<li><a href="#Library_nn3">C Arrays and Pointers</a>
|
<li><a href="#Library_nn3">C arrays and pointers</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#Library_nn4">cpointer.i</a>
|
<li><a href="#Library_nn4">cpointer.i</a>
|
||||||
<li><a href="#Library_carrays">carrays.i</a>
|
<li><a href="#Library_carrays">carrays.i</a>
|
||||||
<li><a href="#Library_nn6">cmalloc.i</a>
|
<li><a href="#Library_nn6">cmalloc.i</a>
|
||||||
<li><a href="#Library_nn7">cdata.i</a>
|
<li><a href="#Library_nn7">cdata.i</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="#Library_nn8">C String Handling</a>
|
<li><a href="#Library_nn8">C string handling</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#Library_nn9">Default string handling</a>
|
<li><a href="#Library_nn9">Default string handling</a>
|
||||||
<li><a href="#Library_nn10">Passing binary data</a>
|
<li><a href="#Library_nn10">Passing binary data</a>
|
||||||
<li><a href="#Library_nn11">Using %newobject to release memory</a>
|
<li><a href="#Library_nn11">Using %newobject to release memory</a>
|
||||||
<li><a href="#Library_nn12">cstring.i</a>
|
<li><a href="#Library_nn12">cstring.i</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="#Library_stl_cpp_library">STL/C++ Library</a>
|
<li><a href="#Library_stl_cpp_library">STL/C++ library</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#Library_std_string">std::string</a>
|
<li><a href="#Library_std_string">std::string</a>
|
||||||
<li><a href="#Library_std_vector">std::vector</a>
|
<li><a href="#Library_std_vector">std::vector</a>
|
||||||
<li><a href="#Library_stl_exceptions">STL exceptions</a>
|
<li><a href="#Library_stl_exceptions">STL exceptions</a>
|
||||||
<li><a href="#Library_std_shared_ptr">shared_ptr smart pointer</a>
|
<li><a href="#Library_std_shared_ptr">shared_ptr smart pointer</a>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#Library_shared_ptr_basics">shared_ptr basics</a>
|
||||||
|
<li><a href="#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
|
||||||
|
<li><a href="#Library_shared_ptr_templates">shared_ptr and templates</a>
|
||||||
|
<li><a href="#Library_shared_ptr_directors">shared_ptr and directors</a>
|
||||||
|
</ul>
|
||||||
<li><a href="#Library_std_auto_ptr">auto_ptr smart pointer</a>
|
<li><a href="#Library_std_auto_ptr">auto_ptr smart pointer</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="#Library_nn16">Utility Libraries</a>
|
<li><a href="#Library_nn16">Utility Libraries</a>
|
||||||
|
|
@ -92,7 +98,7 @@ Set the environment variable to hold an alternative library directory.
|
||||||
The directories that are searched are displayed when using <tt>-verbose</tt> commandline option.
|
The directories that are searched are displayed when using <tt>-verbose</tt> commandline option.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="Library_nn3">9.2 C Arrays and Pointers</a></H2>
|
<H2><a name="Library_nn3">9.2 C arrays and pointers</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -411,7 +417,7 @@ void print_array(double x[10]);
|
||||||
Now, in a scripting language, you might write this:
|
Now, in a scripting language, you might write this:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="targetlang">
|
||||||
<pre>
|
<pre>
|
||||||
a = new_doubleArray(10) # Create an array
|
a = new_doubleArray(10) # Create an array
|
||||||
for i in range(0, 10):
|
for i in range(0, 10):
|
||||||
|
|
@ -475,7 +481,7 @@ void print_array(double x[10]);
|
||||||
Allows you to do this:
|
Allows you to do this:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="targetlang">
|
||||||
<pre>
|
<pre>
|
||||||
import example
|
import example
|
||||||
c = example.doubleArray(10) # Create double[10]
|
c = example.doubleArray(10) # Create double[10]
|
||||||
|
|
@ -761,7 +767,7 @@ char *cdata_<em>name</em>(type* ptr, int nitems)
|
||||||
Clearly they are unsafe.
|
Clearly they are unsafe.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="Library_nn8">9.3 C String Handling</a></H2>
|
<H2><a name="Library_nn8">9.3 C string handling</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -801,7 +807,7 @@ target language. In other words, if you were using a language like Tcl,
|
||||||
and you wrote this,
|
and you wrote this,
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="targetlang">
|
||||||
<pre>
|
<pre>
|
||||||
% foo Hello
|
% foo Hello
|
||||||
</pre>
|
</pre>
|
||||||
|
|
@ -852,7 +858,7 @@ size_t parity(char *str, size_t len, size_t initial);
|
||||||
Now, in the target language, you can use binary string data like this:
|
Now, in the target language, you can use binary string data like this:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="targetlang">
|
||||||
<pre>
|
<pre>
|
||||||
>>> s = "H\x00\x15eg\x09\x20"
|
>>> s = "H\x00\x15eg\x09\x20"
|
||||||
>>> parity(s, 0)
|
>>> parity(s, 0)
|
||||||
|
|
@ -1365,7 +1371,7 @@ structure or class instead.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<H2><a name="Library_stl_cpp_library">9.4 STL/C++ Library</a></H2>
|
<H2><a name="Library_stl_cpp_library">9.4 STL/C++ library</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1385,16 +1391,24 @@ The following table shows which C++ classes are supported and the equivalent SWI
|
||||||
<td><b>SWIG Interface library file</b></td>
|
<td><b>SWIG Interface library file</b></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr> <td>std::array (C++11)</td> <td>array</td> <td>std_array.i</td> </tr>
|
||||||
<tr> <td>std::auto_ptr</td> <td>memory</td> <td>std_auto_ptr.i</td> </tr>
|
<tr> <td>std::auto_ptr</td> <td>memory</td> <td>std_auto_ptr.i</td> </tr>
|
||||||
|
<tr> <td>std::complex</td> <td>complex</td> <td>std_complex.i</td> </tr>
|
||||||
<tr> <td>std::deque</td> <td>deque</td> <td>std_deque.i</td> </tr>
|
<tr> <td>std::deque</td> <td>deque</td> <td>std_deque.i</td> </tr>
|
||||||
<tr> <td>std::list</td> <td>list</td> <td>std_list.i</td> </tr>
|
<tr> <td>std::list</td> <td>list</td> <td>std_list.i</td> </tr>
|
||||||
<tr> <td>std::map</td> <td>map</td> <td>std_map.i</td> </tr>
|
<tr> <td>std::map</td> <td>map</td> <td>std_map.i</td> </tr>
|
||||||
|
<tr> <td>std::multimap (C++11)</td> <td>multimap</td> <td>std_multimap.i</td> </tr>
|
||||||
|
<tr> <td>std::multiset (C++11)</td> <td>multiset</td> <td>std_multiset.i</td> </tr>
|
||||||
<tr> <td>std::pair</td> <td>utility</td> <td>std_pair.i</td> </tr>
|
<tr> <td>std::pair</td> <td>utility</td> <td>std_pair.i</td> </tr>
|
||||||
<tr> <td>std::set</td> <td>set</td> <td>std_set.i</td> </tr>
|
<tr> <td>std::set</td> <td>set</td> <td>std_set.i</td> </tr>
|
||||||
<tr> <td>std::string</td> <td>string</td> <td>std_string.i</td> </tr>
|
<tr> <td>std::string</td> <td>string</td> <td>std_string.i</td> </tr>
|
||||||
|
<tr> <td>std::unordered_map (C++11)</td> <td>unordered_map</td> <td>std_unordered_map.i</td> </tr>
|
||||||
|
<tr> <td>std::unordered_multimap (C++11)</td> <td>unordered_multimap</td> <td>std_unordered_multimap.i</td> </tr>
|
||||||
|
<tr> <td>std::unordered_multiset (C++11)</td> <td>unordered_multiset</td> <td>std_unordered_multiset.i</td> </tr>
|
||||||
|
<tr> <td>std::unordered_set (C++11)</td> <td>unordered_set</td> <td>std_unordered_set.i</td> </tr>
|
||||||
<tr> <td>std::vector</td> <td>vector</td> <td>std_vector.i</td> </tr>
|
<tr> <td>std::vector</td> <td>vector</td> <td>std_vector.i</td> </tr>
|
||||||
<tr> <td>std::array</td> <td>array (C++11)</td> <td>std_array.i</td> </tr>
|
<tr> <td>std::wstring</td> <td>wstring</td> <td>std_wstring.i</td> </tr>
|
||||||
<tr> <td>std::shared_ptr</td> <td>shared_ptr (C++11)</td> <td>std_shared_ptr.i</td> </tr>
|
<tr> <td>std::shared_ptr (C++11)</td> <td>shared_ptr</td> <td>std_shared_ptr.i</td> </tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
@ -1720,6 +1734,9 @@ Any thrown STL exceptions will then be gracefully handled instead of causing a c
|
||||||
<H3><a name="Library_std_shared_ptr">9.4.4 shared_ptr smart pointer</a></H3>
|
<H3><a name="Library_std_shared_ptr">9.4.4 shared_ptr smart pointer</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
<H4><a name="Library_shared_ptr_basics">9.4.4.1 shared_ptr basics</a></H4>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Some target languages have support for handling the shared_ptr reference counted smart pointer.
|
Some target languages have support for handling the shared_ptr reference counted smart pointer.
|
||||||
This smart pointer is available in the standard C++11 library as <tt>std::shared_ptr</tt>.
|
This smart pointer is available in the standard C++11 library as <tt>std::shared_ptr</tt>.
|
||||||
|
|
@ -1813,8 +1830,11 @@ System.out.println(val1 + " " + val2);
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<H4><a name="Library_shared_ptr_inheritance">9.4.4.2 shared_ptr and inheritance</a></H4>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This shared_ptr library works quite differently to SWIG's normal, but somewhat limited,
|
The shared_ptr library works quite differently to SWIG's normal, but somewhat limited,
|
||||||
<a href="SWIGPlus.html#SWIGPlus_smart_pointers">smart pointer handling</a>.
|
<a href="SWIGPlus.html#SWIGPlus_smart_pointers">smart pointer handling</a>.
|
||||||
The shared_ptr library does not generate extra wrappers, just for smart pointer handling, in addition to the proxy class.
|
The shared_ptr library does not generate extra wrappers, just for smart pointer handling, in addition to the proxy class.
|
||||||
The normal proxy class including inheritance relationships is generated as usual.
|
The normal proxy class including inheritance relationships is generated as usual.
|
||||||
|
|
@ -1892,7 +1912,7 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%include "boost_shared_ptr.i"
|
%include <boost_shared_ptr.i>
|
||||||
%shared_ptr(GrandParent);
|
%shared_ptr(GrandParent);
|
||||||
%shared_ptr(Parent);
|
%shared_ptr(Parent);
|
||||||
%shared_ptr(Child);
|
%shared_ptr(Child);
|
||||||
|
|
@ -1901,8 +1921,52 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<H4><a name="Library_shared_ptr_templates">9.4.4.3 shared_ptr and templates</a></H4>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>Note:</b> There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature
|
The <tt>%shared_ptr</tt> macro should be used for all the required instantiations
|
||||||
|
of the template before each of the <tt>%template</tt> instantiations.
|
||||||
|
For example, consider <tt>number.h</tt> containing the following illustrative template:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
template<int N> struct Number {
|
||||||
|
int num;
|
||||||
|
Number() : num(N) {}
|
||||||
|
static std::shared_ptr<Number<N>> make() { return std::make_shared<Number<N>>(); }
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The SWIG code below shows the required ordering:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%include <std_shared_ptr.i>
|
||||||
|
|
||||||
|
%shared_ptr(Number<10>);
|
||||||
|
%shared_ptr(Number<42>);
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include "number.h"
|
||||||
|
%}
|
||||||
|
%include "number.h"
|
||||||
|
|
||||||
|
%template(Number10) Number<10>;
|
||||||
|
%template(Number42) Number<42>;
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<H4><a name="Library_shared_ptr_directors">9.4.4.4 shared_ptr and directors</a></H4>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature
|
||||||
and the degrees of success varies among the different target languages.
|
and the degrees of success varies among the different target languages.
|
||||||
Please help to improve this support by providing patches with improvements.
|
Please help to improve this support by providing patches with improvements.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -122,9 +122,12 @@ swig -cffi -help
|
||||||
<H3><a name="Lisp_nn5">27.2.2 Generating CFFI bindings</a></H3>
|
<H3><a name="Lisp_nn5">27.2.2 Generating CFFI bindings</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
As we mentioned earlier the ideal way to use SWIG is to use interface
|
As we mentioned earlier the ideal way to use SWIG is to use interface
|
||||||
files. To illustrate the use of it, let's assume that we have a
|
files. To illustrate the use of it, let's assume that we have a
|
||||||
file named <i>test.h</i> with the following C code:
|
file named <i>test.h</i> with the following C code:
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
#define y 5
|
#define y 5
|
||||||
|
|
@ -155,7 +158,10 @@ void lispsort_double (int n, double * array);
|
||||||
enum color { RED, BLUE, GREEN};
|
enum color { RED, BLUE, GREEN};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
Corresponding to this we will write a simple interface file:
|
Corresponding to this we will write a simple interface file:
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
%module test
|
%module test
|
||||||
|
|
||||||
|
|
@ -163,7 +169,9 @@ Corresponding to this we will write a simple interface file:
|
||||||
|
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
The generated SWIG Code will be:
|
The generated SWIG Code will be:
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="targetlang"><pre>
|
<div class="targetlang"><pre>
|
||||||
;;;SWIG wrapper code starts here
|
;;;SWIG wrapper code starts here
|
||||||
|
|
@ -430,8 +438,10 @@ Also, while parsing the C++ file and generating C wrapper code SWIG
|
||||||
%include "target/header.h"
|
%include "target/header.h"
|
||||||
|
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
<p>
|
||||||
Various features which were available for C headers can also be used
|
Various features which were available for C headers can also be used
|
||||||
here. The target header which we are going to use here is:
|
here. The target header which we are going to use here is:
|
||||||
|
</p>
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
namespace OpenDemo {
|
namespace OpenDemo {
|
||||||
class Test
|
class Test
|
||||||
|
|
@ -478,8 +488,10 @@ namespace OpenDemo {
|
||||||
%include "test.cpp"
|
%include "test.cpp"
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
SWIG generates 3 files, the first one is a C wrap which we don't show,
|
SWIG generates 3 files, the first one is a C wrap which we don't show,
|
||||||
the second is the plain CFFI wrapper which is as shown below:
|
the second is the plain CFFI wrapper which is as shown below:
|
||||||
|
</p>
|
||||||
<div class="targetlang"><pre>
|
<div class="targetlang"><pre>
|
||||||
(cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void
|
(cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void
|
||||||
(self :pointer)
|
(self :pointer)
|
||||||
|
|
@ -528,11 +540,13 @@ SWIG generates 3 files, the first one is a C wrap which we don't show,
|
||||||
(cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer)
|
(cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer)
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
The output is pretty good but it fails in disambiguating overloaded
|
The output is pretty good but it fails in disambiguating overloaded
|
||||||
functions such as the constructor, in this case. One way of
|
functions such as the constructor, in this case. One way of
|
||||||
resolving this problem is to make the interface use the rename
|
resolving this problem is to make the interface use the rename
|
||||||
directiv, but hopefully there are better solutions.
|
directiv, but hopefully there are better solutions.
|
||||||
In addition SWIG also generates, a CLOS file
|
In addition SWIG also generates, a CLOS file
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<div class="targetlang"><pre>
|
<div class="targetlang"><pre>
|
||||||
|
|
|
||||||
|
|
@ -1008,8 +1008,7 @@ The following operators cannot be overloaded (mainly because they are not suppor
|
||||||
<p>
|
<p>
|
||||||
SWIG also accepts the <tt>__str__()</tt> member function which converts an object to a string. This function should return a const char*, preferably to static memory. This will be used for the <tt>print()</tt> and <tt>tostring()</tt> functions in Lua. Assuming the complex class has a function
|
SWIG also accepts the <tt>__str__()</tt> member function which converts an object to a string. This function should return a const char*, preferably to static memory. This will be used for the <tt>print()</tt> and <tt>tostring()</tt> functions in Lua. Assuming the complex class has a function
|
||||||
</p>
|
</p>
|
||||||
<div class="code"><pre>const char* __str__()
|
<div class="code"><pre>const char* __str__() {
|
||||||
{
|
|
||||||
static char buffer[255];
|
static char buffer[255];
|
||||||
sprintf(buffer, "Complex(%g, %g)", this->re(), this->im());
|
sprintf(buffer, "Complex(%g, %g)", this->re(), this->im());
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
@ -1031,8 +1030,7 @@ Complex(10, 12)
|
||||||
<p>
|
<p>
|
||||||
It is also possible to overload the operator<tt>[]</tt>, but currently this cannot be automatically performed. To overload the operator<tt>[]</tt> you need to provide two functions, <tt>__getitem__()</tt> and <tt>__setitem__()</tt>
|
It is also possible to overload the operator<tt>[]</tt>, but currently this cannot be automatically performed. To overload the operator<tt>[]</tt> you need to provide two functions, <tt>__getitem__()</tt> and <tt>__setitem__()</tt>
|
||||||
</p>
|
</p>
|
||||||
<div class="code"><pre>class Complex
|
<div class="code"><pre>class Complex {
|
||||||
{
|
|
||||||
//....
|
//....
|
||||||
double __getitem__(int i)const; // i is the index, returns the data
|
double __getitem__(int i)const; // i is the index, returns the data
|
||||||
void __setitem__(int i, double d); // i is the index, d is the data
|
void __setitem__(int i, double d); // i is the index, d is the data
|
||||||
|
|
|
||||||
|
|
@ -1633,10 +1633,9 @@ class DoubleArray {
|
||||||
void setitem(int i, double val) {
|
void setitem(int i, double val) {
|
||||||
if ((i >= 0) && (i < n))
|
if ((i >= 0) && (i < n))
|
||||||
ptr[i] = val;
|
ptr[i] = val;
|
||||||
else {
|
else
|
||||||
throw RangeError();
|
throw RangeError();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ If the module is in PHP's default extension directory, you can omit the path.
|
||||||
<p>
|
<p>
|
||||||
For some SAPIs (for example, the CLI SAPI) you can instead use the
|
For some SAPIs (for example, the CLI SAPI) you can instead use the
|
||||||
<a href="http://php.net/manual/en/function.dl.php">dl() function</a> to load
|
<a href="http://php.net/manual/en/function.dl.php">dl() function</a> to load
|
||||||
an extension at run time, by adding a like like this to the start of each
|
an extension at run time, by adding a line like this to the start of each
|
||||||
PHP script which uses your extension:
|
PHP script which uses your extension:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -390,8 +390,7 @@ Although PHP does not support overloading functions natively, swig
|
||||||
will generate dispatch functions which will use <tt>%typecheck</tt>
|
will generate dispatch functions which will use <tt>%typecheck</tt>
|
||||||
typemaps to allow overloading. This dispatch function's operation and
|
typemaps to allow overloading. This dispatch function's operation and
|
||||||
precedence is described in <a
|
precedence is described in <a
|
||||||
href="SWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping
|
href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>.
|
||||||
Overloaded Functions and Methods</a>.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality
|
<!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality
|
||||||
|
|
@ -820,6 +819,15 @@ Results in the following in "example.php"
|
||||||
echo "example.php execution\n";
|
echo "example.php execution\n";
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <b>version</b> pragma can be used to add version to generated PHP extension module. The version is inserted in the zend_module_entry block.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code"><pre>
|
||||||
|
%module example
|
||||||
|
%pragma(php) version="1.5"
|
||||||
|
</pre></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The <b>include</b> pragma is a short cut to add include statements to
|
The <b>include</b> pragma is a short cut to add include statements to
|
||||||
the example.php file.
|
the example.php file.
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,11 @@
|
||||||
<li><a href="#Python_nn77">Byte string output conversion</a>
|
<li><a href="#Python_nn77">Byte string output conversion</a>
|
||||||
<li><a href="#Python_2_unicode">Python 2 Unicode</a>
|
<li><a href="#Python_2_unicode">Python 2 Unicode</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
<li><a href="#Python_multithreaded">Support for Multithreaded Applications</a>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#Python_thread_UI">UI for Enabling Multithreading Support</a>
|
||||||
|
<li><a href="#Python_thread_performance">Multithread Performance</a>
|
||||||
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<!-- INDEX -->
|
<!-- INDEX -->
|
||||||
|
|
@ -221,13 +226,12 @@ resulting C file should be built as a python extension, inserting the module
|
||||||
#include "example.h"
|
#include "example.h"
|
||||||
|
|
||||||
int fact(int n) {
|
int fact(int n) {
|
||||||
if (n < 0){ /* This should probably return an error, but this is simpler */
|
if (n < 0) { /* This should probably return an error, but this is simpler */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/* testing for overflow would be a good idea here */
|
/* testing for overflow would be a good idea here */
|
||||||
return n * fact(n-1);
|
return n * fact(n-1);
|
||||||
}
|
}
|
||||||
|
|
@ -1889,6 +1893,14 @@ Also, be aware that certain operators don't map cleanly to Python. For instance
|
||||||
overloaded assignment operators don't map to Python semantics and will be ignored.
|
overloaded assignment operators don't map to Python semantics and will be ignored.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Operator overloading is implemented in the <tt>pyopers.swg</tt> library file.
|
||||||
|
In particular overloaded operators are marked with the <tt>python:maybecall</tt> feature, also known as <tt>%pythonmaybecall</tt>.
|
||||||
|
This feature forces SWIG to generate code that return an instance of Python's <tt>NotImplemented</tt>
|
||||||
|
instead of raising an exception when the comparison fails, that is, on any kind of error.
|
||||||
|
This follows the guidelines in <a href="https://www.python.org/dev/peps/pep-0207/">PEP 207 - Rich Comparisons</a> and <a href="https://docs.python.org/3/library/constants.html#NotImplemented">NotImplemented Python constant</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<H3><a name="Python_nn25">36.3.12 C++ namespaces</a></H3>
|
<H3><a name="Python_nn25">36.3.12 C++ namespaces</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2463,8 +2475,9 @@ public:
|
||||||
Twit operator+ (const Twit& twit) const;
|
Twit operator+ (const Twit& twit) const;
|
||||||
|
|
||||||
// Forward to operator+
|
// Forward to operator+
|
||||||
Twit add (const Twit& twit) const
|
Twit add (const Twit& twit) const {
|
||||||
{ return *this + twit; }
|
return *this + twit;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2961,9 +2974,6 @@ class MyFoo(mymodule.Foo):
|
||||||
<H3><a name="Python_nn34">36.5.2 Director classes</a></H3>
|
<H3><a name="Python_nn34">36.5.2 Director classes</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
For each class that has directors enabled, SWIG generates a new class
|
For each class that has directors enabled, SWIG generates a new class
|
||||||
that derives from both the class in question and a special
|
that derives from both the class in question and a special
|
||||||
|
|
@ -6036,7 +6046,7 @@ zipimporter requires python-3.5.1 or newer to work with subpackages.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
When SWIG creates wrappers from an interface file, say foo.i, two Python modules are
|
When SWIG creates wrappers from an interface file, say foo.i, two Python modules are
|
||||||
created. There is a pure Python module module (foo.py) and C/C++ code which is
|
created. There is a pure Python module (foo.py) and C/C++ code which is
|
||||||
built and linked into a dynamically (or statically) loaded low-level module _foo
|
built and linked into a dynamically (or statically) loaded low-level module _foo
|
||||||
(see the <a href="Python.html#Python_nn3">Preliminaries section</a> for details). So, the interface
|
(see the <a href="Python.html#Python_nn3">Preliminaries section</a> for details). So, the interface
|
||||||
file really defines two Python modules. How these two modules are loaded is
|
file really defines two Python modules. How these two modules are loaded is
|
||||||
|
|
@ -6331,7 +6341,7 @@ is backported to 2.6.
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
%include <pybuffer.i>
|
%include <pybuffer.i>
|
||||||
%pybuffer_mutable_string(char *str);
|
%pybuffer_mutable_string(char *str);
|
||||||
void get_path(char *s);
|
void get_path(char *str);
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -6730,6 +6740,110 @@ the first is allowing unicode conversion and the second is explicitly
|
||||||
prohibiting it.
|
prohibiting it.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<H2><a name="Python_multithreaded">36.13 Support for Multithreaded Applications</a></H2>
|
||||||
|
|
||||||
|
|
||||||
|
<p>By default, SWIG does not enable support for multithreaded Python applications. More
|
||||||
|
specifically, the Python wrappers generated by SWIG will not release the
|
||||||
|
Python's interpreter's Global Interpreter Lock (GIL) when wrapped C/C++ code is
|
||||||
|
entered. Hence, while any of the wrapped C/C++ code is executing, the Python interpreter
|
||||||
|
will not be able to run any other threads, even if the wrapped C/C++ code is waiting
|
||||||
|
in a blocking call for something like network or disk IO.
|
||||||
|
|
||||||
|
Fortunately, SWIG does have the ability to enable multithreaded support and automatic
|
||||||
|
release of the GIL either for all wrapped code in a module or on a more selective basis. The user
|
||||||
|
interface for this is described in the next section.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<H3><a name="Python_thread_UI">36.13.1 UI for Enabling Multithreading Support</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
<p>The user interface is as follows:</p>
|
||||||
|
<ol>
|
||||||
|
<li><p>Module thread support can be enabled in two ways:</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<p>
|
||||||
|
The <tt>-threads</tt> swig python option at the command line (or in <tt>setup.py</tt>):
|
||||||
|
</p>
|
||||||
|
<div class="shell"><pre>$ swig -python -threads example.i</pre></div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>
|
||||||
|
The <tt>threads</tt> module option in the *.i template file:
|
||||||
|
</p>
|
||||||
|
<div class="code"><pre>%feature("nothread") method;</pre></div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p>You can disable thread support for a given method:</p>
|
||||||
|
<div class="code"><pre>%module("threads"=1)</pre></div>
|
||||||
|
or
|
||||||
|
<div class="code"><pre>%nothread method;</pre></div>
|
||||||
|
</li>
|
||||||
|
<li><p>You can partially disable thread support for a given method:</p>
|
||||||
|
<ul>
|
||||||
|
<li><p>To disable the C++/python thread protection:</p>
|
||||||
|
<div class="code"><pre>%feature("nothreadblock") method;</pre></div>
|
||||||
|
or
|
||||||
|
<div class="code"><pre>%nothreadblock method;</pre></div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>To disable the python/C++ thread protection</p>
|
||||||
|
<div class="code"><pre>%feature("nothreadallow") method;</pre></div>
|
||||||
|
or
|
||||||
|
<div class="code"><pre>%nothreadallow method;</pre></div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<H3><a name="Python_thread_performance">36.13.2 Multithread Performance</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For the curious about performance, here are some numbers for the profiletest.i test,
|
||||||
|
which is used to check the speed of the wrapped code:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table summary="Python multithread performance">
|
||||||
|
<tr>
|
||||||
|
<th>Thread Mode</th>
|
||||||
|
<th>Execution Time (sec)</th>
|
||||||
|
<th>Comment</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Single Threaded</td>
|
||||||
|
<td>9.6</td>
|
||||||
|
<td>no "-threads" option given</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Fully Multithreaded</td>
|
||||||
|
<td>15.5</td>
|
||||||
|
<td>"-threads" option = 'allow' + 'block'</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>No Thread block</td>
|
||||||
|
<td>12.2</td>
|
||||||
|
<td>only 'allow'</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>No Thread Allow</td>
|
||||||
|
<td>13.6</td>
|
||||||
|
<td>only block'</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Fully threaded code decreases the wrapping performance by
|
||||||
|
around 60%. If that is important to your application, you
|
||||||
|
can tune each method using the different 'nothread',
|
||||||
|
'nothreadblock' or 'nothreadallow' features as
|
||||||
|
needed. Note that for some methods deactivating the
|
||||||
|
'thread block' or 'thread allow' code is not an option,
|
||||||
|
so, be careful.
|
||||||
|
</p>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ These two files can be loaded in any order
|
||||||
<li>If you do not set the output file name appropriately, you might see errors like
|
<li>If you do not set the output file name appropriately, you might see errors like
|
||||||
<div class="shell">
|
<div class="shell">
|
||||||
<pre>
|
<pre>
|
||||||
> fact(4)
|
> fact(4)
|
||||||
Error in .Call("R_swig_fact", s_arg1, as.logical(.copy), PACKAGE = "example") :
|
Error in .Call("R_swig_fact", s_arg1, as.logical(.copy), PACKAGE = "example") :
|
||||||
"R_swig_fact" not available for .Call() for package "example"
|
"R_swig_fact" not available for .Call() for package "example"
|
||||||
</pre>
|
</pre>
|
||||||
|
|
|
||||||
|
|
@ -1736,6 +1736,16 @@ already defined in the target scripting language. However, if you are
|
||||||
careful about namespaces and your use of modules, you can usually
|
careful about namespaces and your use of modules, you can usually
|
||||||
avoid these problems.</p>
|
avoid these problems.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When wrapping C code, simple use of identifiers/symbols with <tt>%rename</tt> usually suffices.
|
||||||
|
When wrapping C++ code, simple use of simple identifiers/symbols with <tt>%rename</tt> might be too
|
||||||
|
limiting when using C++ features such as function overloading, default arguments, namespaces, template specialization etc.
|
||||||
|
If you are using the <tt>%rename</tt> directive and C++, make sure you read the
|
||||||
|
<a href="SWIGPlus.html">SWIG and C++</a> chapter and in particular the section on
|
||||||
|
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
|
||||||
|
for method overloading and default arguments.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Closely related to <tt>%rename</tt> is the <tt>%ignore</tt> directive. <tt>%ignore</tt> instructs SWIG
|
Closely related to <tt>%rename</tt> is the <tt>%ignore</tt> directive. <tt>%ignore</tt> instructs SWIG
|
||||||
to ignore declarations that match a given identifier. For example:
|
to ignore declarations that match a given identifier. For example:
|
||||||
|
|
@ -2078,7 +2088,7 @@ except those consisting of capital letters only:
|
||||||
<p>
|
<p>
|
||||||
Finally, variants of <tt>%rename</tt> and <tt>%ignore</tt> directives can be used to help
|
Finally, variants of <tt>%rename</tt> and <tt>%ignore</tt> directives can be used to help
|
||||||
wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the
|
wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the
|
||||||
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section in the C++ chapter.
|
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a> section in the C++ chapter.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3293,11 +3303,27 @@ Vector *new_Vector() {
|
||||||
return (Vector *) malloc(sizeof(Vector));
|
return (Vector *) malloc(sizeof(Vector));
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The <tt>%inline</tt> directive inserts all of the code that follows
|
This is the same as writing:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code"><pre>
|
||||||
|
%{
|
||||||
|
/* Create a new vector */
|
||||||
|
Vector *new_Vector() {
|
||||||
|
return (Vector *) malloc(sizeof(Vector));
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
/* Create a new vector */
|
||||||
|
Vector *new_Vector() {
|
||||||
|
return (Vector *) malloc(sizeof(Vector));
|
||||||
|
}
|
||||||
|
</pre></div>
|
||||||
|
<p>
|
||||||
|
In other words, the <tt>%inline</tt> directive inserts all of the code that follows
|
||||||
verbatim into the header portion of an interface file. The code is
|
verbatim into the header portion of an interface file. The code is
|
||||||
then parsed by both the SWIG preprocessor and parser.
|
then parsed by both the SWIG preprocessor and parser.
|
||||||
Thus, the above example creates a new command <tt>new_Vector</tt> using only one
|
Thus, the above example creates a new command <tt>new_Vector</tt> using only one
|
||||||
|
|
@ -3305,6 +3331,11 @@ declaration. Since the code inside an <tt>%inline %{ ... %}</tt> block
|
||||||
is given to both the C compiler and SWIG, it is illegal to include any
|
is given to both the C compiler and SWIG, it is illegal to include any
|
||||||
SWIG directives inside a <tt>%{ ... %}</tt> block.</p>
|
SWIG directives inside a <tt>%{ ... %}</tt> block.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Note:</b> The usual SWIG C preprocessor rules apply to code in <tt>%apply</tt> blocks when SWIG parses this code. For example, as mentioned earlier, <a href="SWIG.html#SWIG_nn6">SWIG's C Preprocessor</a> does not follow <tt>#include</tt> directives by default.
|
||||||
|
</p>
|
||||||
|
|
||||||
<H3><a name="SWIG_nn44">5.6.4 Initialization blocks</a></H3>
|
<H3><a name="SWIG_nn44">5.6.4 Initialization blocks</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@
|
||||||
<li><a href="#SWIGPlus_nn12">Static members</a>
|
<li><a href="#SWIGPlus_nn12">Static members</a>
|
||||||
<li><a href="#SWIGPlus_member_data">Member data</a>
|
<li><a href="#SWIGPlus_member_data">Member data</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="#SWIGPlus_default_args">Default arguments</a>
|
|
||||||
<li><a href="#SWIGPlus_nn15">Protection</a>
|
<li><a href="#SWIGPlus_nn15">Protection</a>
|
||||||
<li><a href="#SWIGPlus_nn16">Enums and constants</a>
|
<li><a href="#SWIGPlus_nn16">Enums and constants</a>
|
||||||
<li><a href="#SWIGPlus_nn17">Friends</a>
|
<li><a href="#SWIGPlus_nn17">Friends</a>
|
||||||
|
|
@ -39,16 +38,27 @@
|
||||||
<li><a href="#SWIGPlus_nn19">Pass and return by value</a>
|
<li><a href="#SWIGPlus_nn19">Pass and return by value</a>
|
||||||
<li><a href="#SWIGPlus_nn20">Inheritance</a>
|
<li><a href="#SWIGPlus_nn20">Inheritance</a>
|
||||||
<li><a href="#SWIGPlus_nn21">A brief discussion of multiple inheritance, pointers, and type checking</a>
|
<li><a href="#SWIGPlus_nn21">A brief discussion of multiple inheritance, pointers, and type checking</a>
|
||||||
<li><a href="#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods</a>
|
<li><a href="#SWIGPlus_default_args">Default arguments</a>
|
||||||
|
<li><a href="#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#SWIGPlus_nn24">Dispatch function generation</a>
|
<li><a href="#SWIGPlus_nn24">Dispatch function generation</a>
|
||||||
<li><a href="#SWIGPlus_nn25">Ambiguity in Overloading</a>
|
<li><a href="#SWIGPlus_nn25">Ambiguity in overloading</a>
|
||||||
<li><a href="#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
|
<li><a href="#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
|
||||||
<li><a href="#SWIGPlus_nn27">Comments on overloading</a>
|
<li><a href="#SWIGPlus_nn27">Comments on overloading</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="#SWIGPlus_nn28">Wrapping overloaded operators</a>
|
<li><a href="#SWIGPlus_nn28">Overloaded operators</a>
|
||||||
<li><a href="#SWIGPlus_class_extension">Class extension</a>
|
<li><a href="#SWIGPlus_class_extension">Class extension</a>
|
||||||
<li><a href="#SWIGPlus_nn30">Templates</a>
|
<li><a href="#SWIGPlus_nn30">Templates</a>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#SWIGPlus_template_directive">The %template directive</a>
|
||||||
|
<li><a href="#SWIGPlus_template_functions">Function templates</a>
|
||||||
|
<li><a href="#SWIGPlus_template_classes">Default template arguments</a>
|
||||||
|
<li><a href="#SWIGPlus_template_class_inheritance">Template base classes</a>
|
||||||
|
<li><a href="#SWIGPlus_template_specialization">Template specialization</a>
|
||||||
|
<li><a href="#SWIGPlus_template_member">Member templates</a>
|
||||||
|
<li><a href="#SWIGPlus_template_scoping">Scoping and templates</a>
|
||||||
|
<li><a href="#SWIGPlus_template_more">More on templates</a>
|
||||||
|
</ul>
|
||||||
<li><a href="#SWIGPlus_namespaces">Namespaces</a>
|
<li><a href="#SWIGPlus_namespaces">Namespaces</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#SWIGPlus_nspace">The nspace feature for namespaces</a>
|
<li><a href="#SWIGPlus_nspace">The nspace feature for namespaces</a>
|
||||||
|
|
@ -1094,113 +1104,7 @@ a few problems related to structure wrapping and some of SWIG's
|
||||||
customization features.
|
customization features.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="SWIGPlus_default_args">6.7 Default arguments</a></H2>
|
<H2><a name="SWIGPlus_nn15">6.7 Protection</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
SWIG will wrap all types of functions that have default arguments. For example member functions:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="code">
|
|
||||||
<pre>
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
void bar(int x, int y = 3, int z = 4);
|
|
||||||
};
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
SWIG handles default arguments by generating an extra overloaded method for each defaulted argument.
|
|
||||||
SWIG is effectively handling methods with default arguments as if it was wrapping the equivalent overloaded methods.
|
|
||||||
Thus for the example above, it is as if we had instead given the following to SWIG:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="code">
|
|
||||||
<pre>
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
void bar(int x, int y, int z);
|
|
||||||
void bar(int x, int y);
|
|
||||||
void bar(int x);
|
|
||||||
};
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The wrappers produced are exactly the same as if the above code was instead fed into SWIG.
|
|
||||||
Details of this are covered later in the <a href="#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods</a> section.
|
|
||||||
This approach allows SWIG to wrap all possible default arguments, but can be verbose.
|
|
||||||
For example if a method has ten default arguments, then eleven wrapper methods are generated.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Please see the <a href="Customization.html#Customization_features_default_args">Features and default arguments</a>
|
|
||||||
section for more information on using <tt>%feature</tt> with functions with default arguments.
|
|
||||||
The <a href="#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section
|
|
||||||
also deals with using <tt>%rename</tt> and <tt>%ignore</tt> on methods with default arguments.
|
|
||||||
If you are writing your own typemaps for types used in methods with default arguments, you may also need to write a <tt>typecheck</tt> typemap.
|
|
||||||
See the <a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a> section for details or otherwise
|
|
||||||
use the <tt>compactdefaultargs</tt> feature flag as mentioned below.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<b>Compatibility note:</b> Versions of SWIG prior to SWIG-1.3.23 wrapped default arguments slightly differently.
|
|
||||||
Instead a single wrapper method was generated and the default values were copied into the C++ wrappers
|
|
||||||
so that the method being wrapped was then called with all the arguments specified.
|
|
||||||
If the size of the wrappers are a concern then this approach to wrapping methods with default arguments
|
|
||||||
can be re-activated by using the <tt>compactdefaultargs</tt>
|
|
||||||
<a href="Customization.html#Customization_feature_flags">feature flag</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="code">
|
|
||||||
<pre>
|
|
||||||
%feature("compactdefaultargs") Foo::bar;
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
void bar(int x, int y = 3, int z = 4);
|
|
||||||
};
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This is great for reducing the size of the wrappers, but the caveat is it does not work for the statically typed languages,
|
|
||||||
such as C# and Java,
|
|
||||||
which don't have optional arguments in the language,
|
|
||||||
Another restriction of this feature is that it cannot handle default arguments that are not public.
|
|
||||||
The following example illustrates this:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="code">
|
|
||||||
<pre>
|
|
||||||
class Foo {
|
|
||||||
private:
|
|
||||||
static const int spam;
|
|
||||||
public:
|
|
||||||
void bar(int x, int y = spam); // Won't work with %feature("compactdefaultargs") -
|
|
||||||
// private default value
|
|
||||||
};
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This produces uncompilable wrapper code because default values in C++ are
|
|
||||||
evaluated in the same scope as the member function whereas SWIG
|
|
||||||
evaluates them in the scope of a wrapper function (meaning that the
|
|
||||||
values have to be public).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <tt>compactdefaultargs</tt> feature is automatically turned on when wrapping <a href="SWIG.html#SWIG_default_args">C code with default arguments</a>.
|
|
||||||
Some target languages will also automatically turn on this feature
|
|
||||||
if the keyword arguments feature (kwargs) is specified for either C or C++ functions, and the target language supports kwargs,
|
|
||||||
the <tt>compactdefaultargs</tt> feature is also automatically turned on.
|
|
||||||
Keyword arguments are a language feature of some scripting languages, for example Ruby and Python.
|
|
||||||
SWIG is unable to support kwargs when wrapping overloaded methods, so the default approach cannot be used.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<H2><a name="SWIGPlus_nn15">6.8 Protection</a></H2>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1220,7 +1124,7 @@ until you explicitly give a `<tt>public:</tt>' declaration (This is
|
||||||
the same convention used by C++).
|
the same convention used by C++).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="SWIGPlus_nn16">6.9 Enums and constants</a></H2>
|
<H2><a name="SWIGPlus_nn16">6.8 Enums and constants</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1250,7 +1154,7 @@ Swig_STOUT = Swig::STOUT
|
||||||
Members declared as <tt>const</tt> are wrapped as read-only members and do not create constants.
|
Members declared as <tt>const</tt> are wrapped as read-only members and do not create constants.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="SWIGPlus_nn17">6.10 Friends</a></H2>
|
<H2><a name="SWIGPlus_nn17">6.9 Friends</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1311,7 +1215,7 @@ namespace bar {
|
||||||
and a wrapper for the method 'blah' will not be generated.
|
and a wrapper for the method 'blah' will not be generated.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="SWIGPlus_nn18">6.11 References and pointers</a></H2>
|
<H2><a name="SWIGPlus_nn18">6.10 References and pointers</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1411,7 +1315,7 @@ templates and the STL. This was first added in SWIG-1.3.12.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<H2><a name="SWIGPlus_nn19">6.12 Pass and return by value</a></H2>
|
<H2><a name="SWIGPlus_nn19">6.11 Pass and return by value</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1515,7 +1419,7 @@ classes that don't define a default constructor.
|
||||||
It is not used for C++ pointers or references.
|
It is not used for C++ pointers or references.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="SWIGPlus_nn20">6.13 Inheritance</a></H2>
|
<H2><a name="SWIGPlus_nn20">6.12 Inheritance</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1701,7 +1605,7 @@ functions for virtual members that are already defined in a base
|
||||||
class.
|
class.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="SWIGPlus_nn21">6.14 A brief discussion of multiple inheritance, pointers, and type checking</a></H2>
|
<H2><a name="SWIGPlus_nn21">6.13 A brief discussion of multiple inheritance, pointers, and type checking</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1833,7 +1737,113 @@ int y = B_function((B *) pB);
|
||||||
In practice, the pointer is held as an integral number in the target language proxy class.
|
In practice, the pointer is held as an integral number in the target language proxy class.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="SWIGPlus_overloaded_methods">6.15 Wrapping Overloaded Functions and Methods</a></H2>
|
<H2><a name="SWIGPlus_default_args">6.14 Default arguments</a></H2>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
SWIG will wrap all types of functions that have default arguments. For example member functions:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
void bar(int x, int y = 3, int z = 4);
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
SWIG handles default arguments by generating an extra overloaded method for each defaulted argument.
|
||||||
|
SWIG is effectively handling methods with default arguments as if it was wrapping the equivalent overloaded methods.
|
||||||
|
Thus for the example above, it is as if we had instead given the following to SWIG:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
void bar(int x, int y, int z);
|
||||||
|
void bar(int x, int y);
|
||||||
|
void bar(int x);
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The wrappers produced are exactly the same as if the above code was instead fed into SWIG.
|
||||||
|
Details of this are covered in the next section <a href="#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>.
|
||||||
|
This approach allows SWIG to wrap all possible default arguments, but can be verbose.
|
||||||
|
For example if a method has ten default arguments, then eleven wrapper methods are generated.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please see the <a href="Customization.html#Customization_features_default_args">Features and default arguments</a>
|
||||||
|
section for more information on using <tt>%feature</tt> with functions with default arguments.
|
||||||
|
The <a href="#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a> section
|
||||||
|
also deals with using <tt>%rename</tt> and <tt>%ignore</tt> on methods with default arguments.
|
||||||
|
If you are writing your own typemaps for types used in methods with default arguments, you may also need to write a <tt>typecheck</tt> typemap.
|
||||||
|
See the <a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a> section for details or otherwise
|
||||||
|
use the <tt>compactdefaultargs</tt> feature flag as mentioned below.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Compatibility note:</b> Versions of SWIG prior to SWIG-1.3.23 wrapped default arguments slightly differently.
|
||||||
|
Instead a single wrapper method was generated and the default values were copied into the C++ wrappers
|
||||||
|
so that the method being wrapped was then called with all the arguments specified.
|
||||||
|
If the size of the wrappers are a concern then this approach to wrapping methods with default arguments
|
||||||
|
can be re-activated by using the <tt>compactdefaultargs</tt>
|
||||||
|
<a href="Customization.html#Customization_feature_flags">feature flag</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%feature("compactdefaultargs") Foo::bar;
|
||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
void bar(int x, int y = 3, int z = 4);
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This is great for reducing the size of the wrappers, but the caveat is it does not work for the statically typed languages,
|
||||||
|
such as C# and Java,
|
||||||
|
which don't have optional arguments in the language,
|
||||||
|
Another restriction of this feature is that it cannot handle default arguments that are not public.
|
||||||
|
The following example illustrates this:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
class Foo {
|
||||||
|
private:
|
||||||
|
static const int spam;
|
||||||
|
public:
|
||||||
|
void bar(int x, int y = spam); // Won't work with %feature("compactdefaultargs") -
|
||||||
|
// private default value
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This produces uncompilable wrapper code because default values in C++ are
|
||||||
|
evaluated in the same scope as the member function whereas SWIG
|
||||||
|
evaluates them in the scope of a wrapper function (meaning that the
|
||||||
|
values have to be public).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <tt>compactdefaultargs</tt> feature is automatically turned on when wrapping <a href="SWIG.html#SWIG_default_args">C code with default arguments</a>.
|
||||||
|
Some target languages will also automatically turn on this feature
|
||||||
|
if the keyword arguments feature (kwargs) is specified for either C or C++ functions, and the target language supports kwargs,
|
||||||
|
the <tt>compactdefaultargs</tt> feature is also automatically turned on.
|
||||||
|
Keyword arguments are a language feature of some scripting languages, for example Ruby and Python.
|
||||||
|
SWIG is unable to support kwargs when wrapping overloaded methods, so the default approach cannot be used.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<H2><a name="SWIGPlus_overloaded_methods">6.15 Overloaded functions and methods</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -2021,7 +2031,7 @@ checked in the same order as they appear in this ranking.
|
||||||
If you're still confused, don't worry about it---SWIG is probably doing the right thing.
|
If you're still confused, don't worry about it---SWIG is probably doing the right thing.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H3><a name="SWIGPlus_nn25">6.15.2 Ambiguity in Overloading</a></H3>
|
<H3><a name="SWIGPlus_nn25">6.15.2 Ambiguity in overloading</a></H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -2139,7 +2149,7 @@ it means that the target language module has not yet implemented support for ove
|
||||||
functions and methods. The only way to fix the problem is to read the next section.
|
functions and methods. The only way to fix the problem is to read the next section.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H3><a name="SWIGPlus_ambiguity_resolution_renaming">6.15.3 Ambiguity resolution and renaming</a></H3>
|
<H3><a name="SWIGPlus_ambiguity_resolution_renaming">6.15.3 Renaming and ambiguity resolution</a></H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -2399,8 +2409,8 @@ the first renaming rule found on a depth-first traversal of the class hierarchy
|
||||||
is used.
|
is used.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li><p>The name matching rules strictly follow member qualification rules.
|
<li><p>The name matching rules strictly follow member qualifier rules.
|
||||||
For example, if you have a class like this:</p>
|
For example, if you have a class and member with a member that is const qualified like this:</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
|
|
@ -2424,7 +2434,7 @@ the declaration
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
will not apply as there is no unqualified member <tt>bar()</tt>. The following will apply as
|
will not apply as there is no unqualified member <tt>bar()</tt>. The following will apply the rename as
|
||||||
the qualifier matches correctly:
|
the qualifier matches correctly:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -2434,6 +2444,26 @@ the qualifier matches correctly:
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Similarly for combinations of cv-qualifiers and ref-qualifiers, all the qualifiers must be specified to match correctly:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%rename(name) Jam::bar(); // will not match
|
||||||
|
%rename(name) Jam::bar() &; // will not match
|
||||||
|
%rename(name) Jam::bar() const; // will not match
|
||||||
|
%rename(name) Jam::bar() const &; // ok, will match
|
||||||
|
|
||||||
|
class Jam {
|
||||||
|
public:
|
||||||
|
...
|
||||||
|
void bar() const &;
|
||||||
|
...
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
An often overlooked C++ feature is that classes can define two different overloaded members
|
An often overlooked C++ feature is that classes can define two different overloaded members
|
||||||
that differ only in their qualifiers, like this:
|
that differ only in their qualifiers, like this:
|
||||||
|
|
@ -2466,7 +2496,7 @@ For example we can give them separate names in the target language:
|
||||||
<p>
|
<p>
|
||||||
Similarly, if you
|
Similarly, if you
|
||||||
merely wanted to ignore one of the declarations, use <tt>%ignore</tt>
|
merely wanted to ignore one of the declarations, use <tt>%ignore</tt>
|
||||||
with the full qualification. For example, the following directive
|
with the full qualifier. For example, the following directive
|
||||||
would tell SWIG to ignore the <tt>const</tt> version of <tt>bar()</tt>
|
would tell SWIG to ignore the <tt>const</tt> version of <tt>bar()</tt>
|
||||||
above:
|
above:
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -2532,8 +2562,7 @@ exactly matches the wrapped method:
|
||||||
<p>
|
<p>
|
||||||
The C++ method can then be called from the target language with the new name no matter how many arguments are specified, for example:
|
The C++ method can then be called from the target language with the new name no matter how many arguments are specified, for example:
|
||||||
<tt>newbar(2, 2.0)</tt>, <tt>newbar(2)</tt> or <tt>newbar()</tt>.
|
<tt>newbar(2, 2.0)</tt>, <tt>newbar(2)</tt> or <tt>newbar()</tt>.
|
||||||
However, if the <tt>%rename</tt> does not contain the default arguments, it will only apply to the single equivalent target language overloaded method.
|
However, if the <tt>%rename</tt> does not contain the default arguments:
|
||||||
So if instead we have:
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
|
|
@ -2542,9 +2571,24 @@ So if instead we have:
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
then only one of the three equivalent overloaded methods will be renamed and wrapped as if SWIG parsed:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
void Spam::newbar(int i, double d);
|
||||||
|
void Spam::bar(int i);
|
||||||
|
void Spam::bar();
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The C++ method must then be called from the target language with the new name <tt>newbar(2, 2.0)</tt> when both arguments are supplied
|
The C++ method must then be called from the target language with the new name <tt>newbar(2, 2.0)</tt> when both arguments are supplied
|
||||||
or with the original name as <tt>bar(2)</tt> (one argument) or <tt>bar()</tt> (no arguments).
|
or with the original name as <tt>bar(2)</tt> (one argument) or <tt>bar()</tt> (no arguments).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
In fact it is possible to use <tt>%rename</tt> on the equivalent overloaded methods, to rename all the equivalent overloaded methods:
|
In fact it is possible to use <tt>%rename</tt> on the equivalent overloaded methods, to rename all the equivalent overloaded methods:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -2586,7 +2630,7 @@ As a general rule, statically typed languages like Java are able to provide more
|
||||||
than dynamically typed languages like Perl, Python, Ruby, and Tcl.
|
than dynamically typed languages like Perl, Python, Ruby, and Tcl.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="SWIGPlus_nn28">6.16 Wrapping overloaded operators</a></H2>
|
<H2><a name="SWIGPlus_nn28">6.16 Overloaded operators</a></H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -2779,7 +2823,7 @@ into two methods such that additional logic can be packed into the operations; C
|
||||||
<tt>this[type key] { get { ... } set { ... }}</tt>, Python uses
|
<tt>this[type key] { get { ... } set { ... }}</tt>, Python uses
|
||||||
<tt>__getitem__</tt> and <tt>__setitem__</tt>, etc. In C++ if the return
|
<tt>__getitem__</tt> and <tt>__setitem__</tt>, etc. In C++ if the return
|
||||||
type of <tt>operator[]</tt> is a reference and the method is const, it is often indicative of the <i>setter</i>,
|
type of <tt>operator[]</tt> is a reference and the method is const, it is often indicative of the <i>setter</i>,
|
||||||
and and the <i>getter</i> is usually a const function return an object by value.
|
and the <i>getter</i> is usually a const function return an object by value.
|
||||||
In the absence of any hard and fast rules and the fact that there may be multiple index operators,
|
In the absence of any hard and fast rules and the fact that there may be multiple index operators,
|
||||||
it is up to the user to choose the getter and setter to use by using %rename as shown earlier.
|
it is up to the user to choose the getter and setter to use by using %rename as shown earlier.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -2936,10 +2980,12 @@ as <tt>vector<int></tt>. The wrapper for <tt>foo()</tt> will
|
||||||
accept either variant.
|
accept either variant.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<H3><a name="SWIGPlus_template_directive">6.18.1 The %template directive</a></H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Starting with SWIG-1.3.7, simple C++ template declarations can also be
|
There are a couple of important points about template wrapping.
|
||||||
wrapped. SWIG-1.3.12 greatly expands upon the earlier implementation. Before discussing this any further, there are a few things
|
First, a bare C++ template
|
||||||
you need to know about template wrapping. First, a bare C++ template
|
|
||||||
does not define any sort of runnable object-code for which SWIG can
|
does not define any sort of runnable object-code for which SWIG can
|
||||||
normally create a wrapper. Therefore, in order to wrap a template,
|
normally create a wrapper. Therefore, in order to wrap a template,
|
||||||
you need to give SWIG information about a particular template
|
you need to give SWIG information about a particular template
|
||||||
|
|
@ -2947,12 +2993,11 @@ instantiation (e.g., <tt>vector<int></tt>,
|
||||||
<tt>array<double></tt>, etc.). Second, an instantiation name
|
<tt>array<double></tt>, etc.). Second, an instantiation name
|
||||||
such as <tt>vector<int></tt> is generally not a valid identifier
|
such as <tt>vector<int></tt> is generally not a valid identifier
|
||||||
name in most target languages. Thus, you will need to give the
|
name in most target languages. Thus, you will need to give the
|
||||||
template instantiation a more suitable name such as <tt>intvector</tt>
|
template instantiation a more suitable name such as <tt>intvector</tt>.
|
||||||
when creating a wrapper.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To illustrate, consider the following template definition:
|
To illustrate, consider the following class template definition:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
|
|
@ -2985,14 +3030,26 @@ public:
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
By itself, this template declaration is useless--SWIG simply ignores it
|
By itself, this class template is useless--SWIG simply ignores it
|
||||||
because it doesn't know how to generate any code until unless a definition of
|
because it doesn't know how to generate any code unless a definition of
|
||||||
<tt>T</tt> is provided.
|
<tt>T</tt> is provided.
|
||||||
|
The <tt>%template</tt> directive is required to instantiate the template for use in a target language.
|
||||||
|
The directive requires an identifier name for use in the target language plus the template for instantiation.
|
||||||
|
The example below instantiates <tt>List<int></tt> for use as a class named <tt>intList</tt>:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%template(intList) List<int>;
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
One way to create wrappers for a specific template instantiation is to simply
|
The instantiation expands the template code as a C++ compiler would do and then makes it available
|
||||||
provide an expanded version of the class directly like this:
|
under the given identifier name.
|
||||||
|
Essentially it is the same as wrapping the following concept code where
|
||||||
|
the class template definition has <tt>T</TT> expanded to <tt>int</tt>
|
||||||
|
(note that this is not entirely valid syntax):
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
|
|
@ -3014,28 +3071,6 @@ public:
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <tt>%rename</tt> directive is needed to give the template class an appropriate identifier
|
|
||||||
name in the target language (most languages would not recognize C++ template syntax as a valid
|
|
||||||
class name). The rest of the code is the same as what would appear in a normal
|
|
||||||
class definition.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Since manual expansion of templates gets old in a hurry, the <tt>%template</tt> directive can
|
|
||||||
be used to create instantiations of a template class. Semantically, <tt>%template</tt> is
|
|
||||||
simply a shortcut---it expands template code in exactly the same way as shown above. Here
|
|
||||||
are some examples:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="code">
|
|
||||||
<pre>
|
|
||||||
/* Instantiate a few different versions of the template */
|
|
||||||
%template(intList) List<int>;
|
|
||||||
%template(doubleList) List<double>;
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The argument to <tt>%template()</tt> is the name of the instantiation
|
The argument to <tt>%template()</tt> is the name of the instantiation
|
||||||
in the target language. The name you choose should not conflict with
|
in the target language. The name you choose should not conflict with
|
||||||
|
|
@ -3053,7 +3088,81 @@ typedef List<int> intList; // OK
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
SWIG can also generate wrappers for function templates using a similar technique.
|
The <tt>%template</tt> directive
|
||||||
|
must always appear <em>after</em> the definition of the template to be expanded, so the following will work:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
template<class T> class List { ... };
|
||||||
|
%template(intList) List<int>;
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
but if %template is used before the template definition, such as:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%template(intList) List<int>;
|
||||||
|
template<class T> class List { ... };
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
SWIG will generate an error:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="shell">
|
||||||
|
<pre>
|
||||||
|
example.i:3: Error: Template 'List' undefined.
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Since the type system knows how to handle <tt>typedef</tt>, it is
|
||||||
|
generally not necessary to instantiate different versions of a template
|
||||||
|
for typenames that are equivalent. For instance, consider this code:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%template(intList) List<int>;
|
||||||
|
typedef int Integer;
|
||||||
|
...
|
||||||
|
void foo(List<Integer> *x);
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In this case, <tt>List<Integer></tt> is exactly the same type as
|
||||||
|
<tt>List<int></tt>. Any use of <tt>List<Integer></tt> is mapped back to the
|
||||||
|
instantiation of <tt>List<int></tt> created earlier. Therefore, it is
|
||||||
|
not necessary to instantiate a new class for the type <tt>Integer</tt> (doing so is
|
||||||
|
redundant and will simply result in code bloat).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The template provide to <tt>%template</tt> for instantiation must be the actual template and not a typedef to a template.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
typedef List<int> ListOfInt;
|
||||||
|
|
||||||
|
%template(intList) List<int>; // ok
|
||||||
|
%template(intList) ListOfInt; // illegal - Syntax error
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<H3><a name="SWIGPlus_template_functions">6.18.2 Function templates</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
SWIG can also generate wrappers for function templates using a similar technique
|
||||||
|
to that shown above for class templates.
|
||||||
For example:
|
For example:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -3073,6 +3182,28 @@ In this case, <tt>maxint</tt> and <tt>maxdouble</tt> become unique names for spe
|
||||||
instantiations of the function.
|
instantiations of the function.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
SWIG even supports overloaded templated functions. As usual the <tt>%template</tt> directive
|
||||||
|
is used to wrap templated functions. For example:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
template<class T> void foo(T x) { };
|
||||||
|
template<class T> void foo(T x, T y) { };
|
||||||
|
|
||||||
|
%template(foo) foo<int>;
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This will generate two overloaded wrapper methods, the first will take a single integer as an argument
|
||||||
|
and the second will take two integer arguments.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<H3><a name="SWIGPlus_template_classes">6.18.3 Default template arguments</a></H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The number of arguments supplied to <tt>%template</tt> should match that in the
|
The number of arguments supplied to <tt>%template</tt> should match that in the
|
||||||
original template definition. Template default arguments are supported. For example:
|
original template definition. Template default arguments are supported. For example:
|
||||||
|
|
@ -3110,28 +3241,8 @@ instantiation only once in order to reduce the potential for code
|
||||||
bloat.
|
bloat.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<H3><a name="SWIGPlus_template_class_inheritance">6.18.4 Template base classes</a></H3>
|
||||||
Since the type system knows how to handle <tt>typedef</tt>, it is
|
|
||||||
generally not necessary to instantiate different versions of a template
|
|
||||||
for typenames that are equivalent. For instance, consider this code:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="code">
|
|
||||||
<pre>
|
|
||||||
%template(intList) vector<int>;
|
|
||||||
typedef int Integer;
|
|
||||||
...
|
|
||||||
void foo(vector<Integer> *x);
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
In this case, <tt>vector<Integer></tt> is exactly the same type as
|
|
||||||
<tt>vector<int></tt>. Any use of <tt>Vector<Integer></tt> is mapped back to the
|
|
||||||
instantiation of <tt>vector<int></tt> created earlier. Therefore, it is
|
|
||||||
not necessary to instantiate a new class for the type <tt>Integer</tt> (doing so is
|
|
||||||
redundant and will simply result in code bloat).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
When a template is instantiated using <tt>%template</tt>, information
|
When a template is instantiated using <tt>%template</tt>, information
|
||||||
|
|
@ -3158,13 +3269,13 @@ nothing is known about <tt>List<int></tt>, you will get a warning message
|
||||||
|
|
||||||
<div class="shell">
|
<div class="shell">
|
||||||
<pre>
|
<pre>
|
||||||
example.h:42: Warning 401. Nothing known about class 'List<int >'. Ignored.
|
example.h:42: Warning 401. Nothing known about class 'List< int >'. Ignored.
|
||||||
example.h:42: Warning 401. Maybe you forgot to instantiate 'List<int >' using %template.
|
example.h:42: Warning 401. Maybe you forgot to instantiate 'List< int >' using %template.
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If a template class inherits from another template class, you need to
|
If a class template inherits from another class template, you need to
|
||||||
make sure that base classes are instantiated before derived classes.
|
make sure that base classes are instantiated before derived classes.
|
||||||
For example:
|
For example:
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -3235,6 +3346,9 @@ TEMPLATE_WRAP(PairStringInt, std::pair<string, int>)
|
||||||
Note the use of a vararg macro for the type T. If this wasn't used, the comma in the templated type in the last example would not be possible.
|
Note the use of a vararg macro for the type T. If this wasn't used, the comma in the templated type in the last example would not be possible.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<H3><a name="SWIGPlus_template_specialization">6.18.5 Template specialization</a></H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The SWIG template mechanism <em>does</em> support specialization. For instance, if you define
|
The SWIG template mechanism <em>does</em> support specialization. For instance, if you define
|
||||||
a class like this,
|
a class like this,
|
||||||
|
|
@ -3281,7 +3395,7 @@ private:
|
||||||
public:
|
public:
|
||||||
List(int max);
|
List(int max);
|
||||||
~List();
|
~List();
|
||||||
void append(int obj);
|
void append(T obj);
|
||||||
int length();
|
int length();
|
||||||
T get(int n);
|
T get(int n);
|
||||||
};
|
};
|
||||||
|
|
@ -3322,10 +3436,13 @@ SWIG implements template argument deduction so that the following partial specia
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<H3><a name="SWIGPlus_template_member">6.18.6 Member templates</a></H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Member function templates are supported. The underlying principle is the same
|
Member templates are supported. The underlying principle is the same
|
||||||
as for normal templates--SWIG can't create a wrapper unless you provide
|
as for normal templates--SWIG can't create a wrapper unless you provide
|
||||||
more information about types. For example, a class with a member template might
|
more information about types. For example, a class with a member function template might
|
||||||
look like this:
|
look like this:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -3399,11 +3516,6 @@ methods to the Foo class.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Note: because of the way that templates are handled, the <tt>%template</tt> directive
|
|
||||||
must always appear <em>after</em> the definition of the template to be expanded.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Now, if your target language supports overloading, you can even try
|
Now, if your target language supports overloading, you can even try
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -3424,7 +3536,7 @@ depending on the argument type.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
When used with members, the <tt>%template</tt> directive may be placed in another
|
When used with members, the <tt>%template</tt> directive may be placed in another
|
||||||
template class. Here is a slightly perverse example:
|
class template. Here is a slightly perverse example:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
|
|
@ -3475,7 +3587,7 @@ template<class T1, class T2> struct pair {
|
||||||
<p>
|
<p>
|
||||||
This declaration is perfectly acceptable to SWIG, but the constructor template will be ignored
|
This declaration is perfectly acceptable to SWIG, but the constructor template will be ignored
|
||||||
unless you explicitly expand it. To do that, you could expand a few versions of the constructor
|
unless you explicitly expand it. To do that, you could expand a few versions of the constructor
|
||||||
in the template class itself. For example:
|
in the class template itself. For example:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
|
|
@ -3536,6 +3648,110 @@ constructor, that will dispatch the proper call depending on the argument
|
||||||
type.
|
type.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<H3><a name="SWIGPlus_template_scoping">6.18.7 Scoping and templates</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <tt>%template</tt> directive for a class template is the equivalent to an explicit instantiation
|
||||||
|
of a C++ class template. The scope for a valid <tt>%template</tt> instantiation is the same
|
||||||
|
as the scope required for a valid explicit instantiation of a C++ template.
|
||||||
|
A definition of the template for the explicit instantiation must be in scope
|
||||||
|
where the instantiation is declared and must not be enclosed within a different namespace.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For example, a few <tt>%template</tt> instantiations and C++ explicit instantiations are shown below:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
namespace N {
|
||||||
|
template<typename T> class C {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// valid
|
||||||
|
%template(cin) N::C<int>;
|
||||||
|
template class N::C<int>;
|
||||||
|
|
||||||
|
// valid
|
||||||
|
namespace N {
|
||||||
|
%template(cin) C<int>;
|
||||||
|
template class C<int>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// valid
|
||||||
|
using namespace N;
|
||||||
|
%template(cin) C<int>;
|
||||||
|
template class C<int>;
|
||||||
|
|
||||||
|
// valid
|
||||||
|
using N::C;
|
||||||
|
%template(cin) C<int>;
|
||||||
|
template class C<int>;
|
||||||
|
|
||||||
|
// ill-formed
|
||||||
|
namespace unrelated {
|
||||||
|
using N::C;
|
||||||
|
%template(cin) C<int>;
|
||||||
|
template class C<int>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ill-formed
|
||||||
|
namespace unrelated {
|
||||||
|
using namespace N;
|
||||||
|
%template(cin) C<int>;
|
||||||
|
template class C<int>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ill-formed
|
||||||
|
namespace unrelated {
|
||||||
|
namespace N {
|
||||||
|
%template(cin) C<int>;
|
||||||
|
template class C<int>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ill-formed
|
||||||
|
namespace unrelated {
|
||||||
|
%template(cin) N::C<int>;
|
||||||
|
template class N::C<int>;
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When the scope is incorrect, such as for the ill-formed examples above, an error occurs:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="shell">
|
||||||
|
<pre>
|
||||||
|
cpp_template_scope.i:34: Error: 'C' resolves to 'N::C' and was incorrectly instantiated
|
||||||
|
in scope 'unrelated' instead of within scope 'N'.
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A note for the C++ standard geeks out there; a valid instantiation is one which conforms to
|
||||||
|
the C++03 standard as C++11 made a change to disallow using declarations and using directives to find a template.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
// valid C++03, ill-formed C++11
|
||||||
|
using N::C;
|
||||||
|
template class C<int>;
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Compatibility Note</b>: Versions prior to SWIG-4.0.0 did not error out with incorrectly scoped
|
||||||
|
<tt>%template</tt> declarations, but this led to numerous subtle template scope problems.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<H3><a name="SWIGPlus_template_more">6.18.8 More on templates</a></H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If all of this isn't quite enough and you really want to make
|
If all of this isn't quite enough and you really want to make
|
||||||
someone's head explode, SWIG directives such as
|
someone's head explode, SWIG directives such as
|
||||||
|
|
@ -3568,7 +3784,7 @@ instantiation.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
It is also possible to separate these declarations from the template class. For example:
|
It is also possible to separate these declarations from the class template. For example:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
|
|
@ -3616,25 +3832,6 @@ additional methods to a specific instantiation. For example:
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
|
||||||
SWIG even supports overloaded templated functions. As usual the <tt>%template</tt> directive
|
|
||||||
is used to wrap templated functions. For example:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="code">
|
|
||||||
<pre>
|
|
||||||
template<class T> void foo(T x) { };
|
|
||||||
template<class T> void foo(T x, T y) { };
|
|
||||||
|
|
||||||
%template(foo) foo<int>;
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This will generate two overloaded wrapper methods, the first will take a single integer as an argument
|
|
||||||
and the second will take two integer arguments.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
It is even possible to extend a class via <tt>%extend</tt> with template methods, for example:
|
It is even possible to extend a class via <tt>%extend</tt> with template methods, for example:
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -3694,7 +3891,7 @@ For example:
|
||||||
<pre>
|
<pre>
|
||||||
template <class T> class OuterTemplateClass {};
|
template <class T> class OuterTemplateClass {};
|
||||||
|
|
||||||
// The nested class OuterClass::InnerClass inherits from the template class
|
// The nested class OuterClass::InnerClass inherits from the class template
|
||||||
// OuterTemplateClass<OuterClass::InnerStruct> and thus the template needs
|
// OuterTemplateClass<OuterClass::InnerStruct> and thus the template needs
|
||||||
// to be expanded with %template before the OuterClass declaration.
|
// to be expanded with %template before the OuterClass declaration.
|
||||||
%template(OuterTemplateClass_OuterClass__InnerStruct)
|
%template(OuterTemplateClass_OuterClass__InnerStruct)
|
||||||
|
|
@ -3915,6 +4112,8 @@ then SWIG simply creates three wrapper functions <tt>bar()</tt>,
|
||||||
<tt>spam()</tt>, and <tt>blah()</tt> in the target language. SWIG
|
<tt>spam()</tt>, and <tt>blah()</tt> in the target language. SWIG
|
||||||
does not prepend the names with a namespace prefix nor are the
|
does not prepend the names with a namespace prefix nor are the
|
||||||
functions packaged in any kind of nested scope.
|
functions packaged in any kind of nested scope.
|
||||||
|
Note that the default handling of flattening all the namespace scopes in the target language
|
||||||
|
can be changed via the <a href="#SWIGPlus_nspace">nspace feature</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -4203,9 +4402,7 @@ namespace foo {
|
||||||
<p>
|
<p>
|
||||||
<b>Note:</b> The flattening of namespaces is only intended to serve as
|
<b>Note:</b> The flattening of namespaces is only intended to serve as
|
||||||
a basic namespace implementation.
|
a basic namespace implementation.
|
||||||
None of the target language modules are currently programmed
|
More advanced handling of namespaces is discussed next.
|
||||||
with any namespace awareness. In the future, language modules may or may not provide
|
|
||||||
more advanced namespace support.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H3><a name="SWIGPlus_nspace">6.19.1 The nspace feature for namespaces</a></H3>
|
<H3><a name="SWIGPlus_nspace">6.19.1 The nspace feature for namespaces</a></H3>
|
||||||
|
|
@ -4524,7 +4721,7 @@ for member pointers.
|
||||||
<p>
|
<p>
|
||||||
In some C++ programs, objects are often encapsulated by smart-pointers
|
In some C++ programs, objects are often encapsulated by smart-pointers
|
||||||
or proxy classes. This is sometimes done to implement automatic memory management (reference counting) or
|
or proxy classes. This is sometimes done to implement automatic memory management (reference counting) or
|
||||||
persistence. Typically a smart-pointer is defined by a template class where
|
persistence. Typically a smart-pointer is defined by a class template where
|
||||||
the <tt>-></tt> operator has been overloaded. This class is then wrapped
|
the <tt>-></tt> operator has been overloaded. This class is then wrapped
|
||||||
around some other class. For example:
|
around some other class. For example:
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,11 @@ The following table lists the Scilab specific command line options in addition t
|
||||||
<td>Generate the gateway XML with the given <gateway_id></td>
|
<td>Generate the gateway XML with the given <gateway_id></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><tt>-targetversion</tt></td>
|
||||||
|
<td>Generate for Scilab target (major) version</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -331,13 +336,17 @@ There are a few exceptions, such as constants and enumerations, which can be wra
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
In Scilab 5.x, identifier names are composed of 24 characters maximum (this limitation should disappear from Scilab 6.0 onwards).
|
In Scilab 5.x, identifier names are composed of 24 characters maximum (this limitation disappears from Scilab 6.0 onwards).
|
||||||
<br>Thus long function or variable names may be truncated and this can cause ambiguities.
|
<br>By default, variable, member, and function names longer than 24 charaters are truncated, and a warning is produced for each truncation.
|
||||||
</p>
|
</p>
|
||||||
<p>This happens especially when wrapping structs/classes, for which the wrapped function name is composed of the struct/class name and field names.
|
<p>This can cause ambiguities, especially when wrapping structs/classes, for which the wrapped function name is composed of the struct/class name and field names.
|
||||||
In these cases, the <a href="SWIG.html#SWIG_rename_ignore">%rename directive</a> can be used to choose a different Scilab name.
|
In these cases, the <a href="SWIG.html#SWIG_rename_ignore">%rename directive</a> can be used to choose a different Scilab name.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Note: truncations can be disabled by specifying the target version 6 of Scilab in the <tt>targetversion</tt> argument (i.e. <tt>-targetversion 6</tt>).
|
||||||
|
</p>
|
||||||
|
|
||||||
<H3><a name="Scilab_wrapping_functions">39.3.3 Functions</a></H3>
|
<H3><a name="Scilab_wrapping_functions">39.3.3 Functions</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1124,10 +1133,10 @@ But we can use either use the <tt>get_perimeter()</tt> function of the parent cl
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
As explained in <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">6.15</a> SWIG provides support for overloaded functions and constructors.
|
As explained in <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods</a> SWIG provides support for overloaded functions and constructors.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>As SWIG knows pointer types, the overloading works also with pointer types, here is is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>:
|
<p>As SWIG knows pointer types, the overloading works also with pointer types, here is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
|
|
@ -1611,11 +1620,11 @@ void printArray(int values[], int len) {
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
There are no specific typemaps for pointer-to-pointers, they are are mapped as pointers in Scilab.
|
There are no specific typemaps for pointer-to-pointers, they are mapped as pointers in Scilab.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Pointer-to-pointers are sometimes used to implement matrices in C. The following is a an example of this:
|
Pointer-to-pointers are sometimes used to implement matrices in C. The following is an example of this:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2053,7 +2062,7 @@ In this mode, the following SWIG options may be used to setup the build:
|
||||||
Let's give an example how to build a module <tt>example</tt>, composed of two sources, and using a library dependency:
|
Let's give an example how to build a module <tt>example</tt>, composed of two sources, and using a library dependency:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>the sources are <tt>baa1.c</tt> and <tt>baa2.c</tt> (and are stored in in the current directory)</li>
|
<li>the sources are <tt>baa1.c</tt> and <tt>baa2.c</tt> (and are stored in the current directory)</li>
|
||||||
<li>the library is <tt>libfoo</tt> in <tt>/opt/foo</tt> (headers stored in <tt>/opt/foo/include</tt>, and shared library in <tt>/opt/foo/lib</tt>)</li>
|
<li>the library is <tt>libfoo</tt> in <tt>/opt/foo</tt> (headers stored in <tt>/opt/foo/include</tt>, and shared library in <tt>/opt/foo/lib</tt>)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>SWIG-3.0 Documentation</title>
|
<title>SWIG-4.0 Documentation</title>
|
||||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="#ffffff">
|
<body bgcolor="#ffffff">
|
||||||
<H1><a name="Sections">SWIG-3.0 Documentation</a></H1>
|
<H1><a name="Sections">SWIG-4.0 Documentation</a></H1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Last update : SWIG-3.0.13 (in progress)
|
Last update : SWIG-4.0.0 (in progress)
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="Sections_Sections">Sections</a></H2>
|
<H2><a name="Sections_Sections">Sections</a></H2>
|
||||||
|
|
|
||||||
|
|
@ -3904,9 +3904,9 @@ A fragment can use one or more additional fragments, for example:
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%fragment("<limits.h>", "header") {
|
%fragment("<limits.h>", "header") %{
|
||||||
%#include <limits.h>
|
#include <limits.h>
|
||||||
}
|
%}
|
||||||
|
|
||||||
|
|
||||||
%fragment("AsMyClass", "header", fragment="<limits.h>") {
|
%fragment("AsMyClass", "header", fragment="<limits.h>") {
|
||||||
|
|
@ -3989,8 +3989,91 @@ Finally, you can force the inclusion of a fragment at any point in the generated
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
which is very useful inside a template class, for example.
|
which, for example, is very useful inside a template class.
|
||||||
|
Another useful case is when using <tt>%extend</tt> inside a class
|
||||||
|
where the additional code in the <tt>%extend</tt> block depends on the contents of the fragment.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%fragment("<limits.h>", "header") %{
|
||||||
|
#include <limits.h>
|
||||||
|
%}
|
||||||
|
|
||||||
|
struct X {
|
||||||
|
...
|
||||||
|
%extend {
|
||||||
|
%fragment("<limits.h>");
|
||||||
|
bool check(short val) {
|
||||||
|
if (val < SHRT_MIN /*defined in <limits.h>*/) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Forced inclusion of fragments can be used as a replacement for <a href="SWIG.html#SWIG_nn42">code insertion block</a>, ensuring the
|
||||||
|
code block is only generated once.
|
||||||
|
Consider the contents of FileA.i below which first uses a code insertion block and then a forced fragment inclusion to generate code:
|
||||||
|
</p>
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
// FileA.i
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
%}
|
||||||
|
%fragment("<limits.h>");
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
and another file including the above:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
// FileB.i
|
||||||
|
%include "FileA.i"
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The resulting code in the wrappers for FileB.i is:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A note of caution must be mentioned when using <tt>%fragment</tt> forced inclusion or code insertion blocks with <tt>%import</tt>.
|
||||||
|
If <tt>%import</tt> is used instead:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
// FileC.i
|
||||||
|
%import "FileA.i"
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
then nothing is generated in the resulting code in the wrappers for FileC.i.
|
||||||
|
This is because <tt>%import</tt> is for collecting type information and does not result in any code
|
||||||
|
being generated, see <a href="Preprocessor.html#Preprocessor_nn3">File Imports</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>SWIG-3.0 Documentation</title>
|
<title>SWIG-4.0 Documentation</title>
|
||||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="#ffffff">
|
<body bgcolor="#ffffff">
|
||||||
<H1><a name="index">SWIG-3.0 Documentation</a></H1>
|
<H1><a name="index">SWIG-4.0 Documentation</a></H1>
|
||||||
|
|
||||||
The SWIG documentation is available in one of the following formats.
|
The SWIG documentation is available in one of the following formats.
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ perl5_static_cpp: $(SRCDIR_SRCS)
|
||||||
# -----------------------------------------------------------------
|
# -----------------------------------------------------------------
|
||||||
|
|
||||||
perl5_run:
|
perl5_run:
|
||||||
$(RUNTOOL) $(PERL) $(PERL5_SCRIPT) $(RUNPIPE)
|
$(RUNTOOL) $(PERL) -I. $(PERL5_SCRIPT) $(RUNPIPE)
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
# -----------------------------------------------------------------
|
||||||
# Version display
|
# Version display
|
||||||
|
|
@ -897,10 +897,10 @@ mzscheme_clean:
|
||||||
##### Ocaml #####
|
##### Ocaml #####
|
||||||
##################################################################
|
##################################################################
|
||||||
|
|
||||||
OCC=@OCAMLC@
|
OCC=$(COMPILETOOL) @OCAMLC@
|
||||||
OCAMLDLGEN=@OCAMLDLGEN@
|
OCAMLDLGEN=$(COMPILETOOL) @OCAMLDLGEN@
|
||||||
OCAMLFIND=@OCAMLFIND@
|
OCAMLFIND=$(COMPILETOOL) @OCAMLFIND@
|
||||||
OCAMLMKTOP=@OCAMLMKTOP@ $(SWIGWHERE)
|
OCAMLMKTOP=$(COMPILETOOL) @OCAMLMKTOP@ $(SWIGWHERE)
|
||||||
NOLINK ?= false
|
NOLINK ?= false
|
||||||
OCAMLPP= -pp "camlp4o ./swigp4.cmo"
|
OCAMLPP= -pp "camlp4o ./swigp4.cmo"
|
||||||
OCAMLP4WHERE=`$(COMPILETOOL) @CAMLP4@ -where`
|
OCAMLP4WHERE=`$(COMPILETOOL) @CAMLP4@ -where`
|
||||||
|
|
@ -911,8 +911,7 @@ OCAMLCORE=\
|
||||||
$(SWIG) -ocaml -co swigp4.ml 2>/dev/null && \
|
$(SWIG) -ocaml -co swigp4.ml 2>/dev/null && \
|
||||||
$(OCC) -c swig.mli && \
|
$(OCC) -c swig.mli && \
|
||||||
$(OCC) -c swig.ml && \
|
$(OCC) -c swig.ml && \
|
||||||
$(OCC) -I $(OCAMLP4WHERE) -pp "camlp4o pa_extend.cmo q_MLast.cmo" \
|
$(OCC) -I $(OCAMLP4WHERE) -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
|
||||||
-c swigp4.ml
|
|
||||||
|
|
||||||
ocaml_static: $(SRCDIR_SRCS)
|
ocaml_static: $(SRCDIR_SRCS)
|
||||||
$(OCAMLCORE)
|
$(OCAMLCORE)
|
||||||
|
|
@ -920,32 +919,20 @@ ocaml_static: $(SRCDIR_SRCS)
|
||||||
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
|
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
|
||||||
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
||||||
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
||||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
|
||||||
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
|
|
||||||
swig.cmo \
|
|
||||||
$(INTERFACE:%.i=%.cmo) \
|
|
||||||
$(PROGFILE:%.ml=%.cmo) \
|
|
||||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
|
|
||||||
|
|
||||||
ocaml_dynamic: $(SRCDIR_SRCS)
|
ocaml_dynamic: $(SRCDIR_SRCS)
|
||||||
$(OCAMLCORE)
|
$(OCAMLCORE)
|
||||||
$(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
$(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||||
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
|
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
|
||||||
$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CCSHARED) -o $(INTERFACE:%.i=%@SO@) \
|
$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CCSHARED) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS)
|
||||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS)
|
$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml)
|
||||||
$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > \
|
|
||||||
$(INTERFACE:%.i=%_dynamic.ml)
|
|
||||||
mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
|
mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
|
||||||
rm $(INTERFACE:%.i=%.mli)
|
rm $(INTERFACE:%.i=%.mli)
|
||||||
$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
|
$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
|
||||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
$(NOLINK) || $(OCAMLFIND) $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo)
|
||||||
$(NOLINK) || $(OCAMLFIND) \
|
|
||||||
$(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
|
|
||||||
swig.cmo \
|
|
||||||
-package dl -linkpkg \
|
|
||||||
$(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo)
|
|
||||||
|
|
||||||
ocaml_static_toplevel: $(SRCDIR_SRCS)
|
ocaml_static_toplevel: $(SRCDIR_SRCS)
|
||||||
$(OCAMLCORE)
|
$(OCAMLCORE)
|
||||||
|
|
@ -953,72 +940,41 @@ ocaml_static_toplevel: $(SRCDIR_SRCS)
|
||||||
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
|
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
|
||||||
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
||||||
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
||||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
$(NOLINK) || $(OCAMLMKTOP) swig.cmo -I $(OCAMLP4WHERE) camlp4o.cma swigp4.cmo -g -ccopt -g -cclib -g -custom -o $(TARGET)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
|
||||||
$(NOLINK) || $(OCAMLMKTOP) \
|
|
||||||
swig.cmo \
|
|
||||||
-I $(OCAMLP4WHERE) camlp4o.cma swigp4.cmo \
|
|
||||||
-g -ccopt -g -cclib -g -custom -o $(TARGET)_top \
|
|
||||||
$(INTERFACE:%.i=%.cmo) \
|
|
||||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
|
|
||||||
|
|
||||||
ocaml_static_cpp: $(SRCDIR_SRCS)
|
ocaml_static_cpp: $(SRCDIR_SRCS)
|
||||||
$(OCAMLCORE)
|
$(OCAMLCORE)
|
||||||
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||||
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
|
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
|
||||||
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \
|
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
|
||||||
$(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
|
|
||||||
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
||||||
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
||||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
|
||||||
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
|
|
||||||
swig.cmo \
|
|
||||||
$(INTERFACE:%.i=%.cmo) \
|
|
||||||
$(PROGFILE:%.ml=%.cmo) \
|
|
||||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
|
|
||||||
-cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
|
|
||||||
|
|
||||||
ocaml_static_cpp_toplevel: $(SRCDIR_SRCS)
|
ocaml_static_cpp_toplevel: $(SRCDIR_SRCS)
|
||||||
$(OCAMLCORE)
|
$(OCAMLCORE)
|
||||||
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||||
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
|
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
|
||||||
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \
|
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
|
||||||
$(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
|
|
||||||
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
||||||
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
||||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
$(NOLINK) || $(OCAMLMKTOP) swig.cmo -I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo -g -ccopt -g -cclib -g -custom -o $(TARGET)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
|
||||||
$(NOLINK) || $(OCAMLMKTOP) \
|
|
||||||
swig.cmo \
|
|
||||||
-I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo \
|
|
||||||
-g -ccopt -g -cclib -g -custom -o $(TARGET)_top \
|
|
||||||
$(INTERFACE:%.i=%.cmo) \
|
|
||||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
|
|
||||||
-cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
|
|
||||||
|
|
||||||
ocaml_dynamic_cpp: $(SRCDIR_SRCS)
|
ocaml_dynamic_cpp: $(SRCDIR_SRCS)
|
||||||
$(OCAMLCORE)
|
$(OCAMLCORE)
|
||||||
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||||
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
|
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
|
||||||
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \
|
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) -ccopt -fPIC
|
||||||
$(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) -ccopt -fPIC
|
$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(CPP_DLLIBS) $(LIBS)
|
||||||
$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(INTERFACE:%.i=%@SO@) \
|
$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml)
|
||||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
|
|
||||||
$(CPP_DLLIBS) $(LIBS)
|
|
||||||
$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > \
|
|
||||||
$(INTERFACE:%.i=%_dynamic.ml)
|
|
||||||
mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
|
mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
|
||||||
rm $(INTERFACE:%.i=%.mli)
|
rm $(INTERFACE:%.i=%.mli)
|
||||||
$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
|
$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
|
||||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
$(NOLINK) || $(OCAMLFIND) swig.cmo $(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom -o $(TARGET) -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX) -Wno-write-strings'
|
||||||
$(NOLINK) || $(OCAMLFIND) \
|
|
||||||
swig.cmo \
|
|
||||||
$(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom \
|
|
||||||
-o $(TARGET) \
|
|
||||||
-package dl -linkpkg \
|
|
||||||
$(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX) -Wno-write-strings'
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
# -----------------------------------------------------------------
|
||||||
# Run ocaml example
|
# Run ocaml example
|
||||||
|
|
@ -1738,7 +1694,7 @@ r: $(SRCDIR_SRCS)
|
||||||
ifneq ($(SRCDIR_SRCS),)
|
ifneq ($(SRCDIR_SRCS),)
|
||||||
$(CC) -g -c $(CPPFLAGS) $(CFLAGS) $(R_CFLAGS) $(SRCDIR_SRCS) $(INCLUDES)
|
$(CC) -g -c $(CPPFLAGS) $(CFLAGS) $(R_CFLAGS) $(SRCDIR_SRCS) $(INCLUDES)
|
||||||
endif
|
endif
|
||||||
+( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) $(OBJS) > /dev/null )
|
+( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" PKG_CFLAGS="$(CFLAGS)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) $(OBJS) > /dev/null )
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
# Build a R dynamically loadable module (C++)
|
# Build a R dynamically loadable module (C++)
|
||||||
|
|
@ -1748,7 +1704,7 @@ r_cpp: $(SRCDIR_CXXSRCS)
|
||||||
ifneq ($(SRCDIR_CXXSRCS),)
|
ifneq ($(SRCDIR_CXXSRCS),)
|
||||||
$(CXX) -g -c $(CPPFLAGS) $(CXXFLAGS) $(R_CFLAGS) $(SRCDIR_CXXSRCS) $(INCLUDES)
|
$(CXX) -g -c $(CPPFLAGS) $(CXXFLAGS) $(R_CFLAGS) $(SRCDIR_CXXSRCS) $(INCLUDES)
|
||||||
endif
|
endif
|
||||||
+( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) $(OBJS) > /dev/null )
|
+( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" PKG_CXXFLAGS="$(CXXFLAGS)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) $(OBJS) > /dev/null )
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
# -----------------------------------------------------------------
|
||||||
# Run R example
|
# Run R example
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,6 @@ func DeleteGoCallback(p GoCallback) {
|
||||||
p.deleteCallback()
|
p.deleteCallback()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *goCallback) Run() {
|
func (p *overwrittenMethodsOnCallback) Run() {
|
||||||
fmt.Println("GoCallback.Run")
|
fmt.Println("GoCallback.Run")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,5 +30,5 @@ f.enum_test(example.Foo.LUDICROUS);
|
||||||
// enum value BLUE of enum color is accessed as property of cconst
|
// enum value BLUE of enum color is accessed as property of cconst
|
||||||
console.log("example.BLUE= " + example.BLUE);
|
console.log("example.BLUE= " + example.BLUE);
|
||||||
|
|
||||||
// enum value LUDICROUS of enum Foo::speed is accessed as as property of cconst
|
// enum value LUDICROUS of enum Foo::speed is accessed as property of cconst
|
||||||
console.log("example.speed.LUDICROUS= " + example.Foo.LUDICROUS);
|
console.log("example.speed.LUDICROUS= " + example.Foo.LUDICROUS);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,10 @@ public:
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
|
||||||
|
#endif
|
||||||
|
|
||||||
class Test {
|
class Test {
|
||||||
public:
|
public:
|
||||||
|
|
@ -50,4 +54,7 @@ public:
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,14 @@ public:
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
|
||||||
|
#endif
|
||||||
|
|
||||||
class Test {
|
class Test {
|
||||||
public:
|
public:
|
||||||
int simple() throw(int&) {
|
int simple() throw(int) {
|
||||||
throw(37);
|
throw(37);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -50,4 +54,7 @@ public:
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ CEO=@(name) subclass(swigexample.Manager(name),'getPosition',@(self) "CEO");
|
||||||
|
|
||||||
# Create an instance of our employee extension class, CEO. The calls to
|
# Create an instance of our employee extension class, CEO. The calls to
|
||||||
# getName() and getPosition() are standard, the call to getTitle() uses
|
# getName() and getPosition() are standard, the call to getTitle() uses
|
||||||
# the director wrappers to call CEO.getPosition. e = CEO("Alice")
|
# the director wrappers to call CEO.getPosition.
|
||||||
|
|
||||||
e = CEO("Alice");
|
e = CEO("Alice");
|
||||||
printf("%s is a %s\n",e.getName(),e.getPosition());
|
printf("%s is a %s\n",e.getName(),e.getPosition());
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ CXXSRCS = example.cxx
|
||||||
TARGET = example
|
TARGET = example
|
||||||
INTERFACE = example.i
|
INTERFACE = example.i
|
||||||
LIBS =
|
LIBS =
|
||||||
SWIGOPT = -noproxy
|
SWIGOPT =
|
||||||
|
|
||||||
check: build
|
check: build
|
||||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
|
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
|
||||||
|
|
|
||||||
|
|
@ -11,22 +11,22 @@ print " BLUE =" . BLUE;
|
||||||
print " GREEN =" . GREEN;
|
print " GREEN =" . GREEN;
|
||||||
|
|
||||||
print "\n*** Foo::speed ***";
|
print "\n*** Foo::speed ***";
|
||||||
print " Foo_IMPULSE =" . Foo_IMPULSE;
|
print " Foo::IMPULSE =" . Foo::IMPULSE;
|
||||||
print " Foo_WARP =" . Foo_WARP;
|
print " Foo::WARP =" . Foo::WARP;
|
||||||
print " Foo_LUDICROUS =" . Foo_LUDICROUS;
|
print " Foo::LUDICROUS =" . Foo::LUDICROUS;
|
||||||
|
|
||||||
print "\nTesting use of enums with functions\n";
|
print "\nTesting use of enums with functions\n";
|
||||||
|
|
||||||
enum_test(RED, Foo_IMPULSE);
|
enum_test(RED, Foo::IMPULSE);
|
||||||
enum_test(BLUE, Foo_WARP);
|
enum_test(BLUE, Foo::WARP);
|
||||||
enum_test(GREEN, Foo_LUDICROUS);
|
enum_test(GREEN, Foo::LUDICROUS);
|
||||||
enum_test(1234,5678);
|
enum_test(1234,5678);
|
||||||
|
|
||||||
print "\nTesting use of enum with class method\n";
|
print "\nTesting use of enum with class method\n";
|
||||||
$f = new_Foo();
|
$f = new Foo();
|
||||||
|
|
||||||
Foo_enum_test($f,Foo_IMPULSE);
|
$f->enum_test(Foo::IMPULSE);
|
||||||
Foo_enum_test($f,Foo_WARP);
|
$f->enum_test(Foo::WARP);
|
||||||
Foo_enum_test($f,Foo_LUDICROUS);
|
$f->enum_test(Foo::LUDICROUS);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
||||||
|
|
@ -27,5 +27,6 @@
|
||||||
# This code is inserted into example.php
|
# This code is inserted into example.php
|
||||||
echo \"this was php code\\n\";
|
echo \"this was php code\\n\";
|
||||||
"
|
"
|
||||||
|
%pragma(php) version="1.5"
|
||||||
|
|
||||||
%pragma(php) phpinfo="php_info_print_table_start();"
|
%pragma(php) phpinfo="php_info_print_table_start();"
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
require "example.php";
|
require "example.php";
|
||||||
|
|
||||||
|
echo "Version - " . ((new ReflectionExtension('example'))->getVersion());
|
||||||
?>
|
?>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ SRCS = example.c
|
||||||
TARGET = example
|
TARGET = example
|
||||||
INTERFACE = example.i
|
INTERFACE = example.i
|
||||||
LIBS =
|
LIBS =
|
||||||
SWIGOPT = -noproxy
|
SWIGOPT =
|
||||||
|
|
||||||
check: build
|
check: build
|
||||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
|
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@
|
||||||
require "example.php";
|
require "example.php";
|
||||||
|
|
||||||
|
|
||||||
$v = new_vector();
|
$v = new Vector();
|
||||||
vector_x_set($v,1.0);
|
$v->x = 1.0;
|
||||||
vector_y_set($v,2.0);
|
$v->y = 2.0;
|
||||||
vector_z_set($v,3.0);
|
$v->z = 3.0;
|
||||||
|
|
||||||
$w = new_vector();
|
$w = new Vector();
|
||||||
vector_x_set($w,10.0);
|
$w->x = 10.0;
|
||||||
vector_y_set($w,11.0);
|
$w->y = 11.0;
|
||||||
vector_z_set($w,12.0);
|
$w->z = 12.0;
|
||||||
|
|
||||||
echo "I just created the following vector\n";
|
echo "I just created the following vector\n";
|
||||||
vector_print($v);
|
vector_print($v);
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
echo "\nNow I'm going to add the vectors together\n";
|
echo "\nNow I'm going to add the vectors together\n";
|
||||||
|
|
||||||
$r = new_vector();
|
$r = new Vector();
|
||||||
vector_add($v, $w, $r);
|
vector_add($v, $w, $r);
|
||||||
|
|
||||||
vector_print($r);
|
vector_print($r);
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,10 @@
|
||||||
echo "pt = ".pt_get(), point_print(pt_get()) , "\n";
|
echo "pt = ".pt_get(), point_print(pt_get()) , "\n";
|
||||||
|
|
||||||
/* Try to set the values of some global variables */
|
/* Try to set the values of some global variables */
|
||||||
$a = "42.14";
|
$a = "42.14";
|
||||||
|
|
||||||
ivar_set($a);
|
ivar_set($a);
|
||||||
echo "a = $a\n";
|
echo "a = $a\n";
|
||||||
svar_set(-31000);
|
svar_set(-31000);
|
||||||
lvar_set(65537);
|
lvar_set(65537);
|
||||||
uivar_set(123456);
|
uivar_set(123456);
|
||||||
|
|
|
||||||
|
|
@ -27,5 +27,6 @@
|
||||||
# This code is inserted into example.php
|
# This code is inserted into example.php
|
||||||
echo \"this was php code\\n\";
|
echo \"this was php code\\n\";
|
||||||
"
|
"
|
||||||
|
%pragma(php) version="1.5"
|
||||||
|
|
||||||
%pragma(php) phpinfo="php_info_print_table_start();"
|
%pragma(php) phpinfo="php_info_print_table_start();"
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
require "example.php";
|
require "example.php";
|
||||||
|
|
||||||
|
echo "Version - " . ((new ReflectionExtension('example'))->getVersion());
|
||||||
?>
|
?>
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,10 @@
|
||||||
echo "pt = ".pt_get(), point_print(pt_get()) , "\n";
|
echo "pt = ".pt_get(), point_print(pt_get()) , "\n";
|
||||||
|
|
||||||
/* Try to set the values of some global variables */
|
/* Try to set the values of some global variables */
|
||||||
$a = "42.14";
|
$a = "42.14";
|
||||||
|
|
||||||
ivar_set($a);
|
ivar_set($a);
|
||||||
echo "a = $a\n";
|
echo "a = $a\n";
|
||||||
svar_set(-31000);
|
svar_set(-31000);
|
||||||
lvar_set(65537);
|
lvar_set(65537);
|
||||||
uivar_set(123456);
|
uivar_set(123456);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,10 @@ public:
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
|
||||||
|
#endif
|
||||||
|
|
||||||
class Test {
|
class Test {
|
||||||
public:
|
public:
|
||||||
|
|
@ -50,4 +54,7 @@ public:
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,10 @@ class FullError {
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename T> class Queue {
|
template<typename T> class Queue {
|
||||||
int maxsize;
|
int maxsize;
|
||||||
|
|
@ -51,4 +55,7 @@ template<typename T> class Queue {
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ class CEO(example.Manager):
|
||||||
|
|
||||||
# Create an instance of our employee extension class, CEO. The calls to
|
# Create an instance of our employee extension class, CEO. The calls to
|
||||||
# getName() and getPosition() are standard, the call to getTitle() uses
|
# getName() and getPosition() are standard, the call to getTitle() uses
|
||||||
# the director wrappers to call CEO.getPosition. e = CEO("Alice")
|
# the director wrappers to call CEO.getPosition.
|
||||||
|
|
||||||
e = CEO("Alice")
|
e = CEO("Alice")
|
||||||
print e.getName(), "is a", e.getPosition()
|
print e.getName(), "is a", e.getPosition()
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
import robin
|
import robin
|
||||||
|
|
||||||
assert(robin.run() == "AWAY!")
|
if not(robin.run() == "AWAY!"):
|
||||||
|
raise RuntimeError("test failed")
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,5 @@ sys.path.insert(0, 'path1')
|
||||||
|
|
||||||
from brave import robin
|
from brave import robin
|
||||||
|
|
||||||
assert(robin.run() == "AWAY!")
|
if not(robin.run() == "AWAY!"):
|
||||||
|
raise RuntimeError("test failed")
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@ sys.path.insert(0, 'path3')
|
||||||
|
|
||||||
from brave import robin
|
from brave import robin
|
||||||
|
|
||||||
assert(robin.run() == "AWAY!")
|
if not(robin.run() == "AWAY!"):
|
||||||
|
raise RuntimeError("test failed")
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@ sys.path.insert(0, 'path3')
|
||||||
|
|
||||||
from brave import robin
|
from brave import robin
|
||||||
|
|
||||||
assert(robin.run() == "AWAY!")
|
if not(robin.run() == "AWAY!"):
|
||||||
|
raise RuntimeError("test failed")
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,5 @@ import pkg1.foo
|
||||||
|
|
||||||
print " Finished importing pkg1.foo"
|
print " Finished importing pkg1.foo"
|
||||||
|
|
||||||
assert(pkg1.foo.count() == 3)
|
if not(pkg1.foo.count() == 3):
|
||||||
|
raise RuntimeError("test failed")
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,5 @@ import pkg1.foo
|
||||||
|
|
||||||
print " Finished importing pkg1.foo"
|
print " Finished importing pkg1.foo"
|
||||||
|
|
||||||
assert(pkg1.foo.count() == 3)
|
if not(pkg1.foo.count() == 3):
|
||||||
|
raise RuntimeError("test failed")
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,14 @@ class FullError {
|
||||||
FullError(int m) : maxsize(m) { }
|
FullError(int m) : maxsize(m) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename T> class Queue {
|
template<typename T> class Queue {
|
||||||
int maxsize;
|
int maxsize;
|
||||||
T *items;
|
T *items;
|
||||||
|
|
@ -44,6 +52,12 @@ template<typename T> class Queue {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -47,6 +47,6 @@ testdir/README file.
|
||||||
Further Documentation
|
Further Documentation
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
There is documentation about the test-suite and how to use use it in
|
There is documentation about the test-suite and how to use it in
|
||||||
the SWIG documentation - Doc/Manual/Extending.html#Extending_test_suite.
|
the SWIG documentation - Doc/Manual/Extending.html#Extending_test_suite.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,14 @@ typedef int Integer;
|
||||||
void banana(S *a, const struct tagS *b, int c, Integer d) {}
|
void banana(S *a, const struct tagS *b, int c, Integer d) {}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Check docs for a template type
|
||||||
|
%inline %{
|
||||||
|
template<typename X> struct T {
|
||||||
|
T inout(T t) { return t; }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
%template(TInteger) T<int>;
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
#ifdef SWIGPYTHON_BUILTIN
|
#ifdef SWIGPYTHON_BUILTIN
|
||||||
bool is_python_builtin() { return true; }
|
bool is_python_builtin() { return true; }
|
||||||
|
|
@ -140,4 +148,3 @@ bool is_python_builtin() { return true; }
|
||||||
bool is_python_builtin() { return false; }
|
bool is_python_builtin() { return false; }
|
||||||
#endif
|
#endif
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
|
||||||
|
#endif
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%include <exception.i> // for throws(...) typemap
|
%include <exception.i> // for throws(...) typemap
|
||||||
|
|
@ -31,3 +35,11 @@ void test_catches_all(int i) {
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%{
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
%}
|
||||||
|
|
|
||||||
160
Examples/test-suite/class_scope_namespace.i
Normal file
160
Examples/test-suite/class_scope_namespace.i
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
// Test a mix of forward class declarations, class definitions, using declarations and using directives.
|
||||||
|
|
||||||
|
%module class_scope_namespace
|
||||||
|
|
||||||
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) H::HH;
|
||||||
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Space8::I::II;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct A;
|
||||||
|
namespace Space1 {
|
||||||
|
namespace SubSpace1 {
|
||||||
|
struct A {
|
||||||
|
void aa(Space1::SubSpace1::A, SubSpace1::A, A) {}
|
||||||
|
};
|
||||||
|
void aaa(Space1::SubSpace1::A, SubSpace1::A, A) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Space2 {
|
||||||
|
struct B;
|
||||||
|
}
|
||||||
|
using Space2::B;
|
||||||
|
#ifdef __clang__
|
||||||
|
namespace Space2 {
|
||||||
|
struct B {
|
||||||
|
void bb(Space2::B, B) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
struct B {
|
||||||
|
void bb(Space2::B, B) {}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
void bbb(Space2::B, B) {}
|
||||||
|
|
||||||
|
namespace Space3 {
|
||||||
|
namespace SubSpace3 {
|
||||||
|
struct C;
|
||||||
|
struct D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct C;
|
||||||
|
struct D;
|
||||||
|
namespace Space3 {
|
||||||
|
struct C;
|
||||||
|
struct SubSpace3::C {
|
||||||
|
void cc(Space3::SubSpace3::C, SubSpace3::C) {}
|
||||||
|
};
|
||||||
|
using SubSpace3::D;
|
||||||
|
struct SubSpace3::D {
|
||||||
|
void dd(Space3::SubSpace3::D, SubSpace3::D, D) {}
|
||||||
|
};
|
||||||
|
void ccc(Space3::SubSpace3::C, SubSpace3::C) {}
|
||||||
|
void ddd(Space3::SubSpace3::D, SubSpace3::D, D) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Space4 {
|
||||||
|
namespace SubSpace4 {
|
||||||
|
struct E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
using namespace Space4;
|
||||||
|
using SubSpace4::E;
|
||||||
|
// Was added to incorrect namespace in swig-3.0.12
|
||||||
|
struct SubSpace4::E {
|
||||||
|
void ee(Space4::SubSpace4::E, SubSpace4::E, E) {}
|
||||||
|
};
|
||||||
|
void eee(Space4::SubSpace4::E, SubSpace4::E, E) {}
|
||||||
|
|
||||||
|
namespace Space5 {
|
||||||
|
namespace SubSpace5 {
|
||||||
|
namespace SubSubSpace5 {
|
||||||
|
struct F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Space5 {
|
||||||
|
using namespace SubSpace5;
|
||||||
|
using SubSubSpace5::F;
|
||||||
|
// Was added to incorrect namespace in swig-3.0.12
|
||||||
|
struct SubSubSpace5::F {
|
||||||
|
void ff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {}
|
||||||
|
};
|
||||||
|
void fff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Space6 {
|
||||||
|
struct G;
|
||||||
|
namespace SubSpace6 {
|
||||||
|
struct G;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Space6 {
|
||||||
|
struct SubSpace6::G {
|
||||||
|
void gg(Space6::SubSpace6::G, SubSpace6::G) {}
|
||||||
|
};
|
||||||
|
void ggg(Space6::SubSpace6::G, SubSpace6::G) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HH;
|
||||||
|
struct H {
|
||||||
|
struct HH {
|
||||||
|
void hh(H::HH) {}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
void hhh(H::HH) {}
|
||||||
|
|
||||||
|
namespace Space8 {
|
||||||
|
struct II;
|
||||||
|
struct I {
|
||||||
|
struct II {
|
||||||
|
void ii(Space8::I::II, I::II) {}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
void iii(Space8::I::II, I::II) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct J;
|
||||||
|
namespace Space9 {
|
||||||
|
namespace SubSpace9 {
|
||||||
|
struct J {
|
||||||
|
void jj(Space9::SubSpace9::J, SubSpace9::J, J) {}
|
||||||
|
};
|
||||||
|
void jjj(Space9::SubSpace9::J, SubSpace9::J, J) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Space10 {
|
||||||
|
struct K;
|
||||||
|
}
|
||||||
|
namespace Space10 {
|
||||||
|
namespace SubSpace10 {
|
||||||
|
struct K {
|
||||||
|
void kk(Space10::SubSpace10::K, SubSpace10::K, K) {}
|
||||||
|
};
|
||||||
|
void kkk(Space10::SubSpace10::K, SubSpace10::K, K) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace OtherSpace {
|
||||||
|
struct L;
|
||||||
|
struct M;
|
||||||
|
}
|
||||||
|
using OtherSpace::L;
|
||||||
|
namespace Space11 {
|
||||||
|
using OtherSpace::M;
|
||||||
|
namespace SubSpace11 {
|
||||||
|
struct L {
|
||||||
|
void ll(Space11::SubSpace11::L, SubSpace11::L, L) {}
|
||||||
|
};
|
||||||
|
void lll(Space11::SubSpace11::L, SubSpace11::L, L) {}
|
||||||
|
struct M {
|
||||||
|
void mm(Space11::SubSpace11::M, SubSpace11::M, M) {}
|
||||||
|
};
|
||||||
|
void mmm(Space11::SubSpace11::M, SubSpace11::M, M) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ CPP_TEST_BROKEN += \
|
||||||
|
|
||||||
# Broken C test cases. (Can be run individually using: make testcase.ctest)
|
# Broken C test cases. (Can be run individually using: make testcase.ctest)
|
||||||
C_TEST_BROKEN += \
|
C_TEST_BROKEN += \
|
||||||
tag_no_clash_with_variable
|
tag_no_clash_with_variable \
|
||||||
|
|
||||||
# C++ test cases. (Can be run individually using: make testcase.cpptest)
|
# C++ test cases. (Can be run individually using: make testcase.cpptest)
|
||||||
CPP_TEST_CASES += \
|
CPP_TEST_CASES += \
|
||||||
|
|
@ -136,6 +136,7 @@ CPP_TEST_CASES += \
|
||||||
char_binary \
|
char_binary \
|
||||||
char_strings \
|
char_strings \
|
||||||
chartest \
|
chartest \
|
||||||
|
class_scope_namespace \
|
||||||
class_forward \
|
class_forward \
|
||||||
class_ignore \
|
class_ignore \
|
||||||
class_scope_weird \
|
class_scope_weird \
|
||||||
|
|
@ -246,6 +247,7 @@ CPP_TEST_CASES += \
|
||||||
global_vars \
|
global_vars \
|
||||||
grouping \
|
grouping \
|
||||||
ignore_parameter \
|
ignore_parameter \
|
||||||
|
import_fragments \
|
||||||
import_nomodule \
|
import_nomodule \
|
||||||
inherit \
|
inherit \
|
||||||
inherit_member \
|
inherit_member \
|
||||||
|
|
@ -278,6 +280,7 @@ CPP_TEST_CASES += \
|
||||||
memberin_extend \
|
memberin_extend \
|
||||||
member_funcptr_galore \
|
member_funcptr_galore \
|
||||||
member_pointer \
|
member_pointer \
|
||||||
|
member_pointer_const \
|
||||||
member_template \
|
member_template \
|
||||||
minherit \
|
minherit \
|
||||||
minherit2 \
|
minherit2 \
|
||||||
|
|
@ -289,6 +292,7 @@ CPP_TEST_CASES += \
|
||||||
multiple_inheritance_shared_ptr \
|
multiple_inheritance_shared_ptr \
|
||||||
name_cxx \
|
name_cxx \
|
||||||
name_warnings \
|
name_warnings \
|
||||||
|
namespace_chase \
|
||||||
namespace_class \
|
namespace_class \
|
||||||
namespace_enum \
|
namespace_enum \
|
||||||
namespace_extend \
|
namespace_extend \
|
||||||
|
|
@ -416,6 +420,7 @@ CPP_TEST_CASES += \
|
||||||
template_default_inherit \
|
template_default_inherit \
|
||||||
template_default_qualify \
|
template_default_qualify \
|
||||||
template_default_vw \
|
template_default_vw \
|
||||||
|
template_empty_inherit \
|
||||||
template_enum \
|
template_enum \
|
||||||
template_enum_ns_inherit \
|
template_enum_ns_inherit \
|
||||||
template_enum_typedef \
|
template_enum_typedef \
|
||||||
|
|
@ -432,6 +437,7 @@ CPP_TEST_CASES += \
|
||||||
template_methods \
|
template_methods \
|
||||||
template_namespace_forward_declaration \
|
template_namespace_forward_declaration \
|
||||||
template_using_directive_and_declaration_forward \
|
template_using_directive_and_declaration_forward \
|
||||||
|
template_using_directive_typedef \
|
||||||
template_nested \
|
template_nested \
|
||||||
template_nested_typemaps \
|
template_nested_typemaps \
|
||||||
template_ns \
|
template_ns \
|
||||||
|
|
@ -442,6 +448,7 @@ CPP_TEST_CASES += \
|
||||||
template_ns_enum2 \
|
template_ns_enum2 \
|
||||||
template_ns_inherit \
|
template_ns_inherit \
|
||||||
template_ns_scope \
|
template_ns_scope \
|
||||||
|
template_parameters_global_scope \
|
||||||
template_partial_arg \
|
template_partial_arg \
|
||||||
template_partial_specialization \
|
template_partial_specialization \
|
||||||
template_partial_specialization_typedef \
|
template_partial_specialization_typedef \
|
||||||
|
|
@ -531,10 +538,10 @@ CPP_TEST_CASES += \
|
||||||
virtual_vs_nonvirtual_base \
|
virtual_vs_nonvirtual_base \
|
||||||
voidtest \
|
voidtest \
|
||||||
wallkw \
|
wallkw \
|
||||||
wrapmacro
|
wrapmacro \
|
||||||
|
|
||||||
# C++11 test cases.
|
# C++11 test cases.
|
||||||
CPP11_TEST_CASES = \
|
CPP11_TEST_CASES += \
|
||||||
cpp11_alignment \
|
cpp11_alignment \
|
||||||
cpp11_alternate_function_syntax \
|
cpp11_alternate_function_syntax \
|
||||||
cpp11_constexpr \
|
cpp11_constexpr \
|
||||||
|
|
@ -542,6 +549,7 @@ CPP11_TEST_CASES = \
|
||||||
cpp11_default_delete \
|
cpp11_default_delete \
|
||||||
cpp11_delegating_constructors \
|
cpp11_delegating_constructors \
|
||||||
cpp11_director_enums \
|
cpp11_director_enums \
|
||||||
|
cpp11_directors \
|
||||||
cpp11_explicit_conversion_operators \
|
cpp11_explicit_conversion_operators \
|
||||||
cpp11_final_override \
|
cpp11_final_override \
|
||||||
cpp11_function_objects \
|
cpp11_function_objects \
|
||||||
|
|
@ -553,6 +561,9 @@ CPP11_TEST_CASES = \
|
||||||
cpp11_noexcept \
|
cpp11_noexcept \
|
||||||
cpp11_null_pointer_constant \
|
cpp11_null_pointer_constant \
|
||||||
cpp11_raw_string_literals \
|
cpp11_raw_string_literals \
|
||||||
|
cpp11_ref_qualifiers \
|
||||||
|
cpp11_ref_qualifiers_rvalue_unignore \
|
||||||
|
cpp11_ref_qualifiers_typemaps \
|
||||||
cpp11_result_of \
|
cpp11_result_of \
|
||||||
cpp11_rvalue_reference \
|
cpp11_rvalue_reference \
|
||||||
cpp11_rvalue_reference2 \
|
cpp11_rvalue_reference2 \
|
||||||
|
|
@ -572,7 +583,6 @@ CPP11_TEST_CASES = \
|
||||||
|
|
||||||
# Broken C++11 test cases.
|
# Broken C++11 test cases.
|
||||||
CPP11_TEST_BROKEN = \
|
CPP11_TEST_BROKEN = \
|
||||||
# cpp11_hash_tables \ # not fully implemented yet
|
|
||||||
# cpp11_variadic_templates \ # Broken for some languages (such as Java)
|
# cpp11_variadic_templates \ # Broken for some languages (such as Java)
|
||||||
# cpp11_reference_wrapper \ # No typemaps
|
# cpp11_reference_wrapper \ # No typemaps
|
||||||
|
|
||||||
|
|
@ -621,9 +631,7 @@ CPP_STD_TEST_CASES += \
|
||||||
smart_pointer_inherit \
|
smart_pointer_inherit \
|
||||||
template_typedef_fnc \
|
template_typedef_fnc \
|
||||||
template_type_namespace \
|
template_type_namespace \
|
||||||
template_opaque
|
template_opaque \
|
||||||
# li_std_list
|
|
||||||
|
|
||||||
|
|
||||||
ifndef SKIP_CPP_STD_CASES
|
ifndef SKIP_CPP_STD_CASES
|
||||||
CPP_TEST_CASES += ${CPP_STD_TEST_CASES}
|
CPP_TEST_CASES += ${CPP_STD_TEST_CASES}
|
||||||
|
|
@ -687,7 +695,7 @@ C_TEST_CASES += \
|
||||||
typedef_struct \
|
typedef_struct \
|
||||||
typemap_subst \
|
typemap_subst \
|
||||||
union_parameter \
|
union_parameter \
|
||||||
unions
|
unions \
|
||||||
|
|
||||||
|
|
||||||
# Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest)
|
# Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest)
|
||||||
|
|
@ -698,7 +706,7 @@ MULTI_CPP_TEST_CASES += \
|
||||||
packageoption \
|
packageoption \
|
||||||
mod \
|
mod \
|
||||||
template_typedef_import \
|
template_typedef_import \
|
||||||
multi_import
|
multi_import \
|
||||||
|
|
||||||
# Custom tests - tests with additional commandline options
|
# Custom tests - tests with additional commandline options
|
||||||
wallkw.cpptest: SWIGOPT += -Wallkw
|
wallkw.cpptest: SWIGOPT += -Wallkw
|
||||||
|
|
@ -791,7 +799,7 @@ swig_and_compile_external = \
|
||||||
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' \
|
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' \
|
||||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||||
TARGET='$*_wrap_hdr.h' \
|
TARGET='$*_wrap_hdr.h' \
|
||||||
$(LANGUAGE)$(VARIANT)_externalhdr; \
|
$(LANGUAGE)$(VARIANT)_externalhdr && \
|
||||||
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS) $*_external.cxx' \
|
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS) $*_external.cxx' \
|
||||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||||
INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
|
INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
|
||||||
|
|
@ -805,7 +813,7 @@ setup = \
|
||||||
echo "$(ACTION)ing $(LANGUAGE) testcase $* (with run test)" ; \
|
echo "$(ACTION)ing $(LANGUAGE) testcase $* (with run test)" ; \
|
||||||
else \
|
else \
|
||||||
echo "$(ACTION)ing $(LANGUAGE) testcase $*" ; \
|
echo "$(ACTION)ing $(LANGUAGE) testcase $*" ; \
|
||||||
fi;
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,11 @@
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ComplexPair
|
||||||
|
{
|
||||||
|
std::complex<double> z1, z2;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,18 @@ public:
|
||||||
|
|
||||||
%include "std_vector.i"
|
%include "std_vector.i"
|
||||||
|
|
||||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) || defined(SWIGSCILAB)
|
#if defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) || defined(SWIGSCILAB)
|
||||||
#define SWIG_GOOD_VECTOR
|
#define SWIG_GOOD_VECTOR
|
||||||
%ignore std::vector<Space::Flow>::vector(size_type);
|
%ignore std::vector<Space::Flow>::vector(size_type);
|
||||||
%ignore std::vector<Space::Flow>::resize(size_type);
|
%ignore std::vector<Space::Flow>::resize(size_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(SWIGJAVA)
|
||||||
|
#define SWIG_GOOD_VECTOR
|
||||||
|
%ignore std::vector<Space::Flow>::vector(jint);
|
||||||
|
%ignore std::vector<Space::Flow>::resize(jint);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SWIGTCL) || defined(SWIGPERL)
|
#if defined(SWIGTCL) || defined(SWIGPERL)
|
||||||
#define SWIG_GOOD_VECTOR
|
#define SWIG_GOOD_VECTOR
|
||||||
/* here, for languages with bad declaration */
|
/* here, for languages with bad declaration */
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,10 @@
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
|
||||||
|
#endif
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%nodefaultctor;
|
%nodefaultctor;
|
||||||
|
|
@ -26,3 +30,11 @@ public:
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%{
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
%}
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,26 @@
|
||||||
struct SomeStruct {
|
struct SomeStruct {
|
||||||
int addNormal(int x, int y);
|
int addNormal(int x, int y);
|
||||||
auto addAlternate(int x, int y) -> int;
|
auto addAlternate(int x, int y) -> int;
|
||||||
|
auto addAlternateConst(int x, int y) const -> int;
|
||||||
|
auto addAlternateNoExcept(int x, int y) noexcept -> int;
|
||||||
|
auto addAlternateConstNoExcept(int x, int y) const noexcept -> int;
|
||||||
|
auto addAlternateMemberPtrParm(int x, int (SomeStruct::*mp)(int, int)) -> int;
|
||||||
|
auto addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int;
|
||||||
|
|
||||||
|
virtual auto addFinal(int x, int y) const noexcept -> int final { return x + y; }
|
||||||
|
virtual ~SomeStruct() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto SomeStruct::addAlternate(int x, int y) -> int {
|
int SomeStruct::addNormal(int x, int y) { return x + y; }
|
||||||
return x + y;
|
auto SomeStruct::addAlternate(int x, int y) -> int { return x + y; }
|
||||||
|
auto SomeStruct::addAlternateConst(int x, int y) const -> int { return x + y; }
|
||||||
|
auto SomeStruct::addAlternateNoExcept(int x, int y) noexcept -> int { return x + y; }
|
||||||
|
auto SomeStruct::addAlternateConstNoExcept(int x, int y) const noexcept -> int { return x + y; }
|
||||||
|
auto SomeStruct::addAlternateMemberPtrParm(int x, int (SomeStruct::*mp)(int, int)) -> int {
|
||||||
|
return 100*x + (this->*mp)(x, x);
|
||||||
|
}
|
||||||
|
auto SomeStruct::addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int {
|
||||||
|
return 1000*x + (this->*mp)(x, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SomeStruct::addNormal(int x, int y) {
|
|
||||||
return x + y;
|
|
||||||
}
|
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,17 @@
|
||||||
*/
|
*/
|
||||||
%module cpp11_constexpr
|
%module cpp11_constexpr
|
||||||
|
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
|
#ifdef SWIG
|
||||||
|
#define SWIGTESTCONST const
|
||||||
|
#else
|
||||||
|
#define SWIGTESTCONST
|
||||||
|
#endif
|
||||||
constexpr int AAA = 10;
|
constexpr int AAA = 10;
|
||||||
constexpr const int BBB = 20;
|
constexpr const int BBB = 20;
|
||||||
constexpr int CCC() { return 30; }
|
constexpr int CCC() { return 30; }
|
||||||
constexpr const int DDD() { return 40; }
|
constexpr SWIGTESTCONST int DDD() { return 40; }
|
||||||
|
|
||||||
constexpr int XXX() { return 10; }
|
constexpr int XXX() { return 10; }
|
||||||
constexpr int YYY = XXX() + 100;
|
constexpr int YYY = XXX() + 100;
|
||||||
|
|
@ -17,7 +23,7 @@ struct ConstExpressions {
|
||||||
static constexpr int KKK = 200;
|
static constexpr int KKK = 200;
|
||||||
static const int LLL = 300;
|
static const int LLL = 300;
|
||||||
constexpr int MMM() { return 400; }
|
constexpr int MMM() { return 400; }
|
||||||
constexpr const int NNN() { return 500; }
|
constexpr SWIGTESTCONST int NNN() { return 500; }
|
||||||
// Regression tests for support added in SWIG 3.0.4:
|
// Regression tests for support added in SWIG 3.0.4:
|
||||||
static constexpr const int JJJ1 = 101;
|
static constexpr const int JJJ1 = 101;
|
||||||
constexpr static int KKK1 = 201;
|
constexpr static int KKK1 = 201;
|
||||||
|
|
|
||||||
|
|
@ -17,20 +17,20 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct A1 {
|
struct A1 {
|
||||||
void func(int i) {}
|
void funk(int i) {}
|
||||||
A1() = default;
|
A1() = default;
|
||||||
~A1() = default;
|
~A1() = default;
|
||||||
void func(double i) = delete; /* Don't cast double to int. Compiler returns an error */
|
void funk(double i) = delete; /* Don't cast double to int. Compiler returns an error */
|
||||||
private:
|
private:
|
||||||
A1(const A1&);
|
A1(const A1&);
|
||||||
};
|
};
|
||||||
A1::A1(const A1&) = default;
|
A1::A1(const A1&) = default;
|
||||||
|
|
||||||
struct A2 {
|
struct A2 {
|
||||||
void func(int i) {}
|
void funk(int i) {}
|
||||||
virtual void fff(int) = delete;
|
virtual void fff(int) = delete;
|
||||||
virtual ~A2() = default;
|
virtual ~A2() = default;
|
||||||
template<class T> void func(T) = delete;
|
template<class T> void funk(T) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct trivial {
|
struct trivial {
|
||||||
|
|
|
||||||
20
Examples/test-suite/cpp11_directors.i
Normal file
20
Examples/test-suite/cpp11_directors.i
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
%module(directors="1") cpp11_directors
|
||||||
|
%feature("director");
|
||||||
|
|
||||||
|
%{
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
virtual ~Foo() noexcept {}
|
||||||
|
virtual int ping() noexcept = 0;
|
||||||
|
virtual int pong() noexcept = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
virtual ~Foo() noexcept {}
|
||||||
|
virtual int ping() noexcept = 0;
|
||||||
|
virtual int pong() noexcept = 0;
|
||||||
|
};
|
||||||
|
|
@ -16,6 +16,8 @@ struct Base {
|
||||||
virtual void finaloverride2() {}
|
virtual void finaloverride2() {}
|
||||||
virtual void finaloverride3() {}
|
virtual void finaloverride3() {}
|
||||||
virtual void finaloverride4() const {}
|
virtual void finaloverride4() const {}
|
||||||
|
virtual void finaloverride5() {}
|
||||||
|
virtual void finaloverride6() const {}
|
||||||
virtual ~Base() {}
|
virtual ~Base() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -31,6 +33,8 @@ struct Derived /*final*/ : Base {
|
||||||
virtual void finaloverride2() override final {}
|
virtual void finaloverride2() override final {}
|
||||||
virtual void finaloverride3() noexcept override final {}
|
virtual void finaloverride3() noexcept override final {}
|
||||||
virtual void finaloverride4() const noexcept override final {}
|
virtual void finaloverride4() const noexcept override final {}
|
||||||
|
virtual void finaloverride5() throw(int) override final {}
|
||||||
|
virtual void finaloverride6() const throw(int) override final {}
|
||||||
virtual ~Derived() override final {}
|
virtual ~Derived() override final {}
|
||||||
};
|
};
|
||||||
void Derived::override2() const noexcept {}
|
void Derived::override2() const noexcept {}
|
||||||
|
|
@ -78,6 +82,7 @@ struct Destructors4 : Base {
|
||||||
struct FinalOverrideMethods {
|
struct FinalOverrideMethods {
|
||||||
virtual void final() {}
|
virtual void final() {}
|
||||||
virtual void override(int) {}
|
virtual void override(int) {}
|
||||||
|
virtual ~FinalOverrideMethods() = default;
|
||||||
};
|
};
|
||||||
struct FinalOverrideVariables {
|
struct FinalOverrideVariables {
|
||||||
int final;
|
int final;
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,27 @@
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
#include <set>
|
#include <set>
|
||||||
//#include <map>
|
#include <map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
//#include <unordered_map>
|
#include <unordered_map>
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%include "std_set.i"
|
%include "std_set.i"
|
||||||
//%include "std_map.i"
|
%include "std_multiset.i"
|
||||||
|
%include "std_map.i"
|
||||||
|
%include "std_multimap.i"
|
||||||
%include "std_unordered_set.i"
|
%include "std_unordered_set.i"
|
||||||
//%include "std_unordered_map.i"
|
%include "std_unordered_multiset.i"
|
||||||
|
%include "std_unordered_map.i"
|
||||||
|
%include "std_unordered_multimap.i"
|
||||||
%template (SetInt) std::set<int>;
|
%template (SetInt) std::set<int>;
|
||||||
//%template (MapIntInt) std::map<int, int>;
|
%template (MultiSetInt) std::multiset<int>;
|
||||||
|
%template (MapIntInt) std::map<int, int>;
|
||||||
|
%template (MultiMapIntInt) std::multimap<int, int>;
|
||||||
%template (UnorderedSetInt) std::unordered_set<int>;
|
%template (UnorderedSetInt) std::unordered_set<int>;
|
||||||
//%template (UnorderedMapIntInt) std::unordered_map<int, int>;
|
%template (UnorderedMultiSetInt) std::unordered_multiset<int>;
|
||||||
|
%template (UnorderedMapIntInt) std::unordered_map<int, int>;
|
||||||
|
%template (UnorderedMultiMapIntInt) std::unordered_multimap<int, int>;
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
@ -25,19 +33,19 @@ class MyClass {
|
||||||
public:
|
public:
|
||||||
set<int> getSet() { return _set; }
|
set<int> getSet() { return _set; }
|
||||||
void addSet(int elt) { _set.insert(_set.begin(), elt); }
|
void addSet(int elt) { _set.insert(_set.begin(), elt); }
|
||||||
// map<int, int> getMap() { return _map; }
|
map<int, int> getMap() { return _map; }
|
||||||
// void addMap(int elt1, int elt2) { _map.insert(make_pair(elt1, elt2)); }
|
void addMap(int elt1, int elt2) { _map.insert(make_pair(elt1, elt2)); }
|
||||||
|
|
||||||
unordered_set<int> getUnorderedSet() { return _unordered_set; }
|
unordered_set<int> getUnorderedSet() { return _unordered_set; }
|
||||||
void addUnorderedSet(int elt) { _unordered_set.insert(_unordered_set.begin(), elt); }
|
void addUnorderedSet(int elt) { _unordered_set.insert(_unordered_set.begin(), elt); }
|
||||||
// unordered_map<int, int> getUnorderedMap() { return _unordered_map; }
|
unordered_map<int, int> getUnorderedMap() { return _unordered_map; }
|
||||||
// void addUnorderedMap(int elt1, int elt2) { _unordered_map.insert(make_pair(elt1, elt2)); }
|
void addUnorderedMap(int elt1, int elt2) { _unordered_map.insert(make_pair(elt1, elt2)); }
|
||||||
private:
|
private:
|
||||||
set<int> _set;
|
set<int> _set;
|
||||||
// map<int, int> _map;
|
map<int, int> _map;
|
||||||
|
|
||||||
unordered_set<int> _unordered_set;
|
unordered_set<int> _unordered_set;
|
||||||
// unordered_map<int, int> _unordered_map;
|
unordered_map<int, int> _unordered_map;
|
||||||
};
|
};
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,13 @@
|
||||||
%ignore NoExceptClass(NoExceptClass&&);
|
%ignore NoExceptClass(NoExceptClass&&);
|
||||||
%rename(Assignment) NoExceptClass::operator=;
|
%rename(Assignment) NoExceptClass::operator=;
|
||||||
|
|
||||||
|
%{
|
||||||
|
extern "C" void global_noexcept(int, bool) noexcept {}
|
||||||
|
%}
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
extern "C" void global_noexcept(int, bool) noexcept;
|
extern "C" void global_noexcept(int, bool) noexcept;
|
||||||
|
extern "C" void global_noexcept2(int, bool) noexcept {}
|
||||||
|
|
||||||
struct NoExceptClass {
|
struct NoExceptClass {
|
||||||
static const bool VeryTrue = true;
|
static const bool VeryTrue = true;
|
||||||
|
|
@ -14,7 +18,7 @@ struct NoExceptClass {
|
||||||
NoExceptClass(const NoExceptClass&) noexcept {}
|
NoExceptClass(const NoExceptClass&) noexcept {}
|
||||||
NoExceptClass(NoExceptClass&&) noexcept {}
|
NoExceptClass(NoExceptClass&&) noexcept {}
|
||||||
NoExceptClass& operator=(const NoExceptClass&) noexcept { return *this; }
|
NoExceptClass& operator=(const NoExceptClass&) noexcept { return *this; }
|
||||||
~NoExceptClass() noexcept {}
|
virtual ~NoExceptClass() noexcept {}
|
||||||
|
|
||||||
void noex0() noexcept {}
|
void noex0() noexcept {}
|
||||||
void noex1() noexcept(sizeof(int) == 4) {}
|
void noex1() noexcept(sizeof(int) == 4) {}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,9 @@
|
||||||
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) hh;
|
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) hh;
|
||||||
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ii;
|
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ii;
|
||||||
|
|
||||||
|
#if defined(SWIGTCL) || defined(SWIGCSHARP) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGPYTHON) || defined(SWIGJAVA)
|
||||||
%include <std_wstring.i>
|
%include <std_wstring.i>
|
||||||
|
#endif
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
||||||
226
Examples/test-suite/cpp11_ref_qualifiers.i
Normal file
226
Examples/test-suite/cpp11_ref_qualifiers.i
Normal file
|
|
@ -0,0 +1,226 @@
|
||||||
|
%module cpp11_ref_qualifiers
|
||||||
|
|
||||||
|
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra2;
|
||||||
|
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra3;
|
||||||
|
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc2;
|
||||||
|
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc3;
|
||||||
|
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc5;
|
||||||
|
|
||||||
|
%include <std_string.i>
|
||||||
|
|
||||||
|
%ignore Host::h() const &;
|
||||||
|
|
||||||
|
// Basic testing
|
||||||
|
%inline %{
|
||||||
|
using std::string;
|
||||||
|
class Host {
|
||||||
|
string s;
|
||||||
|
public:
|
||||||
|
string h1() & { return string(); }
|
||||||
|
string h2() const & { return string(); }
|
||||||
|
string h3() && { return std::move(string()); }
|
||||||
|
string h4() const && { return std::move(string()); }
|
||||||
|
string h5() const { return string(); }
|
||||||
|
string h6() volatile const & { return string(); }
|
||||||
|
string h7() const volatile & { return string(); }
|
||||||
|
string h8() volatile const && { return std::move(string()); }
|
||||||
|
string h9() const volatile && { return std::move(string()); }
|
||||||
|
|
||||||
|
string h() & { return string(); }
|
||||||
|
string h() const & { return string(); }
|
||||||
|
string h() && { return std::move(string()); }
|
||||||
|
string h() const && { return std::move(string()); }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
// %feature testing
|
||||||
|
%feature("except") F1() & %{ result = "F1"; %}
|
||||||
|
%feature("except") F2 %{ result = "F2"; %}
|
||||||
|
%feature("except") F3 %{ result = "F3"; %}
|
||||||
|
%feature("except") F3() %{ _should_not_be_used_ %}
|
||||||
|
|
||||||
|
%feature("except") C1(int i) const & %{ result = "C1"; %}
|
||||||
|
%feature("except") C2 %{ result = "C2"; %}
|
||||||
|
%feature("except") C3 %{ result = "C3"; %}
|
||||||
|
%feature("except") C3(int i) %{ _should_not_be_used_ %}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct Features {
|
||||||
|
string F1() & { return string(); }
|
||||||
|
string F2() & { return string(); }
|
||||||
|
string F3() & { return string(); }
|
||||||
|
|
||||||
|
string C1(int i) const & { return string(); }
|
||||||
|
string C2(int i) const & { return string(); }
|
||||||
|
string C3(int i) const & { return string(); }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
// %rename testing
|
||||||
|
%rename(RR1) R1;
|
||||||
|
%rename(RR2) R2() &;
|
||||||
|
%rename(RR3) R3;
|
||||||
|
%rename(RR3Bad) R3();
|
||||||
|
|
||||||
|
%rename(SS1) S1;
|
||||||
|
%rename(SS2) S2(int i) const &;
|
||||||
|
%rename(SS3) S3;
|
||||||
|
%rename(SS3Bad) S3(int i);
|
||||||
|
%rename(SS3BadConst) S3(int i) const;
|
||||||
|
%rename(SS3BadLValue) S3(int i) &;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct Renames {
|
||||||
|
string R1() & { return string(); }
|
||||||
|
string R2() & { return string(); }
|
||||||
|
string R3() & { return string(); }
|
||||||
|
|
||||||
|
string S1(int i) const & { return string(); }
|
||||||
|
string S2(int i) const & { return string(); }
|
||||||
|
string S3(int i) const & { return string(); }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Conversion operators
|
||||||
|
%rename(StringConvertCopy) operator string() &;
|
||||||
|
%rename(StringConvertMove) operator string() &&;
|
||||||
|
%feature("ignore", "0") operator string() &&; // unignore as it is ignored by default
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct ConversionOperators {
|
||||||
|
virtual operator string() & { return string(); }
|
||||||
|
virtual operator string() && { return std::move(string()); }
|
||||||
|
virtual ~ConversionOperators() {}
|
||||||
|
};
|
||||||
|
struct ConversionOperators2 {
|
||||||
|
virtual operator string() && { return std::move(string()); }
|
||||||
|
virtual ~ConversionOperators2() {}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct Funcs {
|
||||||
|
short FF(bool) { return 0; }
|
||||||
|
short CC(bool) const & { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class MemberFuncPtrs
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// member ref-qualified function pointers, unnamed parameters
|
||||||
|
int aaa1(short (Funcs::*)(bool) &) const;
|
||||||
|
int aaa2(short (Funcs::* const *&)(bool) &) const;
|
||||||
|
int aaa3(short (Funcs::* *&)(bool) &) const;
|
||||||
|
int aaa4(short (Funcs::* *const&)(bool) &) const;
|
||||||
|
int aaa5(short (Funcs::* &)(bool) &) const;
|
||||||
|
int aaa6(short (Funcs::* const)(bool) &) const;
|
||||||
|
int aaa7(short (Funcs::* const&)(bool) &) const;
|
||||||
|
|
||||||
|
int aaa8(short (Funcs::* const&)(bool) &&) const;
|
||||||
|
|
||||||
|
// member cv-qualified and ref-qualified function pointers, unnamed parameters
|
||||||
|
int bbb1(short (Funcs::*)(bool) const &) const;
|
||||||
|
int bbb2(short (Funcs::* const *&)(bool) const &) const;
|
||||||
|
int bbb3(short (Funcs::* *&)(bool) const &) const;
|
||||||
|
int bbb4(short (Funcs::* *const&)(bool) const &) const;
|
||||||
|
int bbb5(short (Funcs::* &)(bool) const &) const;
|
||||||
|
int bbb6(short (Funcs::* const)(bool) const &) const;
|
||||||
|
int bbb7(short (Funcs::* const&)(bool) const &) const;
|
||||||
|
|
||||||
|
int bbb8(short (Funcs::*)(bool) const &&) const;
|
||||||
|
|
||||||
|
// member ref-qualified function pointers, named parameters
|
||||||
|
int qqq1(short (Funcs::* qq1)(bool) &) const;
|
||||||
|
int qqq2(short (Funcs::* const *& qq2)(bool) &) const;
|
||||||
|
int qqq3(short (Funcs::* *& qq3)(bool) &) const;
|
||||||
|
int qqq4(short (Funcs::* *const& qq4)(bool) &) const;
|
||||||
|
int qqq5(short (Funcs::* & qq5)(bool) &) const;
|
||||||
|
int qqq6(short (Funcs::* const qq6)(bool) &) const;
|
||||||
|
int qqq7(short (Funcs::* const& qq7)(bool) &) const;
|
||||||
|
|
||||||
|
int qqq8(short (Funcs::* const& qq8)(bool) &&) const;
|
||||||
|
|
||||||
|
// member cv-qualified and ref-qualified function pointers, named parameters
|
||||||
|
int rrr1(short (Funcs::* rr1)(bool) const &) const;
|
||||||
|
int rrr2(short (Funcs::* const *& rr2)(bool) const &) const;
|
||||||
|
int rrr3(short (Funcs::* *& rr3)(bool) const &) const;
|
||||||
|
int rrr4(short (Funcs::* *const& rr4)(bool) const &) const;
|
||||||
|
int rrr5(short (Funcs::* & rr5)(bool) const &) const;
|
||||||
|
int rrr6(short (Funcs::* const rr6)(bool) const &) const;
|
||||||
|
int rrr7(short (Funcs::* const& rr7)(bool) const &) const;
|
||||||
|
|
||||||
|
int rrr8(short (Funcs::* rr1)(bool) const &&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// member ref-qualified function pointers, unnamed parameters
|
||||||
|
int MemberFuncPtrs::aaa1(short (Funcs::*)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::aaa2(short (Funcs::* const *&)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::aaa3(short (Funcs::* *&)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::aaa4(short (Funcs::* *const&)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::aaa5(short (Funcs::* &)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::aaa6(short (Funcs::* const)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::aaa7(short (Funcs::* const&)(bool) &) const { return 0; }
|
||||||
|
|
||||||
|
int MemberFuncPtrs::aaa8(short (Funcs::* const&)(bool) &&) const { return 0; }
|
||||||
|
|
||||||
|
// member cv-qualified and ref-qualified function pointers, unnamed parameters
|
||||||
|
int MemberFuncPtrs::bbb1(short (Funcs::*)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::bbb2(short (Funcs::* const *&)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::bbb3(short (Funcs::* *&)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::bbb4(short (Funcs::* *const&)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::bbb5(short (Funcs::* &)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::bbb6(short (Funcs::* const)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::bbb7(short (Funcs::* const&)(bool) const &) const { return 0; }
|
||||||
|
|
||||||
|
int MemberFuncPtrs::bbb8(short (Funcs::*)(bool) const &&) const { return 0; }
|
||||||
|
|
||||||
|
// member ref-qualified function pointers, named parameters
|
||||||
|
int MemberFuncPtrs::qqq1(short (Funcs::* qq1)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::qqq2(short (Funcs::* const *& qq2)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::qqq3(short (Funcs::* *& qq3)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::qqq4(short (Funcs::* *const& qq4)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::qqq5(short (Funcs::* & qq5)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::qqq6(short (Funcs::* const qq6)(bool) &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::qqq7(short (Funcs::* const& qq7)(bool) &) const { return 0; }
|
||||||
|
|
||||||
|
int MemberFuncPtrs::qqq8(short (Funcs::* const& qq8)(bool) &&) const { return 0; }
|
||||||
|
|
||||||
|
// member cv-qualified and ref-qualified function pointers, named parameters
|
||||||
|
int MemberFuncPtrs::rrr1(short (Funcs::* rr1)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::rrr2(short (Funcs::* const *& rr2)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::rrr3(short (Funcs::* *& rr3)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::rrr4(short (Funcs::* *const& rr4)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::rrr5(short (Funcs::* & rr5)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::rrr6(short (Funcs::* const rr6)(bool) const &) const { return 0; }
|
||||||
|
int MemberFuncPtrs::rrr7(short (Funcs::* const& rr7)(bool) const &) const { return 0; }
|
||||||
|
|
||||||
|
int MemberFuncPtrs::rrr8(short (Funcs::* rr1)(bool) const &&) const { return 0; }
|
||||||
|
|
||||||
|
// member cv-qualified and ref-qualified pointer variables
|
||||||
|
short (Funcs::* cc1)(bool) const & = &Funcs::CC;
|
||||||
|
|
||||||
|
short (Funcs::* const * ccextra2)(bool) const & = &cc1;
|
||||||
|
short (Funcs::* * ccextra3)(bool) const & = &cc1;
|
||||||
|
short (Funcs::* *const ccextra4)(bool) const & = &cc1;
|
||||||
|
|
||||||
|
short (Funcs::* const *& cc2)(bool) const & = ccextra2;
|
||||||
|
short (Funcs::* *& cc3)(bool) const & = ccextra3;
|
||||||
|
short (Funcs::* *const& cc4)(bool) const & = ccextra4;
|
||||||
|
short (Funcs::* & cc5)(bool) const & = cc1;
|
||||||
|
short (Funcs::* const cc6)(bool) const & = &Funcs::CC;
|
||||||
|
short (Funcs::* const& cc7)(bool) const & = cc1;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
|
||||||
|
struct Funktions {
|
||||||
|
int addByValue(const int &a, int b) const & { return a+b; }
|
||||||
|
int * addByPointer(const int &a, int b) const & { static int val; val = a+b; return &val; }
|
||||||
|
int & addByReference(const int &a, int b) const & { static int val; val = a+b; return val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
int call1(int (Funktions::*d)(const int &, int) const &, int a, int b) { Funktions f; return (f.*d)(a, b); }
|
||||||
|
//int call2(int * (Funktions::*d)(const int &, int) const &, int a, int b) { Funktions f; return *(f.*d)(a, b); }
|
||||||
|
//int call3(int & (Funktions::*d)(const int &, int) const &, int a, int b) { Funktions f; return (f.*d)(a, b); }
|
||||||
|
%}
|
||||||
|
%constant int (Funktions::*ADD_BY_VALUE)(const int &, int) const & = &Funktions::addByValue;
|
||||||
15
Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i
Normal file
15
Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
%module cpp11_ref_qualifiers_rvalue_unignore
|
||||||
|
|
||||||
|
// This is a minimal test that does not include any C++ headers to make sure the required
|
||||||
|
// <memory> header is generated from a fragment for the generated std::move call
|
||||||
|
|
||||||
|
// m1 and m2 are ignored by default, unignore them
|
||||||
|
%feature("ignore", "0") RefQualifier::m1() &&;
|
||||||
|
%feature("ignore", "0") RefQualifier::m2() const &&;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct RefQualifier {
|
||||||
|
void m1() && {}
|
||||||
|
void m2() const && {}
|
||||||
|
};
|
||||||
|
%}
|
||||||
74
Examples/test-suite/cpp11_ref_qualifiers_typemaps.i
Normal file
74
Examples/test-suite/cpp11_ref_qualifiers_typemaps.i
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
%module cpp11_ref_qualifiers_typemaps
|
||||||
|
|
||||||
|
%typemap(in) SWIGTYPE (CLASS::*) %{
|
||||||
|
_this_will_fail_to_compile_if_used_
|
||||||
|
%}
|
||||||
|
|
||||||
|
// typemaps to completely ignore the input parm and override it
|
||||||
|
%typemap(in) short (Funcs::*ff)(bool) const %{ $1 = &Funcs::FFF2; %}
|
||||||
|
%typemap(in) short (Funcs::*cc)(bool) & %{ $1 = &Funcs::CCC5; %}
|
||||||
|
%typemap(in) short (Funcs::*gg)(bool) const & %{ $1 = &Funcs::GGG8; %}
|
||||||
|
%typemap(in) short (Funcs::*hh)(bool) && %{ $1 = &Funcs::HHH11; %}
|
||||||
|
|
||||||
|
%typemap(in) short (Funcs::*)(bool) const %{ $1 = &Funcs::FFF3; %}
|
||||||
|
%typemap(in) short (Funcs::*)(bool) & %{ $1 = &Funcs::CCC6; %}
|
||||||
|
%typemap(in) short (Funcs::*)(bool) const & %{ $1 = &Funcs::GGG9; %}
|
||||||
|
%typemap(in) short (Funcs::*)(bool) && %{ $1 = &Funcs::HHH12; %}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct Funcs {
|
||||||
|
short FFF1(bool) const { return 1; }
|
||||||
|
short FFF2(bool) const { return 2; }
|
||||||
|
short FFF3(bool) const { return 3; }
|
||||||
|
short CCC4(bool) & { return 4; }
|
||||||
|
short CCC5(bool) & { return 5; }
|
||||||
|
short CCC6(bool) & { return 6; }
|
||||||
|
short GGG7(bool) const & { return 7; }
|
||||||
|
short GGG8(bool) const & { return 8; }
|
||||||
|
short GGG9(bool) const & { return 9; }
|
||||||
|
short HHH10(bool) && { return 10; }
|
||||||
|
short HHH11(bool) && { return 11; }
|
||||||
|
short HHH12(bool) && { return 12; }
|
||||||
|
};
|
||||||
|
struct TypemapsNamedParms
|
||||||
|
{
|
||||||
|
short fff(short (Funcs::*ff)(bool) const) {
|
||||||
|
Funcs funcs;
|
||||||
|
return (funcs.*ff)(true);
|
||||||
|
}
|
||||||
|
short ccc(short (Funcs::*cc)(bool) &) {
|
||||||
|
Funcs funcs;
|
||||||
|
return (funcs.*cc)(true);
|
||||||
|
}
|
||||||
|
short ggg(short (Funcs::*gg)(bool) const &) {
|
||||||
|
Funcs funcs;
|
||||||
|
return (funcs.*gg)(true);
|
||||||
|
}
|
||||||
|
short hhh(short (Funcs::*hh)(bool) &&) {
|
||||||
|
return (Funcs().*hh)(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct TypemapsUnnamedParms
|
||||||
|
{
|
||||||
|
short fff(short (Funcs::*f)(bool) const) {
|
||||||
|
Funcs funcs;
|
||||||
|
return (funcs.*f)(true);
|
||||||
|
}
|
||||||
|
short ccc(short (Funcs::*c)(bool) &) {
|
||||||
|
Funcs funcs;
|
||||||
|
return (funcs.*c)(true);
|
||||||
|
}
|
||||||
|
short ggg(short (Funcs::*g)(bool) const &) {
|
||||||
|
Funcs funcs;
|
||||||
|
return (funcs.*g)(true);
|
||||||
|
}
|
||||||
|
short hhh(short (Funcs::*h)(bool) &&) {
|
||||||
|
return (Funcs().*h)(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
%constant short (Funcs::*FF1_MFP)(bool) const = &Funcs::FFF1;
|
||||||
|
%constant short (Funcs::*CC4_MFP)(bool) & = &Funcs::CCC4;
|
||||||
|
%constant short (Funcs::*GG7_MFP)(bool) const & = &Funcs::GGG7;
|
||||||
|
%constant short (Funcs::*HH10_MFP)(bool) && = &Funcs::HHH10;
|
||||||
|
|
@ -23,7 +23,7 @@ struct Thingy {
|
||||||
int val;
|
int val;
|
||||||
int &lvalref;
|
int &lvalref;
|
||||||
int &&rvalref;
|
int &&rvalref;
|
||||||
Thingy(int v) : val(v), lvalref(val), rvalref(22) {}
|
Thingy(int v, int &&rvalv) : val(v), lvalref(val), rvalref(std::move(rvalv)) {}
|
||||||
void refIn(long &i) {}
|
void refIn(long &i) {}
|
||||||
void rvalueIn(long &&i) {}
|
void rvalueIn(long &&i) {}
|
||||||
short && rvalueInOut(short &&i) { return std::move(i); }
|
short && rvalueInOut(short &&i) { return std::move(i); }
|
||||||
|
|
@ -32,7 +32,7 @@ struct Thingy {
|
||||||
void compactDefaultArgs(const bool &&b = (const bool &&)PublicGlobalTrue, const UserDef &&u = (const UserDef &&)PublicUserDef) {}
|
void compactDefaultArgs(const bool &&b = (const bool &&)PublicGlobalTrue, const UserDef &&u = (const UserDef &&)PublicUserDef) {}
|
||||||
void privateDefaultArgs(const bool &&b = (const bool &&)PrivateTrue) {}
|
void privateDefaultArgs(const bool &&b = (const bool &&)PrivateTrue) {}
|
||||||
operator int &&() { return std::move(0); }
|
operator int &&() { return std::move(0); }
|
||||||
Thingy(const Thingy& rhs) : val(rhs.val), lvalref(rhs.lvalref), rvalref(copy_int(rhs.rvalref)) {}
|
Thingy(const Thingy& rhs) : val(rhs.val), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {}
|
||||||
Thingy& operator=(const Thingy& rhs) {
|
Thingy& operator=(const Thingy& rhs) {
|
||||||
val = rhs.val;
|
val = rhs.val;
|
||||||
lvalref = rhs.lvalref;
|
lvalref = rhs.lvalref;
|
||||||
|
|
@ -41,23 +41,25 @@ struct Thingy {
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
static const bool PrivateTrue;
|
static const bool PrivateTrue;
|
||||||
int copy_int(int& i) { return i; }
|
|
||||||
Thingy();
|
Thingy();
|
||||||
};
|
};
|
||||||
const bool Thingy::PrivateTrue = true;
|
const bool Thingy::PrivateTrue = true;
|
||||||
|
|
||||||
short && globalRvalueInOut(short &&i) { return std::move(i); }
|
short && globalRvalueInOut(short &&i) { return std::move(i); }
|
||||||
|
|
||||||
Thingy &&globalrrval = Thingy(55);
|
int glob = 123;
|
||||||
|
|
||||||
short && func(short &&i) { return std::move(i); }
|
Thingy &&globalrrval = Thingy(55, std::move(glob));
|
||||||
Thingy getit() { return Thingy(22); }
|
|
||||||
|
short && funk(short &&i) { return std::move(i); }
|
||||||
|
Thingy getit() { return Thingy(22, std::move(glob)); }
|
||||||
|
|
||||||
void rvalrefFunction1(int &&v = (int &&)5) {}
|
void rvalrefFunction1(int &&v = (int &&)5) {}
|
||||||
void rvalrefFunctionBYVAL(short (Thingy::*memFunc)(short)) {}
|
void rvalrefFunctionBYVAL(short (Thingy::*fptr)(short)) {}
|
||||||
void rvalrefFunctionLVALUE(short &(Thingy::*memFunc)(short &)) {}
|
void rvalrefFunctionPTR(short * (*fptr)(short *)) {}
|
||||||
void rvalrefFunction2(short && (Thingy::*memFunc)(short &&)) {}
|
void rvalrefFunctionLVALUE(short & (Thingy::*fptr)(short &)) {}
|
||||||
void rvalrefFunction3(short && (*memFunc)(short &&)) {}
|
void rvalrefFunction2(short && (Thingy::*fptr)(short &&)) {}
|
||||||
|
void rvalrefFunction3(short && (*fptr)(short &&)) {}
|
||||||
|
|
||||||
template <typename T> struct RemoveReference {
|
template <typename T> struct RemoveReference {
|
||||||
typedef T type;
|
typedef T type;
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,13 @@ struct Containing {
|
||||||
Thing *const&& member_rvalue_ref_ptr3 = 0;
|
Thing *const&& member_rvalue_ref_ptr3 = 0;
|
||||||
Thing const*const &&member_rvalue_ref_ptr4 = 0;
|
Thing const*const &&member_rvalue_ref_ptr4 = 0;
|
||||||
|
|
||||||
Containing() : member_rvalue_ref(Thing()) {}
|
Containing(Thing&&r, Thing*&& r1, Thing const*&& r2, Thing *const&& r3, Thing const*const && r4) :
|
||||||
|
member_rvalue_ref(std::move(r)),
|
||||||
|
member_rvalue_ref_ptr1(std::move(r1)),
|
||||||
|
member_rvalue_ref_ptr2(std::move(r2)),
|
||||||
|
member_rvalue_ref_ptr3(std::move(r3)),
|
||||||
|
member_rvalue_ref_ptr4(std::move(r4))
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
@ -62,6 +68,12 @@ struct IntContaining {
|
||||||
int *const&& member_rvalue_ref_ptr3 = 0;
|
int *const&& member_rvalue_ref_ptr3 = 0;
|
||||||
int const*const &&member_rvalue_ref_ptr4 = 0;
|
int const*const &&member_rvalue_ref_ptr4 = 0;
|
||||||
|
|
||||||
IntContaining() : member_rvalue_ref(55) {}
|
IntContaining(int&& r, int*&& r1, int const*&& r2, int *const&& r3, int const*const && r4) :
|
||||||
|
member_rvalue_ref(std::move(r)),
|
||||||
|
member_rvalue_ref_ptr1(std::move(r1)),
|
||||||
|
member_rvalue_ref_ptr2(std::move(r2)),
|
||||||
|
member_rvalue_ref_ptr3(std::move(r3)),
|
||||||
|
member_rvalue_ref_ptr4(std::move(r4))
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
57
Examples/test-suite/cpp11_shared_ptr_const.i
Normal file
57
Examples/test-suite/cpp11_shared_ptr_const.i
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
%module cpp11_shared_ptr_const
|
||||||
|
|
||||||
|
%{
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Foo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Foo(int i) : m(i) {}
|
||||||
|
int get_m() { return m;}
|
||||||
|
int m;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<Foo> foo(Foo v) {
|
||||||
|
return std::shared_ptr<Foo>(new Foo(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<const Foo> const_foo(Foo v) {
|
||||||
|
return std::shared_ptr<const Foo>(new Foo(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Foo> > foo_vec(Foo v) {
|
||||||
|
std::vector<std::shared_ptr<Foo> > result;
|
||||||
|
result.push_back( std::shared_ptr<Foo>(new Foo(v)) );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<const Foo> > const_foo_vec(Foo v) {
|
||||||
|
std::vector<std::shared_ptr<const Foo> > result;
|
||||||
|
result.push_back( std::shared_ptr<Foo>(new Foo(v)) );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%include <std_shared_ptr.i>
|
||||||
|
%include <std_vector.i>
|
||||||
|
|
||||||
|
%shared_ptr(Foo);
|
||||||
|
|
||||||
|
%template (FooVector) std::vector<std::shared_ptr<Foo> >;
|
||||||
|
%template (FooConstVector) std::vector<std::shared_ptr<Foo const> >;
|
||||||
|
|
||||||
|
class Foo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Foo(int i);
|
||||||
|
int get_m();
|
||||||
|
int m;
|
||||||
|
};
|
||||||
|
std::shared_ptr<Foo> foo(Foo v);
|
||||||
|
std::shared_ptr<const Foo> const_foo(Foo v);
|
||||||
|
std::vector<std::shared_ptr<Foo> > foo_vec(Foo v) const;
|
||||||
|
std::vector<std::shared_ptr<const Foo> > const_foo_vec(Foo v) const;
|
||||||
|
|
||||||
50
Examples/test-suite/cpp11_shared_ptr_nullptr_in_containers.i
Normal file
50
Examples/test-suite/cpp11_shared_ptr_nullptr_in_containers.i
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
%module cpp11_shared_ptr_nullptr_in_containers
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class C;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%include <std_shared_ptr.i>
|
||||||
|
%include <std_vector.i>
|
||||||
|
|
||||||
|
%shared_ptr(C)
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
|
||||||
|
class C {
|
||||||
|
public:
|
||||||
|
C() : m(-1) {}
|
||||||
|
C(int i) : m(i) {}
|
||||||
|
int get_m() { return m; }
|
||||||
|
int m;
|
||||||
|
};
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%template() std::vector<std::shared_ptr<C> >;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<C> > ret_vec_c_shared_ptr() {
|
||||||
|
std::vector<std::shared_ptr<C> > ret(3);
|
||||||
|
ret[0] = std::shared_ptr<C>(new C(0));
|
||||||
|
ret[2] = std::shared_ptr<C>(new C(2));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<C> > ret_arg_vec(const std::vector<std::shared_ptr<C> >& v) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_last_null(const std::vector<std::shared_ptr<C> >& v) {
|
||||||
|
if( v.back() ) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
188
Examples/test-suite/cpp11_shared_ptr_upcast.i
Normal file
188
Examples/test-suite/cpp11_shared_ptr_upcast.i
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
%module cpp11_shared_ptr_upcast
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <set>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
%}
|
||||||
|
|
||||||
|
%include <std_vector.i>
|
||||||
|
%include <std_map.i>
|
||||||
|
%include <std_shared_ptr.i>
|
||||||
|
|
||||||
|
%{
|
||||||
|
|
||||||
|
class Base {
|
||||||
|
public:
|
||||||
|
Base() : m(-1) {}
|
||||||
|
Base(int i) : m(i) {}
|
||||||
|
int get_m() { return m; }
|
||||||
|
int m;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Derived : public Base {
|
||||||
|
public:
|
||||||
|
Derived() : n(-2) {}
|
||||||
|
Derived(int i) : n(i) {}
|
||||||
|
int get_n() { return n; }
|
||||||
|
int n;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Base> BasePtr;
|
||||||
|
typedef std::shared_ptr<Derived> DerivedPtr;
|
||||||
|
|
||||||
|
// non-overloaded
|
||||||
|
int derived_num1(DerivedPtr v) {
|
||||||
|
return v == nullptr ? 999 : (*v).get_n();
|
||||||
|
}
|
||||||
|
|
||||||
|
int derived_num2(std::vector<DerivedPtr> v) {
|
||||||
|
return v[0] == nullptr ? 999 : (*v[0]).get_n();
|
||||||
|
}
|
||||||
|
|
||||||
|
int derived_num3(std::map<int, DerivedPtr> v) {
|
||||||
|
return v[0] == nullptr ? 999 : (*v[0]).get_n();
|
||||||
|
}
|
||||||
|
|
||||||
|
int base_num1(BasePtr v) {
|
||||||
|
return v == nullptr ? 999 : (*v).get_m();
|
||||||
|
}
|
||||||
|
|
||||||
|
int base_num2(std::vector<BasePtr > v) {
|
||||||
|
return v[0] == nullptr ? 999 : (*v[0]).get_m();
|
||||||
|
}
|
||||||
|
|
||||||
|
int base_num3(std::map<int, BasePtr > v) {
|
||||||
|
return v[0] == nullptr ? 999 : (*v[0]).get_m();
|
||||||
|
}
|
||||||
|
|
||||||
|
// overloaded
|
||||||
|
int derived_num(DerivedPtr v) {
|
||||||
|
return derived_num1(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int derived_num(std::vector<DerivedPtr> v) {
|
||||||
|
return derived_num2(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int derived_num(std::map<int, DerivedPtr> v) {
|
||||||
|
return derived_num3(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int base_num(BasePtr v) {
|
||||||
|
return base_num1(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int base_num(std::vector<BasePtr > v) {
|
||||||
|
return base_num2(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int base_num(std::map<int, BasePtr > v) {
|
||||||
|
return base_num3(v);
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
%shared_ptr(Base);
|
||||||
|
%shared_ptr(Derived);
|
||||||
|
|
||||||
|
%template(BaseList) std::vector<std::shared_ptr<Base> >;
|
||||||
|
%template(DerivedList) std::vector<std::shared_ptr<Derived> >;
|
||||||
|
|
||||||
|
%template(BaseMap) std::map<int, std::shared_ptr<Base> >;
|
||||||
|
%template(DerivedMap) std::map<int, std::shared_ptr<Derived> >;
|
||||||
|
|
||||||
|
class Base {
|
||||||
|
public:
|
||||||
|
Base();
|
||||||
|
int get_m();
|
||||||
|
int m;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Derived : public Base {
|
||||||
|
public:
|
||||||
|
Derived();
|
||||||
|
Derived(int i);
|
||||||
|
int get_n();
|
||||||
|
int n;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Base> BasePtr;
|
||||||
|
typedef std::shared_ptr<Derived> DerivedPtr;
|
||||||
|
|
||||||
|
// non-overloaded
|
||||||
|
int derived_num1(DerivedPtr);
|
||||||
|
int derived_num2(std::vector<std::shared_ptr<Derived> > v);
|
||||||
|
int derived_num3(std::map<int, DerivedPtr> v);
|
||||||
|
int base_num1(BasePtr);
|
||||||
|
int base_num2(std::vector<std::shared_ptr<Base> > v);
|
||||||
|
int base_num3(std::map<int, BasePtr > v);
|
||||||
|
|
||||||
|
// overloaded
|
||||||
|
int derived_num(DerivedPtr);
|
||||||
|
int derived_num(std::vector<std::shared_ptr<Derived> > v);
|
||||||
|
int derived_num(std::map<int, DerivedPtr> v);
|
||||||
|
int base_num(BasePtr);
|
||||||
|
int base_num(std::vector<std::shared_ptr<Base> > v);
|
||||||
|
int base_num(std::map<int, BasePtr > v);
|
||||||
|
|
||||||
|
// ptr to shared_ptr
|
||||||
|
%shared_ptr(Base2);
|
||||||
|
%shared_ptr(Derived2)
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
class Base2 {
|
||||||
|
public:
|
||||||
|
Base2() : m(-1) {}
|
||||||
|
Base2(int i) : m(i) {}
|
||||||
|
int get_m() { return m; }
|
||||||
|
int m;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Derived2 : public Base2 {
|
||||||
|
public:
|
||||||
|
Derived2() : n(0) {}
|
||||||
|
Derived2(int i) : n(i) {}
|
||||||
|
int get_n_2() { return n; }
|
||||||
|
int n;
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
%template(Base2List) std::vector<std::shared_ptr<Base2> * >;
|
||||||
|
%template(Base2Map) std::map<int, std::shared_ptr<Base2> * >;
|
||||||
|
|
||||||
|
%template(Derived2List) std::vector<std::shared_ptr<Derived2> * >;
|
||||||
|
%template(Derived2Map) std::map<int, std::shared_ptr<Derived2> * >;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
typedef std::shared_ptr<Derived2> * Derived2Ptr;
|
||||||
|
typedef std::shared_ptr<Base2> * Base2Ptr;
|
||||||
|
|
||||||
|
int base2_num1(Base2Ptr v) {
|
||||||
|
return v == nullptr ? 999 : *v == nullptr ? 888 : (*v)->get_m();
|
||||||
|
}
|
||||||
|
|
||||||
|
int base2_num2(std::vector<Base2Ptr> v) {
|
||||||
|
return v[0] == nullptr ? 999 : *v[0] == nullptr ? 888 : (*v[0])->get_m();
|
||||||
|
}
|
||||||
|
|
||||||
|
int base2_num3(std::map<int, Base2Ptr> v) {
|
||||||
|
return v[0] == nullptr ? 999 : *v[0] == nullptr ? 888 : (*v[0])->get_m();
|
||||||
|
}
|
||||||
|
|
||||||
|
int derived2_num1(Derived2Ptr v) {
|
||||||
|
return v == nullptr ? 999 : *v == nullptr ? 888 : (*v)->get_n_2();
|
||||||
|
}
|
||||||
|
|
||||||
|
int derived2_num2(std::vector<Derived2Ptr> v) {
|
||||||
|
return v[0] == nullptr ? 999 : *v[0] == nullptr ? 888 : (*v[0])->get_n_2();
|
||||||
|
}
|
||||||
|
|
||||||
|
int derived2_num3(std::map<int, Derived2Ptr> v) {
|
||||||
|
return v[0] == nullptr ? 999 : *v[0] == nullptr ? 888 : (*v[0])->get_n_2();
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
@ -1,12 +1,32 @@
|
||||||
/* This test case checks whether SWIG correctly parses and ignores the
|
/* This test case checks whether SWIG correctly parses and ignores
|
||||||
keywords "static_assert()" inside the class or struct.
|
"static_assert()" in various places.
|
||||||
*/
|
*/
|
||||||
%module cpp11_static_assert
|
%module cpp11_static_assert
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
|
static_assert(sizeof(int) >= 2, "What? int size is invalid!");
|
||||||
|
|
||||||
|
namespace dummy {
|
||||||
|
// C++17 allows the message to be omitted, so check that works too.
|
||||||
|
// But only show the C++17 version to SWIG, as the compiler may
|
||||||
|
// lack C++17 support.
|
||||||
|
#ifdef SWIG
|
||||||
|
static_assert(sizeof(int) >= sizeof(short));
|
||||||
|
#else
|
||||||
|
static_assert(sizeof(int) >= sizeof(short), "blah");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Check1 {
|
struct Check1 {
|
||||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||||
|
Check1() {
|
||||||
|
#ifdef SWIG
|
||||||
|
static_assert(true);
|
||||||
|
#else
|
||||||
|
static_assert(true, "true");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
||||||
5
Examples/test-suite/cpp11_std_unordered_map.i
Normal file
5
Examples/test-suite/cpp11_std_unordered_map.i
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
%module cpp11_std_unordered_map
|
||||||
|
|
||||||
|
%include <std_unordered_map.i>
|
||||||
|
|
||||||
|
%template(UnorderedMapIntInt) std::unordered_map<int, int>;
|
||||||
7
Examples/test-suite/cpp11_std_unordered_multimap.i
Normal file
7
Examples/test-suite/cpp11_std_unordered_multimap.i
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
%module cpp11_std_unordered_multimap
|
||||||
|
|
||||||
|
%include <std_pair.i>
|
||||||
|
%include <std_unordered_multimap.i>
|
||||||
|
|
||||||
|
%template(PairIntInt) std::pair<int,int>;
|
||||||
|
%template(UnorderedMultiMapIntInt) std::unordered_multimap<int, int>;
|
||||||
5
Examples/test-suite/cpp11_std_unordered_multiset.i
Normal file
5
Examples/test-suite/cpp11_std_unordered_multiset.i
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
%module cpp11_std_unordered_multiset
|
||||||
|
|
||||||
|
%include <std_unordered_multiset.i>
|
||||||
|
|
||||||
|
%template(UnorderedMultiSetInt) std::unordered_multiset<int>;
|
||||||
5
Examples/test-suite/cpp11_std_unordered_set.i
Normal file
5
Examples/test-suite/cpp11_std_unordered_set.i
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
%module cpp11_std_unordered_set
|
||||||
|
|
||||||
|
%include <std_unordered_set.i>
|
||||||
|
|
||||||
|
%template(UnorderedSetInt) std::unordered_set<int>;
|
||||||
|
|
@ -108,5 +108,5 @@ PairSubclass::data_t plus1(PairSubclass::const_ref_data_t x) { return x + 1; }
|
||||||
using callback_t = int(*)(int);
|
using callback_t = int(*)(int);
|
||||||
|
|
||||||
callback_t get_callback() { return mult2; }
|
callback_t get_callback() { return mult2; }
|
||||||
int call(callback_t func, int param) { return func(param); }
|
int call(callback_t funk, int param) { return funk(param); }
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ top_srcdir = ../@top_srcdir@
|
||||||
top_builddir = ../@top_builddir@
|
top_builddir = ../@top_builddir@
|
||||||
|
|
||||||
CPP_TEST_CASES = \
|
CPP_TEST_CASES = \
|
||||||
|
complextest \
|
||||||
csharp_attributes \
|
csharp_attributes \
|
||||||
csharp_swig2_compatibility \
|
csharp_swig2_compatibility \
|
||||||
csharp_exceptions \
|
csharp_exceptions \
|
||||||
|
|
@ -40,6 +41,7 @@ CSHARPFLAGSSPECIAL =
|
||||||
|
|
||||||
# Custom tests - tests with additional commandline options
|
# Custom tests - tests with additional commandline options
|
||||||
intermediary_classname.cpptest: SWIGOPT += -dllimport intermediary_classname
|
intermediary_classname.cpptest: SWIGOPT += -dllimport intermediary_classname
|
||||||
|
complextest.cpptest: CSHARPFLAGSSPECIAL = -r:System.Numerics.dll
|
||||||
csharp_lib_arrays.cpptest: CSHARPFLAGSSPECIAL = -unsafe
|
csharp_lib_arrays.cpptest: CSHARPFLAGSSPECIAL = -unsafe
|
||||||
csharp_swig2_compatibility.cpptest: SWIGOPT += -DSWIG2_CSHARP
|
csharp_swig2_compatibility.cpptest: SWIGOPT += -DSWIG2_CSHARP
|
||||||
|
|
||||||
|
|
|
||||||
34
Examples/test-suite/csharp/complextest_runme.cs
Normal file
34
Examples/test-suite/csharp/complextest_runme.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
// This is the complex runtime testcase. It checks that the C++ std::complex type works.
|
||||||
|
// It requires .NET 4.0 as the previous versions didn't have System.Numerics.Complex type.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
using complextestNamespace;
|
||||||
|
|
||||||
|
public class complextest_runme {
|
||||||
|
|
||||||
|
public static void Main() {
|
||||||
|
var a = new Complex(-1, 2);
|
||||||
|
if ( complextest.Conj(a) != Complex.Conjugate(a) )
|
||||||
|
throw new Exception("std::complex<double> test failed");
|
||||||
|
|
||||||
|
if ( complextest.Conjf(a) != Complex.Conjugate(a) )
|
||||||
|
throw new Exception("std::complex<float> test failed");
|
||||||
|
|
||||||
|
var vec = new VectorStdCplx();
|
||||||
|
vec.Add(new Complex(1, 2));
|
||||||
|
vec.Add(new Complex(2, 3));
|
||||||
|
vec.Add(new Complex(4, 3));
|
||||||
|
vec.Add(new Complex(1, 0));
|
||||||
|
|
||||||
|
if ( complextest.Copy_h(vec).Count != 2 )
|
||||||
|
throw new Exception("vector<complex> test failed");
|
||||||
|
|
||||||
|
var p = new ComplexPair();
|
||||||
|
p.z1 = new Complex(0, 1);
|
||||||
|
p.z2 = new Complex(0, -1);
|
||||||
|
if ( Complex.Conjugate(p.z2) != p.z1 )
|
||||||
|
throw new Exception("vector<complex> test failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,6 +26,29 @@ public class runme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class director_smartptr_MyBarFooDerived : FooDerived
|
||||||
|
{
|
||||||
|
public override string ping()
|
||||||
|
{
|
||||||
|
return "director_smartptr_MyBarFooDerived.ping()";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string pong()
|
||||||
|
{
|
||||||
|
return "director_smartptr_MyBarFooDerived.pong();" + ping();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string upcall(FooBar fooBarPtr)
|
||||||
|
{
|
||||||
|
return "overrideDerived;" + fooBarPtr.FooBarDo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Foo makeFoo()
|
||||||
|
{
|
||||||
|
return new Foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void check(string got, string expected)
|
private static void check(string got, string expected)
|
||||||
{
|
{
|
||||||
if (got != expected)
|
if (got != expected)
|
||||||
|
|
@ -49,5 +72,11 @@ public class runme
|
||||||
Foo myFoo2 = new Foo().makeFoo();
|
Foo myFoo2 = new Foo().makeFoo();
|
||||||
check(myFoo2.pong(), "Foo::pong();Foo::ping()");
|
check(myFoo2.pong(), "Foo::pong();Foo::ping()");
|
||||||
check(Foo.callPong(myFoo2), "Foo::pong();Foo::ping()");
|
check(Foo.callPong(myFoo2), "Foo::pong();Foo::ping()");
|
||||||
|
|
||||||
|
FooDerived myBarFooDerived = new director_smartptr_MyBarFooDerived();
|
||||||
|
check(myBarFooDerived.ping(), "director_smartptr_MyBarFooDerived.ping()");
|
||||||
|
check(FooDerived.callPong(myBarFooDerived), "director_smartptr_MyBarFooDerived.pong();director_smartptr_MyBarFooDerived.ping()");
|
||||||
|
check(FooDerived.callUpcall(myBarFooDerived, fooBar), "overrideDerived;Bar::Foo2::Foo2Bar()");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ public class li_std_map_runme {
|
||||||
|
|
||||||
public static void Main()
|
public static void Main()
|
||||||
{
|
{
|
||||||
// Set up an int int map
|
// Set up an string to int map
|
||||||
StringIntMap simap = new StringIntMap();
|
StringIntMap simap = new StringIntMap();
|
||||||
for (int i = 0; i < collectionSize; i++)
|
for (int i = 0; i < collectionSize; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ public class li_std_vector_runme {
|
||||||
throw new Exception("Contains test 4 failed");
|
throw new Exception("Contains test 4 failed");
|
||||||
|
|
||||||
{
|
{
|
||||||
// ICollection constructor
|
// IEnumerable constructor
|
||||||
double[] doubleArray = new double[] { 0.0, 11.1, 22.2, 33.3, 44.4, 55.5, 33.3 };
|
double[] doubleArray = new double[] { 0.0, 11.1, 22.2, 33.3, 44.4, 55.5, 33.3 };
|
||||||
DoubleVector dv = new DoubleVector(doubleArray);
|
DoubleVector dv = new DoubleVector(doubleArray);
|
||||||
if (doubleArray.Length != dv.Count)
|
if (doubleArray.Length != dv.Count)
|
||||||
|
|
@ -619,6 +619,55 @@ public class li_std_vector_runme {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test construction
|
||||||
|
{
|
||||||
|
string[] one_two_three = new string[] { "one", "two", "three" };
|
||||||
|
|
||||||
|
// Test construction from array
|
||||||
|
{
|
||||||
|
string[] collection = one_two_three;
|
||||||
|
check123(new StringVector(collection));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test construction from IEnumerable
|
||||||
|
{
|
||||||
|
global::System.Collections.IEnumerable collection = one_two_three;
|
||||||
|
check123(new StringVector(collection));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test construction from IEnumerable<>
|
||||||
|
{
|
||||||
|
global::System.Collections.Generic.IEnumerable<string> collection = one_two_three;
|
||||||
|
check123(new StringVector(collection));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test construction from IList<>
|
||||||
|
{
|
||||||
|
global::System.Collections.Generic.IList<string> collection = one_two_three;
|
||||||
|
check123(new StringVector(collection));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test construction from ICollection
|
||||||
|
{
|
||||||
|
global::System.Collections.ICollection collection = one_two_three;
|
||||||
|
check123(new StringVector(collection));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test construction from ICollection<>
|
||||||
|
{
|
||||||
|
global::System.Collections.Generic.ICollection<string> collection = new global::System.Collections.Generic.List<string>(one_two_three);
|
||||||
|
check123(new StringVector(collection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void check123(StringVector stringv) {
|
||||||
|
string concatenated = "";
|
||||||
|
foreach (string s in stringv)
|
||||||
|
concatenated = concatenated + s;
|
||||||
|
if (concatenated != "onetwothree")
|
||||||
|
throw new Exception("concatenated string failed: " + concatenated);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ public class runme {
|
||||||
assert( typeof(string) == preproc_constants_c.CONST_STRING2.GetType() );
|
assert( typeof(string) == preproc_constants_c.CONST_STRING2.GetType() );
|
||||||
|
|
||||||
assert( typeof(int) == preproc_constants_c.INT_AND_BOOL.GetType() );
|
assert( typeof(int) == preproc_constants_c.INT_AND_BOOL.GetType() );
|
||||||
// assert( typeof(int) == preproc_constants_c.INT_AND_CHAR.GetType() );
|
assert( typeof(int) == preproc_constants_c.INT_AND_CHAR.GetType() );
|
||||||
assert( typeof(int) == preproc_constants_c.INT_AND_INT.GetType() );
|
assert( typeof(int) == preproc_constants_c.INT_AND_INT.GetType() );
|
||||||
assert( typeof(uint) == preproc_constants_c.INT_AND_UINT.GetType() );
|
assert( typeof(uint) == preproc_constants_c.INT_AND_UINT.GetType() );
|
||||||
assert( typeof(int) == preproc_constants_c.INT_AND_LONG.GetType() );
|
assert( typeof(int) == preproc_constants_c.INT_AND_LONG.GetType() );
|
||||||
|
|
@ -61,7 +61,9 @@ public class runme {
|
||||||
assert( typeof(int) == preproc_constants_c.EXPR_LAND.GetType() );
|
assert( typeof(int) == preproc_constants_c.EXPR_LAND.GetType() );
|
||||||
assert( typeof(int) == preproc_constants_c.EXPR_LOR.GetType() );
|
assert( typeof(int) == preproc_constants_c.EXPR_LOR.GetType() );
|
||||||
assert( typeof(double) == preproc_constants_c.EXPR_CONDITIONAL.GetType() );
|
assert( typeof(double) == preproc_constants_c.EXPR_CONDITIONAL.GetType() );
|
||||||
|
assert( typeof(double) == preproc_constants_c.EXPR_MIXED1.GetType() );
|
||||||
|
assert( typeof(int) == preproc_constants_c.EXPR_WCHAR_MAX.GetType() );
|
||||||
|
assert( typeof(int) == preproc_constants_c.EXPR_WCHAR_MIN.GetType() );
|
||||||
}
|
}
|
||||||
static void assert(bool assertion) {
|
static void assert(bool assertion) {
|
||||||
if (!assertion)
|
if (!assertion)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ public class runme {
|
||||||
assert( typeof(string) == preproc_constants.CONST_STRING2.GetType() );
|
assert( typeof(string) == preproc_constants.CONST_STRING2.GetType() );
|
||||||
|
|
||||||
assert( typeof(int) == preproc_constants.INT_AND_BOOL.GetType() );
|
assert( typeof(int) == preproc_constants.INT_AND_BOOL.GetType() );
|
||||||
// assert( typeof(int) == preproc_constants.INT_AND_CHAR.GetType() );
|
assert( typeof(int) == preproc_constants.INT_AND_CHAR.GetType() );
|
||||||
assert( typeof(int) == preproc_constants.INT_AND_INT.GetType() );
|
assert( typeof(int) == preproc_constants.INT_AND_INT.GetType() );
|
||||||
assert( typeof(uint) == preproc_constants.INT_AND_UINT.GetType() );
|
assert( typeof(uint) == preproc_constants.INT_AND_UINT.GetType() );
|
||||||
assert( typeof(int) == preproc_constants.INT_AND_LONG.GetType() );
|
assert( typeof(int) == preproc_constants.INT_AND_LONG.GetType() );
|
||||||
|
|
@ -60,6 +60,9 @@ public class runme {
|
||||||
assert( typeof(bool) == preproc_constants.EXPR_LAND.GetType() );
|
assert( typeof(bool) == preproc_constants.EXPR_LAND.GetType() );
|
||||||
assert( typeof(bool) == preproc_constants.EXPR_LOR.GetType() );
|
assert( typeof(bool) == preproc_constants.EXPR_LOR.GetType() );
|
||||||
assert( typeof(double) == preproc_constants.EXPR_CONDITIONAL.GetType() );
|
assert( typeof(double) == preproc_constants.EXPR_CONDITIONAL.GetType() );
|
||||||
|
assert( typeof(double) == preproc_constants.EXPR_MIXED1.GetType() );
|
||||||
|
assert( typeof(int) == preproc_constants.EXPR_WCHAR_MAX.GetType() );
|
||||||
|
assert( typeof(int) == preproc_constants.EXPR_WCHAR_MIN.GetType() );
|
||||||
|
|
||||||
}
|
}
|
||||||
static void assert(bool assertion) {
|
static void assert(bool assertion) {
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue