Add unignore for rvalue ref-qualifiers

Use std::move on this pointer as the default approach to supporting
rvalue ref-qualifiers if a user really wants to wrap.

std::move requires <memory> headers so add swigfragments.swg for all
languages to use common fragments. Just header file fragments for now.
This commit is contained in:
William S Fulton 2017-08-25 19:08:09 +01:00
parent 1cf599bccb
commit 8a40327aa8
10 changed files with 149 additions and 74 deletions

View File

@ -562,6 +562,7 @@ CPP11_TEST_CASES += \
cpp11_null_pointer_constant \
cpp11_raw_string_literals \
cpp11_ref_qualifiers \
cpp11_ref_qualifiers_rvalue_unignore \
cpp11_result_of \
cpp11_rvalue_reference \
cpp11_rvalue_reference2 \

View File

@ -0,0 +1,15 @@
%module cpp11_ref_qualifiers_rvalue_unignore
// This is a minimal test that does not include any C++ headers to make sure the required
// <memory> header is generated from a fragment for the generated std::move call
// m1 and m2 are ignored by default, unignore them
%feature("ignore", "0") RefQualifier::m1() &&;
%feature("ignore", "0") RefQualifier::m2() const &&;
%inline %{
struct RefQualifier {
void m1() && {}
void m2() const && {}
};
%}

View File

@ -18,5 +18,11 @@ public:
void h_ignored() &&;
void i_ignored() &&;
void j_ignored() const &&;
void i_ignored() &&;
};
%feature("ignore", "0") Unignore::k_unignored() const &&;
struct Unignore {
void k_unignored() const &&;
};

View File

@ -0,0 +1,20 @@
import cpp11_ref_qualifiers_rvalue_unignore.*;
public class cpp11_ref_qualifiers_rvalue_unignore_runme {
static {
try {
System.loadLibrary("cpp11_ref_qualifiers_rvalue_unignore");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
new RefQualifier().m1();
new RefQualifier().m2();
}
}

View File

@ -0,0 +1,4 @@
import cpp11_ref_qualifiers_rvalue_unignore
cpp11_ref_qualifiers_rvalue_unignore.RefQualifier().m1()
cpp11_ref_qualifiers_rvalue_unignore.RefQualifier().m2()

View File

@ -309,11 +309,13 @@ static int NAME(TYPE x) {
%define %$classname %$ismember,"match$parentNode$name" %enddef
%define %$isnested "match$nested"="1" %enddef
/* -----------------------------------------------------------------------------
* Include all the warnings labels and macros
* Common includes for warning labels, macros, fragments etc
* ----------------------------------------------------------------------------- */
%include <swigwarnings.swg>
%include <swigfragments.swg>
/* -----------------------------------------------------------------------------
* Overloading support

86
Lib/swigfragments.swg Normal file
View File

@ -0,0 +1,86 @@
/* -----------------------------------------------------------------------------
* swigfragments.swg
*
* Common fragments
* ----------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
* Fragments for C header files
* ----------------------------------------------------------------------------- */
%fragment("<float.h>", "header") %{
#include <float.h>
%}
/* Default compiler options for gcc allow long_long but not LLONG_MAX.
* Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */
%fragment("<limits.h>", "header") %{
#include <limits.h>
#if !defined(SWIG_NO_LLONG_MAX)
# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
# define LLONG_MAX __LONG_LONG_MAX__
# define LLONG_MIN (-LLONG_MAX - 1LL)
# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
# endif
#endif
%}
%fragment("<math.h>", "header") %{
#include <math.h>
%}
%fragment("<stddef.h>", "header") %{
#include <stddef.h>
%}
%fragment("<stdio.h>", "header") %{
#include <stdio.h>
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
# ifndef snprintf
# define snprintf _snprintf
# endif
#endif
%}
%fragment("<stdlib.h>", "header") %{
#include <stdlib.h>
#ifdef _MSC_VER
# ifndef strtoull
# define strtoull _strtoui64
# endif
# ifndef strtoll
# define strtoll _strtoi64
# endif
#endif
%}
%fragment("<wchar.h>", "header") %{
#include <wchar.h>
#include <limits.h>
#ifndef WCHAR_MIN
# define WCHAR_MIN 0
#endif
#ifndef WCHAR_MAX
# define WCHAR_MAX 65535
#endif
%}
/* -----------------------------------------------------------------------------
* Fragments for C++ header files
* ----------------------------------------------------------------------------- */
%fragment("<algorithm>", "header") %{
#include <algorithm>
%}
%fragment("<stdexcept>", "header") %{
#include <stdexcept>
%}
%fragment("<string>", "header") %{
#include <string>
%}
%fragment("<memory>", "header") %{
#include <memory>
%}

View File

@ -96,75 +96,6 @@
* common fragments
* ------------------------------------------------------------ */
/* Default compiler options for gcc allow long_long but not LLONG_MAX.
* Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */
%fragment("<limits.h>","header") %{
#include <limits.h>
#if !defined(SWIG_NO_LLONG_MAX)
# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
# define LLONG_MAX __LONG_LONG_MAX__
# define LLONG_MIN (-LLONG_MAX - 1LL)
# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
# endif
#endif
%}
%fragment("<math.h>","header") %{
#include <math.h>
%}
%fragment("<wchar.h>","header") %{
#include <wchar.h>
#include <limits.h>
#ifndef WCHAR_MIN
# define WCHAR_MIN 0
#endif
#ifndef WCHAR_MAX
# define WCHAR_MAX 65535
#endif
%}
%fragment("<float.h>","header") %{
#include <float.h>
%}
%fragment("<stdio.h>","header") %{
#include <stdio.h>
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
# ifndef snprintf
# define snprintf _snprintf
# endif
#endif
%}
%fragment("<stdlib.h>","header") %{
#include <stdlib.h>
#ifdef _MSC_VER
# ifndef strtoull
# define strtoull _strtoui64
# endif
# ifndef strtoll
# define strtoll _strtoi64
# endif
#endif
%}
%fragment("<stddef.h>", "header") %{
#include <stddef.h>
%}
%fragment("<string>", "header") %{
#include <string>
%}
%fragment("<stdexcept>", "header") %{
#include <stdexcept>
%}
%fragment("<algorithm>", "header") %{
#include <algorithm>
%}
%fragment("SWIG_isfinite","header",fragment="<math.h>,<float.h>") %{
/* Getting isfinite working pre C99 across multiple platforms is non-trivial. Users can provide SWIG_isfinite on older platforms. */
#ifndef SWIG_isfinite

View File

@ -485,9 +485,10 @@ static void add_symbols(Node *n) {
SetFlag(n,"deleted");
SetFlag(n,"feature:ignore");
}
{
String *refqualifier = Getattr(n, "refqualifier");
if (SwigType_isrvalue_reference(refqualifier) && Strcmp(symname, "$ignore") != 0) {
if (SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) {
/* Ignore rvalue ref-qualifiers by default
* Use Getattr instead of GetFlag to handle explicit ignore and explicit not ignore */
if (!(Getattr(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0)) {
SWIG_WARN_NODE_BEGIN(n);
Swig_warning(WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED, Getfile(n), Getline(n),
"Method with rvalue ref-qualifier %s ignored.\n", Swig_name_decl(n));

View File

@ -1024,6 +1024,15 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas
}
}
if (!self && SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) {
String *memory_header = NewString("<memory>");
Setfile(memory_header, Getfile(n));
Setline(memory_header, Getline(n));
Swig_fragment_emit(memory_header);
self = NewString("std::move(*this).");
Delete(memory_header);
}
call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type);
cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call);