Discussion:
[Swig-devel] C++11 using statements / type alias
Lior Goldberg
2016-06-17 15:39:54 UTC
Permalink
Hi all,

I noticed that C++11 using statements (type alias) such as:
* using A = int;
* template <typename T> using ptr_t = T*;
are not currently supported by SWIG.

Attached is a patch that adds support for these cases, by treating them
as the equivalent typedef statements.

Note: an alias template needs to be declared in the swig file as follows:
%template() ptr_t<int>;

What do you think?

(I will be happy to revise the code according to your comments as needed)

Thanks,
Lior
Lior Goldberg
2016-06-17 16:00:49 UTC
Permalink
For some reason the previous message was sent as HTML. Here it is
again, hopefully in plain text.
Post by Lior Goldberg
Hi all,
* using A = int;
* template <typename T> using ptr_t = T*;
are not currently supported by SWIG.
Attached is a patch that adds support for these cases, by treating them
as the equivalent typedef statements.
%template() ptr_t<int>;
What do you think?
(I will be happy to revise the code according to your comments as needed)
Thanks,
Lior
William S Fulton
2016-06-19 14:31:11 UTC
Permalink
Post by Lior Goldberg
Hi all,
* using A = int;
* template <typename T> using ptr_t = T*;
are not currently supported by SWIG.
Attached is a patch that adds support for these cases, by treating them
as the equivalent typedef statements.
%template() ptr_t<int>;
What do you think?
(I will be happy to revise the code according to your comments as needed)
That's a nice approach for finishing off an important C++11 feature,
thanks! Let's split the patch into two parts.

1) Type alias
This is just a typedef in C++11 syntax. Patch looks okay. I think we
should add an attribute like SetFlag($$, "typealias") into the typedef
node indicating that it originates from a using statement and is a
type alias rather than a C style typedef. This info may not be used in
the code, but is useful info when debugging and for the -xml option.

2) Alias templates
While your patches seem to work, I'm undecided if this is all that is
required. The requirement to use the empty template instantiation,
%template(), seems an unnecessary burden to place on users. Normally a
%template with a name is required to instantiate templates so that the
template has a name in the target language, but for alias templates,
this is not necessary. Hence I think that ideally, SWIG should not
require a user to use %template() to support alias templates. There
seem to be two cases:

a) alias template resolves to a non-template type, eg:
template<typename T> using ptr_t = T*;
ptr_t<int> pi; // pi is a plain primitive type int

b) alias template resolves to a template type, eg:
template<typename T> using Vector = std::vector<T>;
Vector<int> vi;

SWIG usage would then need to be:

%include <std_vector.i>
template<typename T> using Vector = std::vector<T>;
%template() Vector<int>; // This empty template instantiation seems
really redundant!
%template(VectorInt) std::vector<int>;
Vector<int> vi;

This is actually very similar to something that is currently a
nuisance, but not a very prevalent problem atm, eg sometimes the
entire std::vector is not required in the wrappers, but the type
deduction of the typedefs in the template are, such as:

%template() std::vector<bool>; // this is needed (empty %template()
or a name provided to %template) otherwise SWIG doesn't recognise the
type below is actually a bool
std::vector<bool>::value_type mybool;

As template aliases are becoming very common, I think SWIG ought to
improve this sooner rather than later by having some sort of automatic
empty template instantiation if a user has not provided a name to
%template. I suspect this will not be easy to solve properly though
but would be a great enhancement.

Taking this forward, can you put together these improvements into
github pull requests? Let's have one request for each of these two
improvements. They'll need suitable changes in the CPlusPlus11.html
documentation including some examples and plenty of test cases added
to the test-suite. There are extensive ways that type aliases can be
declared, eg in different scopes and different types. I suggest the
cpp11_type_aliasing.i and cpp11_template_typedefs.i testcases are
expanded and runtime tests added. Most of the C++11 runtime tests are
in Java or Python, so runtime tests in both or one of these languages
is preferred. Lastly, please try and use the correct whitespace in
your patches.

