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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,34 @@
using System;
using cpp11_move_onlyNamespace;
public class cpp11_move_only_runme {
public static void Main() {
// Output
Counter.reset_counts();
using (MoveOnly mo = MoveOnly.create()) {
}
Counter.check_counts(1, 0, 0, 2, 0, 3);
Counter.reset_counts();
using (MovableCopyable mo = MovableCopyable.create()) {
}
Counter.check_counts(2, 1, 0, 0, 1, 3);
// Move semantics not used
Counter.reset_counts();
using (MovableCopyable mo = MovableCopyable.createConst()) {
}
Counter.check_counts(2, 1, 1, 0, 0, 3);
// Input
Counter.reset_counts();
using (MovableCopyable mo = new MovableCopyable(222)) {
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable.take(mo);
Counter.check_counts(2, 0, 1, 1, 0, 2);
}
Counter.check_counts(2, 0, 1, 1, 0, 3);
}
}

View file

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

View file

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

View file

@ -0,0 +1,86 @@
using System;
using cpp11_rvalue_reference_moveNamespace;
public class cpp11_rvalue_reference_move_runme {
public static void Main() {
{
// Function containing rvalue reference parameter
Counter.reset_counts();
MovableCopyable mo = new MovableCopyable(222);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable.movein(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
if (!MovableCopyable.is_nullptr(mo))
throw new ApplicationException("is_nullptr failed");
mo.Dispose();
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
{
// Move constructor test
Counter.reset_counts();
MovableCopyable mo = new MovableCopyable(222);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable mo_moved = new MovableCopyable(mo);
Counter.check_counts(1, 0, 0, 1, 0, 1);
if (!MovableCopyable.is_nullptr(mo))
throw new ApplicationException("is_nullptr failed");
mo.Dispose();
Counter.check_counts(1, 0, 0, 1, 0, 1);
mo_moved.Dispose();
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
{
// Move assignment operator test
Counter.reset_counts();
MovableCopyable mo111 = new MovableCopyable(111);
MovableCopyable mo222 = new MovableCopyable(222);
Counter.check_counts(2, 0, 0, 0, 0, 0);
mo111.MoveAssign(mo222);
Counter.check_counts(2, 0, 0, 0, 1, 1);
if (!MovableCopyable.is_nullptr(mo222))
throw new ApplicationException("is_nullptr failed");
mo222.Dispose();
Counter.check_counts(2, 0, 0, 0, 1, 1);
mo111.Dispose();
Counter.check_counts(2, 0, 0, 0, 1, 2);
}
{
// null check
Counter.reset_counts();
bool exception_thrown = false;
try {
MovableCopyable.movein(null);
} catch (ArgumentNullException e) {
if (!e.Message.Contains("MovableCopyable && is null"))
throw new ApplicationException("incorrect exception message:" + e);
exception_thrown = true;
}
if (!exception_thrown)
throw new ApplicationException("Should have thrown null error");
Counter.check_counts(0, 0, 0, 0, 0, 0);
}
{
// output
Counter.reset_counts();
MovableCopyable mc = MovableCopyable.moveout(1234);
Counter.check_counts(2, 0, 0, 0, 1, 1);
MovableCopyable.check_numbers_match(mc, 1234);
bool exception_thrown = false;
try {
MovableCopyable.movein(mc);
} catch (ApplicationException e) {
if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
throw new ApplicationException("incorrect exception message");
exception_thrown = true;
}
if (!exception_thrown)
throw new ApplicationException("Should have thrown 'Cannot release ownership as memory is not owned' error");
Counter.check_counts(2, 0, 0, 0, 1, 1);
}
}
}

View file

@ -0,0 +1,131 @@
using System;
using cpp11_std_unique_ptrNamespace;
public class cpp11_std_unique_ptr_runme {
private static void WaitForGC()
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.Threading.Thread.Sleep(10);
}
private static void checkCount(int expected_count)
{
int actual_count = Klass.getTotal_count();
if (actual_count != expected_count)
throw new ApplicationException("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
}
public static void Main()
{
// Test raw pointer handling involving virtual inheritance
using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
checkCount(1);
string s = cpp11_std_unique_ptr.useKlassRawPtr(kini);
if (s != "KlassInheritanceInput")
throw new ApplicationException("Incorrect string: " + s);
}
checkCount(0);
// unique_ptr as input
using (Klass kin = new Klass("KlassInput")) {
checkCount(1);
string s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new ApplicationException("Incorrect string: " + s);
if (!cpp11_std_unique_ptr.is_nullptr(kin))
throw new ApplicationException("is_nullptr failed");
} // Dispose should not fail, even though already deleted
checkCount(0);
using (Klass kin = new Klass("KlassInput")) {
checkCount(1);
string s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new ApplicationException("Incorrect string: " + s);
if (!cpp11_std_unique_ptr.is_nullptr(kin))
throw new ApplicationException("is_nullptr failed");
bool exception_thrown = false;
try {
cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
} catch (ApplicationException e) {
if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
throw new ApplicationException("incorrect exception message");
exception_thrown = true;
}
if (!exception_thrown)
throw new ApplicationException("double usage of takeKlassUniquePtr should have been an error");
} // Dispose should not fail, even though already deleted
checkCount(0);
using (Klass kin = new Klass("KlassInput")) {
bool exception_thrown = false;
Klass notowned = cpp11_std_unique_ptr.get_not_owned_ptr(kin);
try {
cpp11_std_unique_ptr.takeKlassUniquePtr(notowned);
} catch (ApplicationException e) {
if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
throw new ApplicationException("incorrect exception message");
exception_thrown = true;
}
if (!exception_thrown)
throw new ApplicationException("Should have thrown 'Cannot release ownership as memory is not owned' error");
checkCount(1);
}
checkCount(0);
using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
checkCount(1);
string s = cpp11_std_unique_ptr.takeKlassUniquePtr(kini);
checkCount(0);
if (s != "KlassInheritanceInput")
throw new ApplicationException("Incorrect string: " + s);
if (!cpp11_std_unique_ptr.is_nullptr(kini))
throw new ApplicationException("is_nullptr failed");
} // Dispose should not fail, even though already deleted
checkCount(0);
cpp11_std_unique_ptr.takeKlassUniquePtr(null);
cpp11_std_unique_ptr.takeKlassUniquePtr(cpp11_std_unique_ptr.make_null());
checkCount(0);
// overloaded parameters
if (cpp11_std_unique_ptr.overloadTest() != 0)
throw new ApplicationException("overloadTest failed");
if (cpp11_std_unique_ptr.overloadTest(null) != 1)
throw new ApplicationException("overloadTest failed");
if (cpp11_std_unique_ptr.overloadTest(new Klass("over")) != 1)
throw new ApplicationException("overloadTest failed");
checkCount(0);
// unique_ptr as output
Klass k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first");
if (k1.getLabel() != "first")
throw new Exception("wrong object label");
Klass k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second");
checkCount(2);
using (Klass k3 = cpp11_std_unique_ptr.makeKlassUniquePtr("second")) {
checkCount(3);
}
checkCount(2);
k1.Dispose();
k1 = null;
checkCount(1);
if (k2.getLabel() != "second")
throw new Exception("wrong object label");
k2.Dispose();
k2 = null;
checkCount(0);
if (cpp11_std_unique_ptr.makeNullUniquePtr() != null)
throw new Exception("null failure");
}
}

View file

@ -107,6 +107,22 @@ public class TestThread {
Console.Error.WriteLine("Test failed (thread " + threadId + "): " + e.Message);
Failed = true;
}
// $imfuncname substitution
ProxyA pa = new ProxyA();
if (pa.imfuncname_test() != 123)
throw new ApplicationException("imfuncname_test is not 123");
if (ProxyA.imfuncname_static_test() != 234)
throw new ApplicationException("imfuncname_test is not 234");
if (csharp_typemaps.imfuncname_global_test() != 345)
throw new ApplicationException("imfuncname_test is not 345");
pa.variab = 1000;
if (pa.variab != 1000 + 111 + 222)
throw new ApplicationException("pa.variab is not 1333");
csharp_typemaps.global_variab = 1000;
if (csharp_typemaps.global_variab != 1000 + 333 + 444)
throw new ApplicationException("csharp_typemaps.variab is not 1777");
}
}

View file

@ -50,7 +50,7 @@ public class runme
myNewBar.x = 10;
// Low level implementation check
// my.testSwigDerivedClassHasMethod();
my.testSwigDerivedClassHasMethod();
// These should not call the C# implementations as they are not overridden
int v;

View file

@ -177,7 +177,7 @@ public class CSharpDerived : Base
// Note the following method can never be called from unmanaged code.
// It is here only for code that calls it directly from managed code.
// But should always be defined to ensure behaviour is consistent
// independent of where DefaultParsms is called from (managed or unmanaged code).
// independent of where DefaultParams is called from (managed or unmanaged code).
// Note this method can never be called from unmanaged code
public override String DefaultParms(int x)
{

View file

@ -0,0 +1,58 @@
using System;
namespace director_defaultNamespace {
public class runme
{
static void Main()
{
{
MyFoo a = new MyFoo();
a = new MyFoo(10);
a.Dispose();
}
{
MyFoo a = new MyFoo();
if (a.GetMsg() != "MyFoo-default") {
throw new Exception( "Test 1 failed" );
}
if (a.GetMsg("boo") != "MyFoo-boo") {
throw new Exception( "Test 2 failed" );
}
a.Dispose();
}
{
Foo b = new Foo();
if (b.GetMsg() != "Foo-default") {
throw new Exception( "Test 1 failed" );
}
if (b.GetMsg("boo") != "Foo-boo") {
throw new Exception( "Test 2 failed" );
}
b.Dispose();
}
}
}
public class MyFoo : Foo
{
public MyFoo()
: base()
{
}
public MyFoo(int i)
: base(i)
{
}
public override string Msg(string msg)
{
return "MyFoo-" + msg;
}
}
}

View file

@ -28,6 +28,8 @@ public class runme
break;
};
}
if (director_pass_by_value.has_cplusplus11())
Counter.check_counts(1, 0, 0, 1, 0, 1); // check move constructor called and just one destructor
// bug was the passByVal 'global' object was destroyed after the call to virtualMethod had finished.
int ret = runme.passByVal.getVal();
if (ret != 0x12345678)

View file

@ -0,0 +1,64 @@
using System;
namespace director_propertyNamespace {
public class runme
{
static void Main()
{
{
Foo a = new MyFoo();
if (a.getA() != "") {
throw new Exception( "Test failed" );
}
a.setA("Hello");
if (a.getA() != "Hello set from MyFoo") {
throw new Exception( "Test failed" );
}
a.setAByRef("Hello");
if (a.getA() != "Hello setAByRef from MyFoo") {
throw new Exception( "Test failed" );
}
a.Dispose();
}
{
Foo a_original = new MyFoo();
Foo a = Foo.get_self(a_original);
if (a.getA() != "") {
throw new Exception( "Test failed" );
}
a.setA("Hello");
if (a.getA() != "Hello set from MyFoo") {
throw new Exception( "Test failed" );
}
a.setAByRef("Hello");
if (a.getA() != "Hello setAByRef from MyFoo") {
throw new Exception( "Test failed" );
}
a.Dispose();
}
}
}
public class MyFoo : Foo
{
public MyFoo()
: base()
{
}
public override void setA(string a)
{
base.setA(a + " set from MyFoo");
}
public override void setAByRef(string a)
{
base.setA(a + " setAByRef from MyFoo");
}
}
}

View file

@ -0,0 +1,70 @@
using System;
namespace director_using_member_scopesNamespace {
public class runme
{
static void Main()
{
runme r = new runme();
r.run();
}
void run()
{
NativeWindowType nwt = new NativeWindowType();
{
MyApplicationContextSDL a = new MyApplicationContextSDL();
if (ApplicationContextBase.call_setWindowGrab(a, nwt, true) != 100)
throw new Exception("failed");
if (ApplicationContextSDL.call_setWindowGrab(a, nwt, true) != 100)
throw new Exception("failed");
}
{
MyACSDL a = new MyACSDL();
if (ACB.call_setWindowGrab(a, nwt, true) != 100)
throw new Exception("failed");
if (ACB.call_setWindowGrab(a, "hi", 0) != 200)
throw new Exception("failed");
if (ACSDL.call_setWindowGrab(a, nwt, true) != 100)
throw new Exception("failed");
if (ACSDL.call_setWindowGrab(a, "hi", 0) != 200)
throw new Exception("failed");
}
}
}
class MyApplicationContextSDL: ApplicationContextSDL
{
public MyApplicationContextSDL() : base()
{
}
public override int setWindowGrab(NativeWindowType win, bool grab)
{
return 100;
}
}
class MyACSDL: ACSDL
{
public MyACSDL() : base()
{
}
public override int setWindowGrab(NativeWindowType win, bool grab)
{
return 100;
}
public override int setWindowGrab(string s, int val)
{
return 200;
}
}
}

View file

@ -0,0 +1,56 @@
using System;
using director_wstringNamespace;
public class runme
{
static void Main()
{
runme r = new runme();
r.run();
}
void run()
{
director_wstring_B b = new director_wstring_B("hello");
b.get(0);
if (b.get_first() != "hello world!")
throw new ApplicationException("Incorrect get_first:" + b.get_first());
b.call_process_func();
if (b.smem != "hello")
throw new ApplicationException("Incorrect smem:" + b.smem);
b.call_process_wstring_func();
if (b.smem != "hello (wstring)")
throw new ApplicationException("Incorrect smem:" + b.smem);
b.call_process_wstring_ref_func();
if (b.smem != "hello (wstring ref)")
throw new ApplicationException("Incorrect smem:" + b.smem);
}
}
class director_wstring_B : A
{
public String smem;
public director_wstring_B(String first) : base(first)
{
}
public override String get_first()
{
return base.get_first() + " world!";
}
public override void process_text(String s)
{
this.smem = s;
}
public override void process_wstring_text(String s)
{
this.smem = s + " (wstring)";
}
public override void process_wstring_ref_text(String s)
{
this.smem = s + " (wstring ref)";
}
}

View file