William
Lior Goldberg
2016-06-23 18:12:45 UTC
Permalink
On Sun, Jun 19, 2016 at 5:31 PM William S Fulton
Post by William S Fulton
Post by Lior Goldberg
Hi all,
* using A = int;
* template <typename T> using ptr_t = T*;
are not currently supported by SWIG.
Attached is a patch that adds support for these cases, by treating them
as the equivalent typedef statements.
%template() ptr_t<int>;
What do you think?
(I will be happy to revise the code according to your comments as needed)
That's a nice approach for finishing off an important C++11 feature,
thanks! Let's split the patch into two parts.
1) Type alias
This is just a typedef in C++11 syntax. Patch looks okay. I think we
should add an attribute like SetFlag($$, "typealias") into the typedef
node indicating that it originates from a using statement and is a
type alias rather than a C style typedef. This info may not be used in
the code, but is useful info when debugging and for the -xml option.
2) Alias templates
While your patches seem to work, I'm undecided if this is all that is
required. The requirement to use the empty template instantiation,
%template(), seems an unnecessary burden to place on users. Normally a
%template with a name is required to instantiate templates so that the
template has a name in the target language, but for alias templates,
this is not necessary. Hence I think that ideally, SWIG should not
require a user to use %template() to support alias templates. There
template<typename T> using ptr_t = T*;
ptr_t<int> pi; // pi is a plain primitive type int
template<typename T> using Vector = std::vector<T>;
Vector<int> vi;
%include <std_vector.i>
template<typename T> using Vector = std::vector<T>;
%template() Vector<int>; // This empty template instantiation seems
really redundant!
%template(VectorInt) std::vector<int>;
Vector<int> vi;
This is actually very similar to something that is currently a
nuisance, but not a very prevalent problem atm, eg sometimes the
entire std::vector is not required in the wrappers, but the type
%template() std::vector<bool>; // this is needed (empty %template()
or a name provided to %template) otherwise SWIG doesn't recognise the
type below is actually a bool
std::vector<bool>::value_type mybool;
As template aliases are becoming very common, I think SWIG ought to
improve this sooner rather than later by having some sort of automatic
empty template instantiation if a user has not provided a name to
%template. I suspect this will not be easy to solve properly though
but would be a great enhancement.
Taking this forward, can you put together these improvements into
github pull requests? Let's have one request for each of these two
improvements. They'll need suitable changes in the CPlusPlus11.html
documentation including some examples and plenty of test cases added
to the test-suite. There are extensive ways that type aliases can be
declared, eg in different scopes and different types. I suggest the
cpp11_type_aliasing.i and cpp11_template_typedefs.i testcases are
expanded and runtime tests added. Most of the C++11 runtime tests are
in Java or Python, so runtime tests in both or one of these languages
is preferred. Lastly, please try and use the correct whitespace in
your patches.
William
Hi,

I created a pull request for the first part (type alias).
Regarding alias templates, I agree that a %template() statement is
completely redundant. But as you mentioned it is part of a bigger
feature, and therefore should have its own pull request, in my
opinion. I will try to look into it in the coming days and meanwhile
work on the alias templates pull request (without this feature).

Lior
William S Fulton
2016-06-25 15:16:10 UTC
Permalink
Post by Lior Goldberg
On Sun, Jun 19, 2016 at 5:31 PM William S Fulton
Post by William S Fulton
Post by Lior Goldberg
Hi all,
* using A = int;
* template <typename T> using ptr_t = T*;
are not currently supported by SWIG.
Attached is a patch that adds support for these cases, by treating them
as the equivalent typedef statements.
%template() ptr_t<int>;
What do you think?
(I will be happy to revise the code according to your comments as needed)
That's a nice approach for finishing off an important C++11 feature,
thanks! Let's split the patch into two parts.
1) Type alias
This is just a typedef in C++11 syntax. Patch looks okay. I think we
should add an attribute like SetFlag($$, "typealias") into the typedef
node indicating that it originates from a using statement and is a
type alias rather than a C style typedef. This info may not be used in
the code, but is useful info when debugging and for the -xml option.
2) Alias templates
While your patches seem to work, I'm undecided if this is all that is
required. The requirement to use the empty template instantiation,
%template(), seems an unnecessary burden to place on users. Normally a
%template with a name is required to instantiate templates so that the
template has a name in the target language, but for alias templates,
this is not necessary. Hence I think that ideally, SWIG should not
require a user to use %template() to support alias templates. There
template<typename T> using ptr_t = T*;
ptr_t<int> pi; // pi is a plain primitive type int
template<typename T> using Vector = std::vector<T>;
Vector<int> vi;
%include <std_vector.i>
template<typename T> using Vector = std::vector<T>;
%template() Vector<int>; // This empty template instantiation seems
really redundant!
%template(VectorInt) std::vector<int>;
Vector<int> vi;
This is actually very similar to something that is currently a
nuisance, but not a very prevalent problem atm, eg sometimes the
entire std::vector is not required in the wrappers, but the type
%template() std::vector<bool>; // this is needed (empty %template()
or a name provided to %template) otherwise SWIG doesn't recognise the
type below is actually a bool
std::vector<bool>::value_type mybool;
As template aliases are becoming very common, I think SWIG ought to
improve this sooner rather than later by having some sort of automatic
empty template instantiation if a user has not provided a name to
%template. I suspect this will not be easy to solve properly though
but would be a great enhancement.
Taking this forward, can you put together these improvements into
github pull requests? Let's have one request for each of these two
improvements. They'll need suitable changes in the CPlusPlus11.html
documentation including some examples and plenty of test cases added
to the test-suite. There are extensive ways that type aliases can be
declared, eg in different scopes and different types. I suggest the
cpp11_type_aliasing.i and cpp11_template_typedefs.i testcases are
expanded and runtime tests added. Most of the C++11 runtime tests are
in Java or Python, so runtime tests in both or one of these languages
is preferred. Lastly, please try and use the correct whitespace in
your patches.
William
Hi,
I created a pull request for the first part (type alias).
Regarding alias templates, I agree that a %template() statement is
completely redundant. But as you mentioned it is part of a bigger
feature, and therefore should have its own pull request, in my
opinion. I will try to look into it in the coming days and meanwhile
work on the alias templates pull request (without this feature).
Lior, thank you very much. I've now merged in the type alias pull
request. I'm sure I speak on behalf of many other C++11 users in
saying I look forward to the 2nd pull request.