@ -22,7 +22,7 @@ public class friends_runme {
if (friends.mix(a,b) != 5)
throw new Exception("failed");
D_d di = new D_d(2);
D_i di = new D_i(2);
D_d dd = new D_d(3.3);
// incredible template overloading working just fine

View file

@ -9,56 +9,123 @@ public class li_std_auto_ptr_runme {
System.Threading.Thread.Sleep(10);
}
private static void checkCount(int expected_count)
{
int actual_count = Klass.getTotal_count();
if (actual_count != expected_count)
throw new ApplicationException("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
}
public static void Main()
{
// Test raw pointer handling involving virtual inheritance
using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
checkCount(1);
string s = li_std_auto_ptr.useKlassRawPtr(kini);
if (s != "KlassInheritanceInput")
throw new ApplicationException("Incorrect string: " + s);
}
checkCount(0);
// auto_ptr as input
using (Klass kin = new Klass("KlassInput")) {
checkCount(1);
string s = li_std_auto_ptr.takeKlassAutoPtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new ApplicationException("Incorrect string: " + s);
if (!li_std_auto_ptr.is_nullptr(kin))
throw new ApplicationException("is_nullptr failed");
} // Dispose should not fail, even though already deleted
checkCount(0);
using (Klass kin = new Klass("KlassInput")) {
checkCount(1);
string s = li_std_auto_ptr.takeKlassAutoPtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new ApplicationException("Incorrect string: " + s);
if (!li_std_auto_ptr.is_nullptr(kin))
throw new ApplicationException("is_nullptr failed");
bool exception_thrown = false;
try {
li_std_auto_ptr.takeKlassAutoPtr(kin);
} catch (ApplicationException e) {
if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
throw new ApplicationException("incorrect exception message");
exception_thrown = true;
}
if (!exception_thrown)
throw new ApplicationException("double usage of takeKlassAutoPtr should have been an error");
} // Dispose should not fail, even though already deleted
checkCount(0);
using (Klass kin = new Klass("KlassInput")) {
bool exception_thrown = false;
Klass notowned = li_std_auto_ptr.get_not_owned_ptr(kin);
try {
li_std_auto_ptr.takeKlassAutoPtr(notowned);
} catch (ApplicationException e) {
if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
throw new ApplicationException("incorrect exception message");
exception_thrown = true;
}
if (!exception_thrown)
throw new ApplicationException("Should have thrown 'Cannot release ownership as memory is not owned' error");
checkCount(1);
}
checkCount(0);
using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
checkCount(1);
string s = li_std_auto_ptr.takeKlassAutoPtr(kini);
checkCount(0);
if (s != "KlassInheritanceInput")
throw new ApplicationException("Incorrect string: " + s);
if (!li_std_auto_ptr.is_nullptr(kini))
throw new ApplicationException("is_nullptr failed");
} // Dispose should not fail, even though already deleted
checkCount(0);
li_std_auto_ptr.takeKlassAutoPtr(null);
li_std_auto_ptr.takeKlassAutoPtr(li_std_auto_ptr.make_null());
checkCount(0);
// overloaded parameters
if (li_std_auto_ptr.overloadTest() != 0)
throw new ApplicationException("overloadTest failed");
if (li_std_auto_ptr.overloadTest(null) != 1)
throw new ApplicationException("overloadTest failed");
if (li_std_auto_ptr.overloadTest(new Klass("over")) != 1)
throw new ApplicationException("overloadTest failed");
checkCount(0);
// auto_ptr as output
Klass k1 = li_std_auto_ptr.makeKlassAutoPtr("first");
if (k1.getLabel() != "first")
throw new Exception("wrong object label");
Klass k2 = li_std_auto_ptr.makeKlassAutoPtr("second");
if (Klass.getTotal_count() != 2)
throw new Exception("number of objects should be 2");
checkCount(2);
using (Klass k3 = li_std_auto_ptr.makeKlassAutoPtr("second")) {
if (Klass.getTotal_count() != 3)
throw new Exception("number of objects should be 3");
checkCount(3);
}
if (Klass.getTotal_count() != 2)
throw new Exception("number of objects should be 2");
checkCount(2);
k1.Dispose();
k1 = null;
{
int countdown = 500;
int expectedCount = 1;
while (true) {
WaitForGC();
if (--countdown == 0)
break;
if (Klass.getTotal_count() == expectedCount)
break;
};
int actualCount = Klass.getTotal_count();
if (actualCount != expectedCount)
Console.Error.WriteLine("Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
}
checkCount(1);
if (k2.getLabel() != "second")
throw new Exception("wrong object label");
k2.Dispose();
k2 = null;
{
int countdown = 500;
int expectedCount = 0;
while (true) {
WaitForGC();
if (--countdown == 0)
break;
if (Klass.getTotal_count() == expectedCount)
break;
}
int actualCount = Klass.getTotal_count();
if (actualCount != expectedCount)
Console.Error.WriteLine("Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
}
checkCount(0);
if (li_std_auto_ptr.makeNullAutoPtr() != null)
throw new Exception("null failure");
}
}

View file

@ -1,3 +1,6 @@
// This file has a BOM for UTF-8
// Notes for displaying UTF-8 properly in Windows: https://stackoverflow.com/questions/49476326/displaying-unicode-in-powershell
using System;
using li_std_wstringNamespace;
@ -5,17 +8,38 @@ public class runme
{
static private void check_equal(char a, char b)
{
if (a != b)
throw new Exception("char failed '" + a + "' != '" + b + "'");
if (a != b)
throw new Exception("char failed '" + a + "' != '" + b + "'");
}
static private void display_bytes(string s)
{
Console.Write("[");
if (s != null)
{
foreach (char x in s)
{
int n = Convert.ToInt32(x);
Console.Write(n.ToString("X") + " ");
}
}
else
Console.Write("null");
Console.WriteLine("]");
}
static private void check_equal(string a, string b)
{
if (a != b)
throw new Exception("string failed '" + a + "' != '" + b + "'");
if (li_std_wstring.trace) {
Console.WriteLine("check_equal {0} {1}", a, b);
display_bytes(a);
display_bytes(b);
}
if (a != b)
throw new Exception("string failed '" + a + "' != '" + b + "'");
}
static void Main()
static void Main()
{
char h = 'h';
check_equal(li_std_wstring.test_wcvalue(h), h);
@ -30,6 +54,8 @@ public class runme
li_std_wstring.test_pointer(null);
li_std_wstring.test_const_pointer(null);
check_equal(li_std_wstring.test_ccvalue(null), null);
try {
li_std_wstring.test_value(null);
throw new Exception("NULL check failed");
@ -37,10 +63,10 @@ public class runme
}
try {
li_std_wstring.test_reference(null);
throw new Exception("NULL check failed");
li_std_wstring.test_reference(null);
throw new Exception("NULL check failed");
} catch (ArgumentNullException e) {
if (!e.Message.Contains("type is null"))
if (!e.Message.Contains("is null"))
throw new Exception("Missing text " + e);
}
try {
@ -54,13 +80,24 @@ public class runme
x = "hello";
check_equal(li_std_wstring.test_const_reference(x), x);
/* Postpone, tricky, std::wstring portability problem.
/* Tricky, std::wstring portability problem.
* std::wstring is 2 bytes on Windows, 4 bytes on Linux, LPWSTR is 2 bytes.
* .NET marshalling should work on Windows but not Linux.
string s = "abc";
if (!li_std_wstring.test_equal_abc(s))
throw new Exception("Not equal " + s);
*/
*/
string ss = "abc";
if (!li_std_wstring.test_equal_abc(ss))
throw new Exception("Not equal " + ss);
ss = "JP: 日本語";
if (!li_std_wstring.test_equal_jp(ss))
throw new Exception("Not equal " + ss);
ss = "DE: Kröpeliner Straße";
if (!li_std_wstring.test_equal_de(ss))
throw new Exception("Not equal " + ss);
ss = "RU: Война и мир";
if (!li_std_wstring.test_equal_ru(ss))
throw new Exception("Not equal " + ss);
try {
li_std_wstring.test_throw();
@ -68,6 +105,24 @@ public class runme
check_equal(e.Message, "throwing test_throw");
}
try {
li_std_wstring.test_throw_jp();
} catch (Exception e) {
check_equal(e.Message, "JP: 日本語");
}
try {
li_std_wstring.test_throw_ref_jp();
} catch (Exception e) {
check_equal(e.Message, "JP: 日本語");
}
try {
li_std_wstring.test_throw_wchar_t_ptr();
} catch (Exception e) {
check_equal(e.Message, "JP: 日本語");
}
x = "abc\0def";
// Unlike other languages, embedded NULL in std::string not supported
// check_equal(li_std_wstring.test_value(x), x);
@ -81,15 +136,22 @@ public class runme
check_equal(s.wchar_t_member, h);
s.wchar_t_ptr_member = x;
check_equal(s.wchar_t_ptr_member, "abc");
s.wchar_t_ptr_member = ss;
check_equal(s.wchar_t_ptr_member, ss);
{
// Unicode strings
// Strings below are UTF8 in this file, but .NET holds them internally as UTF16
// DE: https://www.utf8-chartable.de/
// RU: https://www.utf8-chartable.de/unicode-utf8-table.pl?start=1024
string[] test_strings = {
"JP: 日本語", "DE: Kröpeliner Straße" , "RU: Война и мир", "EN: War and Peace"
};
foreach (string expected in test_strings)
{
if (li_std_wstring.trace)
Console.WriteLine("expected (C#): " + expected);
string received = li_std_wstring.test_value(expected);
check_equal(received, expected);
}

View file

@ -83,5 +83,7 @@ public class multiple_inheritance_interfaces_runme {
d.ia(10);
d.ia("bye");
d.ia("bye", false);
UndesirablesSwigImpl.UndesiredStaticMethod(UndesirablesSwigImpl.UndesiredEnum.UndesiredEnum1);
}
}

View file

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using multiple_inheritance_overloadNamespace;
public class multiple_inheritance_overload_runme {
public static void check(bool fail, String msg) {
if (fail)
throw new Exception(msg);
}
public static void Main() {
int i = 0;
Base b1 = new Derived();
check(b1.Method(i) != 0, "b1.Method failed");
check(b1.MethodForRenaming(i) != 0, "b1.MethodForRenaming failed");
check(b1.MethodForRenamingConst(i) != 1, "b1.MethodForRenamingConst failed");
check(b1.MethodWarningSuppressed(i) != 0, "b1.MethodWarningSuppressed failed");
check(b1.NotVirtualMethod(i) != 0, "b1.NotVirtualMethod failed");
check(b1.SimilarOverloadedMethod(i) != 0, "b1.NotVirtualMethod failed");
Derived d1 = new Derived();
check(d1.Method(i) != 0, "d1.Method failed");
check(d1.MethodForRenaming(i) != 0, "d1.MethodForRenaming failed");
check(d1.MethodForRenamingConst(i) != 1, "d1.MethodForRenamingConst failed");
check(d1.MethodWarningSuppressed(i) != 0, "d1.MethodWarningSuppressed failed");
check(d1.NotVirtualMethod(i) != 0, "d1.NotVirtualMethod failed");
check(d1.SimilarOverloadedMethod(i) != 0, "d1.NotVirtualMethod failed");
check(d1.AnotherMethod(i) != 0, "d1.AnotherMethod failed");
Base db1 = BaseSwigImpl.in_out(d1);
check(db1.Method(i) != 0, "db1.Method failed");
check(db1.MethodForRenaming(i) != 0, "db1.MethodForRenaming failed");
check(db1.MethodForRenamingConst(i) != 1, "db1.MethodForRenamingConst failed");
check(db1.MethodWarningSuppressed(i) != 0, "db1.MethodWarningSuppressed failed");
check(db1.NotVirtualMethod(i) != 0, "db1.NotVirtualMethod failed");
check(db1.SimilarOverloadedMethod(i) != 0, "db1.NotVirtualMethod failed");
MoreDerived m1 = new MoreDerived();
check(m1.Method(i) != 0, "m1.Method failed");
check(m1.MethodForRenaming(i) != 0, "m1.MethodForRenaming failed");
check(m1.MethodForRenamingConst(i) != 1, "m1.MethodForRenamingConst failed");
check(m1.MethodWarningSuppressed(i) != 0, "m1.MethodWarningSuppressed failed");
check(m1.NotVirtualMethod(i) != 0, "m1.NotVirtualMethod failed");
check(m1.SimilarOverloadedMethod(i) != 0, "m1.NotVirtualMethod failed");
check(m1.AnotherMethod(i) != 0, "m1.AnotherMethod failed");
Base mb2 = BaseSwigImpl.in_out(m1);
check(mb2.Method(i) != 0, "mb2.Method failed");
check(mb2.MethodForRenaming(i) != 0, "mb2.MethodForRenaming failed");
check(mb2.MethodForRenamingConst(i) != 1, "mb2.MethodForRenamingConst failed");
check(mb2.MethodWarningSuppressed(i) != 0, "mb2.MethodWarningSuppressed failed");
check(mb2.NotVirtualMethod(i) != 0, "mb2.NotVirtualMethod failed");
check(mb2.SimilarOverloadedMethod(i) != 0, "mb2.NotVirtualMethod failed");
}
}

View file

@ -51,6 +51,8 @@ public class runme {
assert( typeof(int) == preproc_constants_c.EXPR_MINUS.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_LSHIFT.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_RSHIFT.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_LT.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_GT.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_LTE.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_GTE.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_INEQUALITY.GetType() );

View file

@ -50,6 +50,8 @@ public class runme {
assert( typeof(int) == preproc_constants.EXPR_MINUS.GetType() );
assert( typeof(int) == preproc_constants.EXPR_LSHIFT.GetType() );
assert( typeof(int) == preproc_constants.EXPR_RSHIFT.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_LT.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_GT.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_LTE.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_GTE.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_INEQUALITY.GetType() );

View file

@ -3,10 +3,14 @@ using typemap_out_optimalNamespace;
public class typemap_out_optimal_runme {
public static XX x = null;
public static void Main() {
XX.debug = false;
x = XX.create();
XX.trace = false;
if (XX.trace)
Console.WriteLine("calling create()");
using (XX x = XX.create()) { }
if (XX.trace)
Console.WriteLine("calling createConst()");
using (XX x = XX.createConst()) { }
}
}

View file

@ -136,3 +136,42 @@ namespace Glob {
bool MVar::svar = false;
%}
// $imfuncname substitution
%typemap(csout) int imfuncname_test {
return $modulePINVOKE.$imfuncname(swigCPtr) + 123;
}
%typemap(csout) int imfuncname_static_test {
return $modulePINVOKE.$imfuncname() + 234;
}
%typemap(csout) int imfuncname_global_test {
return $modulePINVOKE.$imfuncname() + 345;
}
%typemap(csvarout, excode=SWIGEXCODE2) int variab %{
get {
int ret = $modulePINVOKE.$imfuncname(swigCPtr) + 222;$excode
return ret;
} %}
%typemap(csvarin, excode=SWIGEXCODE2) int variab %{
set {
$modulePINVOKE.$imfuncname(swigCPtr, value + 111);$excode
} %}
%typemap(csvarout, excode=SWIGEXCODE2) int global_variab %{
get {
int ret = $modulePINVOKE.$imfuncname() + 333;$excode
return ret;
} %}
%typemap(csvarin, excode=SWIGEXCODE2) int global_variab %{
set {
$modulePINVOKE.$imfuncname(value + 444);$excode
} %}
%inline %{
struct ProxyA {
int imfuncname_test() { return 0; }
static int imfuncname_static_test() { return 0; }
int variab;
};
int imfuncname_global_test() { return 0; }
int global_variab;
%}

View file

@ -4,6 +4,10 @@
LANGUAGE = d
HAVE_CXX11 = @HAVE_CXX11@
HAVE_CXX14 = @HAVE_CXX14@
HAVE_CXX17 = @HAVE_CXX17@
HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = ../@top_srcdir@
top_builddir = ../@top_builddir@

View file

@ -0,0 +1,42 @@
module cpp11_move_typemaps_runme;
import cpp11_move_typemaps.Counter;
import cpp11_move_typemaps.MoveOnly;
import cpp11_move_typemaps.MovableCopyable;
import std.conv;
import std.algorithm;
void main() {
{
Counter.reset_counts();
scope MoveOnly mo = new MoveOnly(111);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MoveOnly.take(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
{
Counter.reset_counts();
scope MovableCopyable mo = new MovableCopyable(111);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable.take(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
{
scope MoveOnly mo = new MoveOnly(222);
MoveOnly.take(mo);
bool exception_thrown = false;
try {
MoveOnly.take(mo);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("double usage of take should have been an error");
}
}

View file

@ -0,0 +1,42 @@
module cpp11_move_typemaps_runme;
import cpp11_move_typemaps.Counter;
import cpp11_move_typemaps.MoveOnly;
import cpp11_move_typemaps.MovableCopyable;
import std.conv;
import std.algorithm;
void main() {
{
Counter.reset_counts();
scope MoveOnly mo = new MoveOnly(111);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MoveOnly.take(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
{
Counter.reset_counts();
scope MovableCopyable mo = new MovableCopyable(111);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable.take(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
{
scope MoveOnly mo = new MoveOnly(222);
MoveOnly.take(mo);
bool exception_thrown = false;
try {
MoveOnly.take(mo);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("double usage of take should have been an error");
}
}

View file

@ -0,0 +1,86 @@
module cpp11_rvalue_reference_move_runme;
import cpp11_rvalue_reference_move.Counter;
import cpp11_rvalue_reference_move.MovableCopyable;
void main() {
{
// Function containing rvalue reference parameter
Counter.reset_counts();
scope MovableCopyable mo = new MovableCopyable(222);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable.movein(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
if (!MovableCopyable.is_nullptr(mo))
throw new Exception("is_nullptr failed");
mo.dispose();
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
{
// Move constructor test
Counter.reset_counts();
scope MovableCopyable mo = new MovableCopyable(222);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable mo_moved = new MovableCopyable(mo);
Counter.check_counts(1, 0, 0, 1, 0, 1);
if (!MovableCopyable.is_nullptr(mo))
throw new Exception("is_nullptr failed");
mo.dispose();
Counter.check_counts(1, 0, 0, 1, 0, 1);
mo_moved.dispose();
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
{
// Move assignment operator test
Counter.reset_counts();
scope MovableCopyable mo111 = new MovableCopyable(111);
scope MovableCopyable mo222 = new MovableCopyable(222);
Counter.check_counts(2, 0, 0, 0, 0, 0);
mo111.MoveAssign(mo222);
Counter.check_counts(2, 0, 0, 0, 1, 1);
if (!MovableCopyable.is_nullptr(mo222))
throw new Exception("is_nullptr failed");
mo222.dispose();
Counter.check_counts(2, 0, 0, 0, 1, 1);
mo111.dispose();
Counter.check_counts(2, 0, 0, 0, 1, 2);
}
{
// null check
Counter.reset_counts();
bool exception_thrown = false;
try {
MovableCopyable.movein(null);
} catch (Exception e) {
if (!canFind(e.msg, "MovableCopyable && is null"))
throw new Exception("incorrect exception message:" ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("Should have thrown null error");
Counter.check_counts(0, 0, 0, 0, 0, 0);
}
{
// output
Counter.reset_counts();
MovableCopyable mc = MovableCopyable.moveout(1234);
Counter.check_counts(2, 0, 0, 0, 1, 1);
MovableCopyable.check_numbers_match(mc, 1234);
bool exception_thrown = false;
try {
MovableCopyable.movein(mc);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
Counter.check_counts(2, 0, 0, 0, 1, 1);
}
}

View file

@ -0,0 +1,87 @@
module cpp11_rvalue_reference_move_runme;
import cpp11_rvalue_reference_move.Counter;
import cpp11_rvalue_reference_move.MovableCopyable;
import std.algorithm;
void main() {
{
// Function containing rvalue reference parameter
Counter.reset_counts();
scope MovableCopyable mo = new MovableCopyable(222);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable.movein(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
if (!MovableCopyable.is_nullptr(mo))
throw new Exception("is_nullptr failed");
mo.dispose();
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
{
// Move constructor test
Counter.reset_counts();
scope MovableCopyable mo = new MovableCopyable(222);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable mo_moved = new MovableCopyable(mo);
Counter.check_counts(1, 0, 0, 1, 0, 1);
if (!MovableCopyable.is_nullptr(mo))
throw new Exception("is_nullptr failed");
mo.dispose();
Counter.check_counts(1, 0, 0, 1, 0, 1);
mo_moved.dispose();
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
{
// Move assignment operator test
Counter.reset_counts();
scope MovableCopyable mo111 = new MovableCopyable(111);
scope MovableCopyable mo222 = new MovableCopyable(222);
Counter.check_counts(2, 0, 0, 0, 0, 0);
mo111.MoveAssign(mo222);
Counter.check_counts(2, 0, 0, 0, 1, 1);
if (!MovableCopyable.is_nullptr(mo222))
throw new Exception("is_nullptr failed");
mo222.dispose();
Counter.check_counts(2, 0, 0, 0, 1, 1);
mo111.dispose();
Counter.check_counts(2, 0, 0, 0, 1, 2);
}
{
// null check
Counter.reset_counts();
bool exception_thrown = false;
try {
MovableCopyable.movein(null);
} catch (Exception e) {
if (!canFind(e.msg, "MovableCopyable && is null"))
throw new Exception("incorrect exception message:" ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("Should have thrown null error");
Counter.check_counts(0, 0, 0, 0, 0, 0);
}
{
// output
Counter.reset_counts();
MovableCopyable mc = MovableCopyable.moveout(1234);
Counter.check_counts(2, 0, 0, 0, 1, 1);
MovableCopyable.check_numbers_match(mc, 1234);
bool exception_thrown = false;
try {
MovableCopyable.movein(mc);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
Counter.check_counts(2, 0, 0, 0, 1, 1);
}
}

View file

@ -0,0 +1,123 @@
module cpp11_std_unique_ptr_runme;
import cpp11_std_unique_ptr.cpp11_std_unique_ptr;
import cpp11_std_unique_ptr.Klass;
import cpp11_std_unique_ptr.KlassInheritance;
import std.conv;
import std.algorithm;
void checkCount(int expected_count) {
int actual_count = Klass.getTotal_count();
if (actual_count != expected_count)
throw new Exception("Counts incorrect, expected:" ~ to!string(expected_count) ~ " actual:" ~ to!string(actual_count));
}
void main() {
// Test raw pointer handling involving virtual inheritance
{
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
checkCount(1);
string s = useKlassRawPtr(kini);
if (s != "KlassInheritanceInput")
throw new Exception("Incorrect string: " ~ s);
}
checkCount(0);
// unique_ptr as input
{
scope Klass kin = new Klass("KlassInput");
checkCount(1);
string s = takeKlassUniquePtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kin))
throw new Exception("is_nullptr failed");
} // dispose should not fail, even though already deleted
checkCount(0);
{
scope Klass kin = new Klass("KlassInput");
checkCount(1);
string s = takeKlassUniquePtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kin))
throw new Exception("is_nullptr failed");
bool exception_thrown = false;
try {
takeKlassUniquePtr(kin);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("double usage of takeKlassUniquePtr should have been an error");
} // dispose should not fail, even though already deleted
checkCount(0);
{
scope Klass kin = new Klass("KlassInput");
bool exception_thrown = false;
Klass notowned = get_not_owned_ptr(kin);
try {
takeKlassUniquePtr(notowned);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
checkCount(1);
}
checkCount(0);
{
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
checkCount(1);
string s = takeKlassUniquePtr(kini);
checkCount(0);
if (s != "KlassInheritanceInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kini))
throw new Exception("is_nullptr failed");
} // dispose should not fail, even though already deleted
checkCount(0);
takeKlassUniquePtr(null);
takeKlassUniquePtr(make_null());
checkCount(0);
// overloaded parameters
if (overloadTest() != 0)
throw new Exception("overloadTest failed");
if (overloadTest(null) != 1)
throw new Exception("overloadTest failed");
if (overloadTest(new Klass("over")) != 1)
throw new Exception("overloadTest failed");
checkCount(0);
// unique_ptr as output
Klass k1 = makeKlassUniquePtr("first");
if (k1.getLabel() != "first")
throw new Exception("wrong object label");
Klass k2 = makeKlassUniquePtr("second");
checkCount(2);
k1.dispose();
checkCount(1);
if (k2.getLabel() != "second")
throw new Exception("wrong object label");
k2.dispose();
checkCount(0);
if (makeNullUniquePtr() !is null)
throw new Exception("null failure");
}

View file

@ -0,0 +1,123 @@
module cpp11_std_unique_ptr_runme;
import cpp11_std_unique_ptr.cpp11_std_unique_ptr;
import cpp11_std_unique_ptr.Klass;
import cpp11_std_unique_ptr.KlassInheritance;
import std.conv;
import std.algorithm;
void checkCount(int expected_count) {
int actual_count = Klass.getTotal_count();
if (actual_count != expected_count)
throw new Exception("Counts incorrect, expected:" ~ to!string(expected_count) ~ " actual:" ~ to!string(actual_count));
}
void main() {
// Test raw pointer handling involving virtual inheritance
{
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
checkCount(1);
string s = useKlassRawPtr(kini);
if (s != "KlassInheritanceInput")
throw new Exception("Incorrect string: " ~ s);
}
checkCount(0);
// unique_ptr as input
{
scope Klass kin = new Klass("KlassInput");
checkCount(1);
string s = takeKlassUniquePtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kin))
throw new Exception("is_nullptr failed");
} // dispose should not fail, even though already deleted
checkCount(0);
{
scope Klass kin = new Klass("KlassInput");
checkCount(1);
string s = takeKlassUniquePtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kin))
throw new Exception("is_nullptr failed");
bool exception_thrown = false;
try {
takeKlassUniquePtr(kin);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("double usage of takeKlassUniquePtr should have been an error");
} // dispose should not fail, even though already deleted
checkCount(0);
{
scope Klass kin = new Klass("KlassInput");
bool exception_thrown = false;
Klass notowned = get_not_owned_ptr(kin);
try {
takeKlassUniquePtr(notowned);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
checkCount(1);
}
checkCount(0);
{
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
checkCount(1);
string s = takeKlassUniquePtr(kini);
checkCount(0);
if (s != "KlassInheritanceInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kini))
throw new Exception("is_nullptr failed");
} // dispose should not fail, even though already deleted
checkCount(0);
takeKlassUniquePtr(null);
takeKlassUniquePtr(make_null());
checkCount(0);
// overloaded parameters
if (overloadTest() != 0)
throw new Exception("overloadTest failed");
if (overloadTest(null) != 1)
throw new Exception("overloadTest failed");
if (overloadTest(new Klass("over")) != 1)
throw new Exception("overloadTest failed");
checkCount(0);
// unique_ptr as output
Klass k1 = makeKlassUniquePtr("first");
if (k1.getLabel() != "first")
throw new Exception("wrong object label");
Klass k2 = makeKlassUniquePtr("second");
checkCount(2);
k1.dispose();
checkCount(1);
if (k2.getLabel() != "second")
throw new Exception("wrong object label");
k2.dispose();
checkCount(0);
if (makeNullUniquePtr() !is null)
throw new Exception("null failure");
}

View file

@ -0,0 +1,123 @@
module li_std_auto_ptr_runme;
import li_std_auto_ptr.li_std_auto_ptr;
import li_std_auto_ptr.Klass;
import li_std_auto_ptr.KlassInheritance;
import std.conv;
import std.algorithm;
void checkCount(int expected_count) {
int actual_count = Klass.getTotal_count();
if (actual_count != expected_count)
throw new Exception("Counts incorrect, expected:" ~ to!string(expected_count) ~ " actual:" ~ to!string(actual_count));
}
void main() {
// Test raw pointer handling involving virtual inheritance
{
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
checkCount(1);
string s = useKlassRawPtr(kini);
if (s != "KlassInheritanceInput")
throw new Exception("Incorrect string: " ~ s);
}
checkCount(0);
// auto_ptr as input
{
scope Klass kin = new Klass("KlassInput");
checkCount(1);
string s = takeKlassAutoPtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kin))
throw new Exception("is_nullptr failed");
} // dispose should not fail, even though already deleted
checkCount(0);
{
scope Klass kin = new Klass("KlassInput");
checkCount(1);
string s = takeKlassAutoPtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kin))
throw new Exception("is_nullptr failed");
bool exception_thrown = false;
try {
takeKlassAutoPtr(kin);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("double usage of takeKlassAutoPtr should have been an error");
} // dispose should not fail, even though already deleted
checkCount(0);
{
scope Klass kin = new Klass("KlassInput");
bool exception_thrown = false;
Klass notowned = get_not_owned_ptr(kin);
try {
takeKlassAutoPtr(notowned);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
checkCount(1);
}
checkCount(0);
{
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
checkCount(1);
string s = takeKlassAutoPtr(kini);
checkCount(0);
if (s != "KlassInheritanceInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kini))
throw new Exception("is_nullptr failed");
} // dispose should not fail, even though already deleted
checkCount(0);
takeKlassAutoPtr(null);
takeKlassAutoPtr(make_null());
checkCount(0);
// overloaded parameters
if (overloadTest() != 0)
throw new Exception("overloadTest failed");
if (overloadTest(null) != 1)
throw new Exception("overloadTest failed");
if (overloadTest(new Klass("over")) != 1)
throw new Exception("overloadTest failed");
checkCount(0);
// auto_ptr as output
Klass k1 = makeKlassAutoPtr("first");
if (k1.getLabel() != "first")
throw new Exception("wrong object label");
Klass k2 = makeKlassAutoPtr("second");
checkCount(2);
k1.dispose();
checkCount(1);
if (k2.getLabel() != "second")
throw new Exception("wrong object label");
k2.dispose();
checkCount(0);
if (makeNullAutoPtr() !is null)
throw new Exception("null failure");
}

View file

@ -0,0 +1,123 @@
module li_std_auto_ptr_runme;
import li_std_auto_ptr.li_std_auto_ptr;
import li_std_auto_ptr.Klass;
import li_std_auto_ptr.KlassInheritance;
import std.conv;
import std.algorithm;
void checkCount(int expected_count) {
int actual_count = Klass.getTotal_count();
if (actual_count != expected_count)
throw new Exception("Counts incorrect, expected:" ~ to!string(expected_count) ~ " actual:" ~ to!string(actual_count));
}
void main() {
// Test raw pointer handling involving virtual inheritance
{
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
checkCount(1);
string s = useKlassRawPtr(kini);
if (s != "KlassInheritanceInput")
throw new Exception("Incorrect string: " ~ s);
}
checkCount(0);
// auto_ptr as input
{
scope Klass kin = new Klass("KlassInput");
checkCount(1);
string s = takeKlassAutoPtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kin))
throw new Exception("is_nullptr failed");
} // dispose should not fail, even though already deleted
checkCount(0);
{
scope Klass kin = new Klass("KlassInput");
checkCount(1);
string s = takeKlassAutoPtr(kin);
checkCount(0);
if (s != "KlassInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kin))
throw new Exception("is_nullptr failed");
bool exception_thrown = false;
try {
takeKlassAutoPtr(kin);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("double usage of takeKlassAutoPtr should have been an error");
} // dispose should not fail, even though already deleted
checkCount(0);
{
scope Klass kin = new Klass("KlassInput");
bool exception_thrown = false;
Klass notowned = get_not_owned_ptr(kin);
try {
takeKlassAutoPtr(notowned);
} catch (Exception e) {
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
throw new Exception("incorrect exception message: " ~ e.msg);
exception_thrown = true;
}
if (!exception_thrown)
throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
checkCount(1);
}
checkCount(0);
{
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
checkCount(1);
string s = takeKlassAutoPtr(kini);
checkCount(0);
if (s != "KlassInheritanceInput")
throw new Exception("Incorrect string: " ~ s);
if (!is_nullptr(kini))
throw new Exception("is_nullptr failed");
} // dispose should not fail, even though already deleted
checkCount(0);
takeKlassAutoPtr(null);
takeKlassAutoPtr(make_null());
checkCount(0);
// overloaded parameters
if (overloadTest() != 0)
throw new Exception("overloadTest failed");
if (overloadTest(null) != 1)
throw new Exception("overloadTest failed");
if (overloadTest(new Klass("over")) != 1)
throw new Exception("overloadTest failed");
checkCount(0);
// auto_ptr as output
Klass k1 = makeKlassAutoPtr("first");
if (k1.getLabel() != "first")
throw new Exception("wrong object label");
Klass k2 = makeKlassAutoPtr("second");
checkCount(2);
k1.dispose();
checkCount(1);
if (k2.getLabel() != "second")
throw new Exception("wrong object label");
k2.dispose();
checkCount(0);
if (makeNullAutoPtr() !is null)
throw new Exception("null failure");
}

View file

@ -51,6 +51,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
static assert(is(int == typeof(EXPR_LT())));
static assert(is(int == typeof(EXPR_GT())));
static assert(is(int == typeof(EXPR_LTE())));
static assert(is(int == typeof(EXPR_GTE())));
static assert(is(int == typeof(EXPR_INEQUALITY())));

View file

@ -51,6 +51,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
static assert(is(int == typeof(EXPR_LT())));
static assert(is(int == typeof(EXPR_GT())));
static assert(is(int == typeof(EXPR_LTE())));
static assert(is(int == typeof(EXPR_GTE())));
static assert(is(int == typeof(EXPR_INEQUALITY())));

View file

@ -50,6 +50,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
static assert(is(int == typeof(EXPR_LT())));
static assert(is(int == typeof(EXPR_GT())));
static assert(is(bool == typeof(EXPR_LTE())));
static assert(is(bool == typeof(EXPR_GTE())));
static assert(is(bool == typeof(EXPR_INEQUALITY())));

View file

@ -50,6 +50,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
static assert(is(bool == typeof(EXPR_LT())));
static assert(is(bool == typeof(EXPR_GT())));
static assert(is(bool == typeof(EXPR_LTE())));
static assert(is(bool == typeof(EXPR_GTE())));
static assert(is(bool == typeof(EXPR_INEQUALITY())));

View file

@ -6,4 +6,5 @@ void main() {
XX x;
XX.trace = false;
x = XX.create();
x = XX.createConst();
}

View file

@ -6,4 +6,5 @@ void main() {
XX x;
XX.trace = false;
x = XX.create();
x = XX.createConst();
}

View file

@ -8,20 +8,29 @@
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) UsdGeomTokensPtr;
%immutable UsdGeomTokens;
// Don't call our getters get_xxx() as that collides with generated getters in
// some languages (e.g. csharp).
%inline %{
struct Numbers {
int val;
int *ptr;
const int& g_val() const { return val; }
const int* g_ptr() const { return ptr; }
Numbers() : val(), ptr(&val) {}
};
struct TfToken {
Numbers val;
Numbers *ptr;
const Numbers& g_val() const { return val; }
const Numbers* g_ptr() const { return ptr; }
TfToken() : val(), ptr(&val) {}
};
struct Tokens {
const TfToken face;
const TfToken *pface;
const TfToken& g_face() const { return face; }
const TfToken* g_pface() const { return pface; }
Tokens() : face(), pface(&face) {}
};
static Tokens UsdGeomTokens;
@ -30,5 +39,33 @@ void CreateMaterialBindSubset1(const Tokens &elementType = UsdGeomTokens) {}
void CreateMaterialBindSubset2(int num = UsdGeomTokensPtr->pface->val.val) {}
void CreateMaterialBindSubset3(int num = UsdGeomTokensPtr->pface->ptr->val) {}
void CreateMaterialBindSubset4(int num = UsdGeomTokensPtr->face.val.val) {}
//void CreateMaterialBindSubset5(int num = UsdGeomTokens.face.val.val) {}
void CreateMaterialBindSubset5(int num = UsdGeomTokens.face.val.val) {}
void CreateMaterialBindSubset6(int num = UsdGeomTokensPtr->pface->val.g_val()) {}
void CreateMaterialBindSubset7(int num = UsdGeomTokensPtr->pface->ptr->g_val()) {}
void CreateMaterialBindSubset8(int num = UsdGeomTokensPtr->face.val.g_val()) {}
void CreateMaterialBindSubset9(int num = UsdGeomTokens.face.val.g_val()) {}
void CreateMaterialBindSubseta(int num = UsdGeomTokensPtr->pface->g_val().val) {}
void CreateMaterialBindSubsetb(int num = UsdGeomTokensPtr->pface->g_ptr()->val) {}
void CreateMaterialBindSubsetc(int num = UsdGeomTokensPtr->face.g_val().val) {}
void CreateMaterialBindSubsetd(int num = UsdGeomTokens.face.g_val().val) {}
void CreateMaterialBindSubsete(int num = UsdGeomTokensPtr->pface->g_val().g_val()) {}
void CreateMaterialBindSubsetf(int num = UsdGeomTokensPtr->pface->g_ptr()->g_val()) {}
void CreateMaterialBindSubsetg(int num = UsdGeomTokensPtr->face.g_val().g_val()) {}
void CreateMaterialBindSubseth(int num = UsdGeomTokens.face.g_val().g_val()) {}
void CreateMaterialBindSubseti(int num = UsdGeomTokensPtr->g_pface()->val.val) {}
void CreateMaterialBindSubsetj(int num = UsdGeomTokensPtr->g_pface()->ptr->val) {}
void CreateMaterialBindSubsetk(int num = UsdGeomTokensPtr->g_face().val.val) {}
void CreateMaterialBindSubsetl(int num = UsdGeomTokens.g_face().val.val) {}
void CreateMaterialBindSubsetm(int num = UsdGeomTokensPtr->g_pface()->val.g_val()) {}
void CreateMaterialBindSubsetn(int num = UsdGeomTokensPtr->g_pface()->ptr->g_val()) {}
void CreateMaterialBindSubseto(int num = UsdGeomTokensPtr->g_face().val.g_val()) {}
void CreateMaterialBindSubsetp(int num = UsdGeomTokens.g_face().val.g_val()) {}
void CreateMaterialBindSubsetq(int num = UsdGeomTokensPtr->g_pface()->g_val().val) {}
void CreateMaterialBindSubsetr(int num = UsdGeomTokensPtr->g_pface()->g_ptr()->val) {}
void CreateMaterialBindSubsets(int num = UsdGeomTokensPtr->g_face().g_val().val) {}
void CreateMaterialBindSubsett(int num = UsdGeomTokens.g_face().g_val().val) {}
void CreateMaterialBindSubsetu(int num = UsdGeomTokensPtr->g_pface()->g_val().g_val()) {}
void CreateMaterialBindSubsetv(int num = UsdGeomTokensPtr->g_pface()->g_ptr()->g_val()) {}
void CreateMaterialBindSubsetw(int num = UsdGeomTokensPtr->g_face().g_val().g_val()) {}
void CreateMaterialBindSubsetx(int num = UsdGeomTokens.g_face().g_val().g_val()) {}
%}

View file

@ -18,6 +18,7 @@
%{
#define TESTCASE_THROW1(T1)
#define TESTCASE_THROW2(T1, T2)
#include <string.h>
%}
%include <std_string.i>
@ -71,7 +72,7 @@
class EnumClass {
public:
enum speed { FAST, SLOW };
// Note: default values should be EnumClass::FAST and SWEET
// Note: default values should be EnumClass::FAST and SWEET
bool blah(speed s = FAST, flavor f = SWEET) { return (s == FAST && f == SWEET); };
};
@ -83,16 +84,16 @@
// casts
const char * casts1(const char *m = (const char *) NULL) {
char *ret = NULL;
if (m) {
char *ret = NULL;
if (m) {
ret = new char[strlen(m)+1];
strcpy(ret, m);
}
return ret;
}
const char * casts2(const char *m = (const char *) "Hello") {
char *ret = NULL;
if (m) {
char *ret = NULL;
if (m) {
ret = new char[strlen(m)+1];
strcpy(ret, m);
}
@ -108,16 +109,16 @@
char chartest6(char c = '\x43') { return c; } // 'C'
// namespaces
namespace AType {
enum AType { NoType };
}
namespace AType {
enum AType { NoType };
}
void dummy(AType::AType aType = AType::NoType) {}
namespace A {
namespace B {
int CONST_NUM = 10;
}
namespace A {
namespace B {
int CONST_NUM = 10;
}
int afunction(int i = B::CONST_NUM) { return i; }
}
}
// references
int reftest1(const int &x = 42) { return x; }
@ -131,7 +132,7 @@
void test(int x = Oak + Fir + Cedar) {}
};
enum Tree::types chops(enum Tree::types type) { return type; }
%}
// Rename a class member
@ -143,7 +144,7 @@
%rename(renamed2arg) Foo::renameme(int x) const;
%rename(renamed1arg) Foo::renameme() const;
%typemap(default) double* null_by_default "$1=0;";
%typemap(default) double* null_by_default "$1=0;"
%inline %{
typedef void* MyHandle;
@ -155,11 +156,11 @@
static int spam;
Foo(){}
Foo(int x, int y = 0, int z = 0){}
void meth(int x, int y = 0, int z = 0){}
// Use a renamed member as a default argument. SWIG has to resolve
// bar to Foo::bar and not Foo::spam. SWIG-1.3.11 got this wrong.
// (Different default parameter wrapping in SWIG-1.3.23 ensures SWIG doesn't have to resolve these symbols).
@ -189,20 +190,20 @@
// tests valuewrapper
%feature("compactdefaultargs") MyClass2::set;
%inline %{
enum MyType { Val1, Val2 };
enum MyType { Val1, Val2 };
class MyClass1
{
public:
class MyClass1
{
public:
MyClass1(MyType myType) {}
};
};
class MyClass2
{
public :
class MyClass2
{
public :
void set(MyClass1 cl1 = Val1) {}
// This could have been written : set(MyClass1 cl1 = MyClass1(Val1))
// But it works in C++ since there is a "conversion" constructor in MyClass1.
// This could have been written : set(MyClass1 cl1 = MyClass1(Val1))
// But it works in C++ since there is a "conversion" constructor in MyClass1.
void set2(MyClass1 cl1 = Val1) {}
};
%}
@ -281,7 +282,7 @@ struct ConstMethods {
};
%}
// const methods
// const methods
// runtime test needed to check that the const method is called
struct ConstMethods {
int coo(double d = 0.0) const;
@ -305,8 +306,8 @@ struct ConstMethods {
return(x+p);
}
typedef struct Pointf {
double x,y;
typedef struct Pointf {
double x,y;
} Pointf;
}
%}

View file

@ -83,7 +83,7 @@ Hash {
and by checking the typemaps.
The typemap code also calls SwigType_remember(), if your typemaps
defined an object type, it will be added into the SwigType table.
its normally a
it's normally a
SWIG_ConvertPtr(....$descriptor...)
when it should have been a $&descriptor or $*descriptor

View file

@ -71,11 +71,12 @@
%}
%typemap(cscode) MyClass %{
// low level implementation check for checking MyOverriddenClass
public void testSwigDerivedClassHasMethod() {
if (SwigDerivedClassHasMethod("nonVirtual", swigMethodTypes3))
throw new global::System.Exception("non-overriding non-virtual method would be when connecting director");
throw new global::System.Exception("SwigDerivedClassHasMethod failed checking a non-overriding non-virtual method (nonVirtual)");
if (SwigDerivedClassHasMethod("nonOverride", swigMethodTypes4))
throw new global::System.Exception("non-overriding virtual method would be when connecting director");
throw new global::System.Exception("SwigDerivedClassHasMethod failed checking a non-overriding method (nonOverride)");
}
%}

View file

@ -8,6 +8,7 @@
%inline %{
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE_AA 8
#define BUFFER_SIZE_BB 5

View file

@ -48,7 +48,7 @@ namespace Swig {
%feature("director:except") {
jthrowable $error = jenv->ExceptionOccurred();
if ($error) {
// Dont clear exception, still be active when return to java execution
// Don't clear exception, still be active when return to java execution
// Essentially ignore exception occurred -- old behavior.
return $null;
}

View file

@ -0,0 +1,71 @@
//%module(ruby_minherit="1") multiple_inheritance
%module(directors="1") director_multiple_inheritance
%feature("director") A;
%feature("director") B;
%feature("director") C;
%feature("director") D;
%inline %{
class A {
public:
virtual ~A() { }
virtual int testA();
};
class B: virtual public A {
public:
virtual ~B() { }
virtual int testB();
};
class C: virtual public A {
public:
virtual ~C() { }
virtual int testC();
};
class D: virtual public A {
public:
virtual ~D() { }
virtual int testD();
};
class E {
public:
virtual ~E() { }
virtual int testE(B*);
};
class F {
public:
virtual ~F() { }
virtual int testF(C*);
};
class T {
public:
virtual ~T() { }
virtual int testT(D*);
};
%}
%{
int A::testA() { return 1; }
int B::testB() { return 2; }
int C::testC() { return 3; }
int D::testD() { return 4; }
int E::testE(B*) { return 5; }
int F::testF(C*) { return 6; }
int T::testT(D*) { return 20; }
%}

View file

@ -14,17 +14,12 @@ struct OverloadDerived1 : OverloadBase {
virtual void nnn(int vvv) {}
#if defined(__SUNPRO_CC)
virtual void nnn() {}
#elif defined(SWIGPHP) // FIXME: Hack to stop director_overload2 failing for PHP8
virtual void nnn() {}
#endif
};
struct OverloadDerived2 : OverloadBase {
#if defined(__SUNPRO_CC)
virtual void nnn(int vvv) {}
#elif defined(SWIGPHP) // FIXME: Hack to stop director_overload2 failing for PHP8
virtual void nnn(int vvv) {}
#endif
virtual void nnn() {}
};
%}

View file

@ -1,14 +1,34 @@
%module(directors="1") director_pass_by_value
%director DirectorPassByValueAbstractBase;
%include "cpp11_move_only_helper.i"
%ignore PassedByValue::operator=;
%ignore PassedByValue::PassedByValue(PassedByValue &&);
%inline %{
class PassedByValue {
int val;
public:
PassedByValue() { val = 0x12345678; }
#include <iostream>
using namespace std;
int trace = false;
struct PassedByValue {
PassedByValue(int v = 0x12345678) { val = v; if (trace) cout << "PassedByValue(0x" << hex << val << ")" << " " << this << endl; Counter::normal_constructor++; }
PassedByValue(const PassedByValue &other) { val = other.val; if (trace) cout << "PassedByValue(const PassedByValue &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
PassedByValue & operator=(const PassedByValue &other) { val = other.val; if (trace) cout << "operator=(const PassedByValue &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
#if __cplusplus >= 201103L
PassedByValue(PassedByValue &&other) noexcept { val = other.val; if (trace) cout << "PassedByValue(PassedByValue &&)" << " " << this << endl; Counter::move_constructor++; }
PassedByValue & operator=(PassedByValue &&other) noexcept { val = other.val; if (trace) cout << "operator=(PassedByValue &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
~PassedByValue() { if (trace) cout << "~PassedByValue()" << " " << this << endl; Counter::destructor++; }
#endif
int getVal() { return val; }
private:
int val;
};
int doSomething(int x) {
int yy[256];
yy[0] =0x9876;
@ -18,6 +38,7 @@ int doSomething(int x) {
class DirectorPassByValueAbstractBase {
public:
virtual void virtualMethod(PassedByValue pbv) = 0;
virtual void virtualConstMethod(const PassedByValue pbv) {}
virtual ~DirectorPassByValueAbstractBase () {}
};
@ -27,4 +48,12 @@ public:
f.virtualMethod(PassedByValue());
}
};
bool has_cplusplus11() {
#if __cplusplus >= 201103L
return true;
#else
return false;
#endif
}
%}

View file

@ -18,9 +18,9 @@
virtual std::string pong() { return "Foo::pong();" + ping(); }
virtual std::string getA() { return this->a_; }
virtual void setA(std::string a) { this->a_ = a; }
virtual void setAByRef(const std::string &a) { this->a_ = a; }
static Foo* get_self(Foo *slf) {return slf;}
};
%}
@ -37,9 +37,9 @@
virtual std::string pong();
virtual std::string getA();
virtual void setA(std::string a);
virtual void setAByRef(const std::string &a);
static Foo* get_self(Foo *slf);
};
%{

View file

@ -0,0 +1,42 @@
%module(directors="1") director_simple
%feature("director") IntBase;
%feature("director") BoolBase;
%inline %{
class IntBase {
public:
virtual ~IntBase() {}
IntBase(int i = 3) { (void)i; }
virtual int apply(int x) const { return x * 2; }
};
class IntDerived : public IntBase {
public:
virtual int apply(int x) const { return x * 3; }
};
int apply(const IntBase& b, int x)
{
return b.apply(x);
}
class BoolBase {
public:
virtual ~BoolBase() {}
BoolBase() {}
virtual bool apply(bool a, bool b) const = 0;
};
class BoolDerived : public BoolBase {
public:
virtual bool apply(bool a, bool b) const { return a != b; }
};
bool apply(const BoolBase& base, bool a, bool b)
{
return base.apply(a, b);
}
%}

View file

@ -20,7 +20,6 @@
#ifdef _WIN32
#include <windows.h>
#include <process.h>
#include <stdio.h>
#else
#include <pthread.h>
#include <errno.h>
@ -30,6 +29,7 @@
#endif
#include <assert.h>
#include <stdio.h>
#include "swig_examples_lock.h"
class Foo;
@ -42,15 +42,15 @@ extern "C" {
static pthread_t thread;
#endif
static int thread_terminate = 0;
static int swig_thread_terminate = 0;
static SwigExamples::CriticalSection critical_section;
int get_thread_terminate() {
SwigExamples::Lock lock(critical_section);
return thread_terminate;
return swig_thread_terminate;
}
void set_thread_terminate(int value) {
SwigExamples::Lock lock(critical_section);
thread_terminate = value;
swig_thread_terminate = value;
}
}
%}

View file

@ -0,0 +1,55 @@
%module(directors="1") director_using_member_scopes
// Similar to using_member_scopes but for directors
#if !defined(SWIGGO) // TODO: fix Go crash
%feature("director");
// Python,Java,C# no diffs in generated code when adding in nodirector. Go not happy even without %nodirector.
// Fully qualifying parameter types in a method declared after the using declaration caused
// a method being incorrectly added by the using declaration even though the declaration already existed
// Github issue #1441 - segfault in Go and C#
%inline %{
namespace OgreBites
{
struct NativeWindowType {};
class ApplicationContextBase {
public:
virtual ~ApplicationContextBase() {}
virtual int setWindowGrab(NativeWindowType* win, bool grab = true) { return 0; }
int setWindowGrab(bool grab = true) { return 5; }
static int call_setWindowGrab(ApplicationContextBase* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
};
class ApplicationContextSDL : public ApplicationContextBase {
public:
using ApplicationContextBase::setWindowGrab;
int setWindowGrab(NativeWindowType* win, bool grab = true) { return 10; } // This should not be added again as it exists in base class
static int call_setWindowGrab(ApplicationContextSDL* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
};
class ACB {
public:
virtual ~ACB() {}
virtual int setWindowGrab(NativeWindowType* win, bool grab = true) { return 0; }
virtual int setWindowGrab(const char *s, int val) { return 1; } // Additional method compared to ApplicationContextBase
int setWindowGrab(bool grab = true) { return 5; }
static int call_setWindowGrab(ACB* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
static int call_setWindowGrab(ACB* ptr, const char *s, int val) { return ptr->setWindowGrab(s, val); }
};
class ACSDL : public ACB {
public:
using ACB::setWindowGrab; // This introduces two methods, not one method like ApplicationContextSDL
int setWindowGrab(NativeWindowType* win, bool grab = true) { return 10; } // This should not be added again as it exists in base class
static int call_setWindowGrab(ACSDL* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
static int call_setWindowGrab(ACSDL* ptr, const char *s, int val) { return ptr->setWindowGrab(s, val); }
};
}
%}
#endif

View file

@ -39,10 +39,11 @@ struct A
std::vector<std::wstring> m_strings;
virtual const wchar_t * wchar_out() { return L"ciao"; }
virtual void process_text(const wchar_t *text)
{
}
virtual void process_text(const wchar_t *text) {}
virtual void process_wstring_text(std::wstring text) {}
virtual void process_wstring_ref_text(const std::wstring& text) {}
virtual std::wstring multiple_params_val(const std::wstring& p1, const std::wstring& p2, std::wstring p3, std::wstring p4) const
{ return get_first(); }
@ -51,6 +52,8 @@ struct A
{ return get_first(); }
void call_process_func() { process_text(L"hello"); }
void call_process_wstring_func() { process_wstring_text(L"hello"); }
void call_process_wstring_ref_func() { process_wstring_ref_text(L"hello"); }
};
%}

View file

@ -0,0 +1,75 @@
%module doxygen_autodoc_docstring
%feature("autodoc", 1);
%feature("docstring") ClassWithDocString "Class doc from docstring";
%feature("docstring") functionWithDocString "Function doc from docstring";
%feature("docstring") ClassWithDocStringAndDoxygenComment "Class doc from docstring overriding doxycomment";
%feature("docstring") functionWithDocStringAndDoxygenComment "Function doc from docstring overriding doxycomment";
%inline %{
class ClassWithoutDoxygenComment {};
void functionWithoutDoxygenComment(int number) {}
/**
* Class doxygen comment
*/
class ClassWithDoxygenComment {};
/**
* Function doxygen comment
*/
void functionWithDoxygenComment(int number) {}
class ClassWithDocString {};
void functionWithDocString(int number) {}
/**
* Class doxygen comment
*/
class ClassWithDocStringAndDoxygenComment {};
/**
* Function doxygen comment
*/
void functionWithDocStringAndDoxygenComment(int number) {}
%}
%feature("autodoc", ""); // clear autodoc
%feature("docstring") ClassWithDocStringAndDoxygenCommentNoAutodoc "Class doc from docstring overriding doxycomment (no autodoc)";
%feature("docstring") functionWithDocStringAndDoxygenCommentNoAutodoc "Function doc from docstring overriding doxycomment (no autodoc)";
%inline %{
/**
* Class doxygen comment
*/
class ClassWithDocStringAndDoxygenCommentNoAutodoc {};
/**
* Function doxygen comment
*/
void functionWithDocStringAndDoxygenCommentNoAutodoc(int number) {}
/**
* Class doxygen comment 2
*/
class ClassWithDoxygenComment2 {};
/**
* Function doxygen comment 2
*/
void functionWithDoxygenComment2(int number) {}
%}
%inline %{
#ifdef SWIGPYTHON_BUILTIN
bool is_python_builtin() { return true; }
#else
bool is_python_builtin() { return false; }
#endif
%}

View file

@ -133,6 +133,15 @@ struct SomeAnotherStruct
}
};
struct Foo1750
{
/// @name Group name
/// @{
int a;
/// @}
int b;
};
#ifdef SWIGPYTHON_BUILTIN
bool is_python_builtin() { return true; }
#else

View file

@ -89,8 +89,6 @@ struct SpeedClass {
const colour myColour2;
speedtd1 mySpeedtd1;
SpeedClass() : myColour2(red), mySpeedtd1(slow) { }
private:
SpeedClass& operator=(const SpeedClass&);
};
int speedTest0(int s) { return s; }

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