William
Lior Goldberg
2016-07-06 19:02:06 UTC
Permalink
On Sat, Jun 25, 2016 at 6:16 PM, William S Fulton
Post by William S Fulton
Post by Lior Goldberg
On Sun, Jun 19, 2016 at 5:31 PM William S Fulton
Post by William S Fulton
Post by Lior Goldberg
Hi all,
* using A = int;
* template <typename T> using ptr_t = T*;
are not currently supported by SWIG.
Attached is a patch that adds support for these cases, by treating them
as the equivalent typedef statements.
%template() ptr_t<int>;
What do you think?
(I will be happy to revise the code according to your comments as needed)
That's a nice approach for finishing off an important C++11 feature,
thanks! Let's split the patch into two parts.
1) Type alias
This is just a typedef in C++11 syntax. Patch looks okay. I think we
should add an attribute like SetFlag($$, "typealias") into the typedef
node indicating that it originates from a using statement and is a
type alias rather than a C style typedef. This info may not be used in
the code, but is useful info when debugging and for the -xml option.
2) Alias templates
While your patches seem to work, I'm undecided if this is all that is
required. The requirement to use the empty template instantiation,
%template(), seems an unnecessary burden to place on users. Normally a
%template with a name is required to instantiate templates so that the
template has a name in the target language, but for alias templates,
this is not necessary. Hence I think that ideally, SWIG should not
require a user to use %template() to support alias templates. There
template<typename T> using ptr_t = T*;
ptr_t<int> pi; // pi is a plain primitive type int
template<typename T> using Vector = std::vector<T>;
Vector<int> vi;
%include <std_vector.i>
template<typename T> using Vector = std::vector<T>;
%template() Vector<int>; // This empty template instantiation seems
really redundant!
%template(VectorInt) std::vector<int>;
Vector<int> vi;
This is actually very similar to something that is currently a
nuisance, but not a very prevalent problem atm, eg sometimes the
entire std::vector is not required in the wrappers, but the type
%template() std::vector<bool>; // this is needed (empty %template()
or a name provided to %template) otherwise SWIG doesn't recognise the
type below is actually a bool
std::vector<bool>::value_type mybool;
As template aliases are becoming very common, I think SWIG ought to
improve this sooner rather than later by having some sort of automatic
empty template instantiation if a user has not provided a name to
%template. I suspect this will not be easy to solve properly though
but would be a great enhancement.
Taking this forward, can you put together these improvements into
github pull requests? Let's have one request for each of these two
improvements. They'll need suitable changes in the CPlusPlus11.html
documentation including some examples and plenty of test cases added
to the test-suite. There are extensive ways that type aliases can be
declared, eg in different scopes and different types. I suggest the
cpp11_type_aliasing.i and cpp11_template_typedefs.i testcases are
expanded and runtime tests added. Most of the C++11 runtime tests are
in Java or Python, so runtime tests in both or one of these languages
is preferred. Lastly, please try and use the correct whitespace in
your patches.
William
Hi,
I created a pull request for the first part (type alias).
Regarding alias templates, I agree that a %template() statement is
completely redundant. But as you mentioned it is part of a bigger
feature, and therefore should have its own pull request, in my
opinion. I will try to look into it in the coming days and meanwhile
work on the alias templates pull request (without this feature).
Lior, thank you very much. I've now merged in the type alias pull
request. I'm sure I speak on behalf of many other C++11 users in
saying I look forward to the 2nd pull request.
William
I created the second pull request. Currently the code requires the
redundant %template() directive, but I hope to remove this requirement
in another pull request. This seems to be simpler than the larger goal
- to be able to understand std::vector<int>::value_type without
%template(Vec) std::vector<int>.

One thing I was not sure about was the call to
SwigType_typedef_class() I added in typepass.cxx. This function adds a
meta tag "class" to the type name. Is this OK? Or should we refactor
this function (SwigType_typedef_class) somehow?

Thanks,
Lior

Loading...