Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
dd8e0cbf
Commit
dd8e0cbf
authored
Feb 21, 2016
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a workaround for variables of default template parameter types.
parent
767fce81
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
50 additions
and
32 deletions
+50
-32
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+13
-10
docs/src/userguide/wrapping_CPlusPlus.rst
docs/src/userguide/wrapping_CPlusPlus.rst
+16
-11
tests/run/cpp_templates.pyx
tests/run/cpp_templates.pyx
+15
-10
tests/run/cpp_templates_helper.h
tests/run/cpp_templates_helper.h
+6
-1
No files found.
Cython/Compiler/PyrexTypes.py
View file @
dd8e0cbf
...
...
@@ -16,7 +16,7 @@ from .Code import UtilityCode, LazyUtilityCode, TempitaUtilityCode
from
.
import
StringEncoding
from
.
import
Naming
from
.Errors
import
error
from
.Errors
import
error
,
warning
class
BaseType
(
object
):
...
...
@@ -3555,12 +3555,20 @@ class CppClassType(CType):
error
(
pos
,
"'%s' type is not a template"
%
self
)
return
error_type
if
len
(
self
.
templates
)
-
self
.
num_optional_templates
<=
len
(
template_values
)
<
len
(
self
.
templates
):
num_defaults
=
len
(
self
.
templates
)
-
len
(
template_values
)
partial_specialization
=
self
.
declaration_code
(
''
,
template_params
=
template_values
)
# Most of the time we don't need to declare anything typed to these
# default template arguments, but when we do there's no way in C++
# to reference this directly. However, it is common convention to
# provide a typedef in the template class that resolves to each
# template type. For now, allow the user to specify this name as
# the template parameter.
# TODO: Allow typedefs in cpp classes and search for it in this
# classes scope as a concrete name we could use.
template_values
=
template_values
+
[
TemplatePlaceholderType
(
"%s %s::%s"
%
(
TemplatePlaceholderType
.
UNDECLARABLE_DEFAULT
,
partial_specialization
,
param
.
name
),
True
)
for
param
in
self
.
templates
[
-
self
.
num_optional_templates
:]]
TemplatePlaceholderType
(
"%s::%s"
%
(
partial_specialization
,
param
.
name
),
True
)
for
param
in
self
.
templates
[
-
num_defaults
:]]
if
len
(
self
.
templates
)
!=
len
(
template_values
):
error
(
pos
,
"%s templated type receives %d arguments, got %d"
%
(
self
.
name
,
len
(
self
.
templates
),
len
(
template_values
)))
...
...
@@ -3684,17 +3692,12 @@ class CppClassType(CType):
class
TemplatePlaceholderType
(
CType
):
UNDECLARABLE_DEFAULT
=
"undeclarable default "
def
__init__
(
self
,
name
,
optional
=
False
):
self
.
name
=
name
self
.
optional
=
optional
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
if
self
.
name
.
startswith
(
self
.
UNDECLARABLE_DEFAULT
)
and
not
for_display
:
error
(
None
,
"Can't declare variable of type '%s'"
%
self
.
name
[
len
(
self
.
UNDECLARABLE_DEFAULT
)
+
1
:])
if
entity_code
:
return
self
.
name
+
" "
+
entity_code
else
:
...
...
docs/src/userguide/wrapping_CPlusPlus.rst
View file @
dd8e0cbf
...
...
@@ -409,8 +409,15 @@ Cython uses a bracket syntax for templating. A simple example for wrapping C++ v
del v
Multiple template parameters can be defined as a list, such as [T, U, V]
or [int, bool, char]. Template functions are defined similarly, with
Multiple template parameters can be defined as a list, such as ``[T, U, V]``
or ``[int, bool, char]``. Optional template parameters can be indicated
by writing ``[T, U, V=*]``. In the event that Cython needs to explicitly
reference a default template value for an incomplete template instantiation,
it will write ``MyClass<T, U>::V``, so if the class provides a typedef
for its template parameters it is preferable to use that name here.
Template functions are defined similarly to class templates, with
the template parameter list following the function name::
cdef extern from "<algorithm>" namespace "std":
...
...
@@ -614,5 +621,3 @@ C++ left-values
C++ allows functions returning a reference to be left-values. This is currently
not supported in Cython. ``cython.operator.dereference(foo)`` is also not
considered a left-value.
tests/run/cpp_templates.pyx
View file @
dd8e0cbf
...
...
@@ -3,14 +3,17 @@
from
cython.operator
import
dereference
as
deref
cdef
extern
from
"cpp_templates_helper.h"
:
cdef
cppclass
Wrap
[
T
,
S
=*
]:
cdef
cppclass
Wrap
[
T
,
AltType
=*
,
UndeclarableAltType
=*
]:
Wrap
(
T
)
void
set
(
T
)
T
get
()
bint
operator
==
(
Wrap
[
T
])
S
get_alt_type
()
void
set_alt_type
(
S
)
AltType
get_alt_type
()
void
set_alt_type
(
AltType
)
UndeclarableAltType
create
()
bint
accept
(
UndeclarableAltType
)
cdef
cppclass
Pair
[
T1
,
T2
]:
Pair
(
T1
,
T2
)
...
...
@@ -68,15 +71,17 @@ def test_default_template_arguments(double x):
"""
try
:
a
=
new
Wrap
[
double
](
x
)
b
=
new
Wrap
[
double
,
int
](
x
)
b
=
new
Wrap
[
double
,
int
,
long
](
x
)
ax
=
a
.
get_alt_type
()
a
.
set_alt_type
(
ax
)
assert
a
.
accept
(
a
.
create
())
# never declared
# ax = a.get_alt_type()
# a.set_alt_type(ax)
a
.
set_alt_type
(
a
.
get_alt_type
())
bx
=
b
.
get_alt_type
()
b
.
set_alt_type
(
bx
)
# bx = b.get_alt_type()
# b.set_alt_type(bx)
b
.
set_alt_type
(
b
.
get_alt_type
())
bc
=
b
.
create
()
# declaration here is fine
assert
b
.
accept
(
bc
)
return
a
.
get
(),
b
.
get
()
finally
:
...
...
tests/run/cpp_templates_helper.h
View file @
dd8e0cbf
template
<
typename
T
,
typename
S
=
T
>
template
<
typename
T
,
typename
S
=
T
,
typename
U
=
T
>
class
Wrap
{
T
value
;
public:
typedef
S
AltType
;
Wrap
(
T
v
)
:
value
(
v
)
{
}
void
set
(
T
v
)
{
value
=
v
;
}
T
get
(
void
)
{
return
value
;
}
...
...
@@ -9,6 +11,9 @@ public:
S
get_alt_type
(
void
)
{
return
(
S
)
value
;
}
void
set_alt_type
(
S
v
)
{
value
=
(
T
)
v
;
}
U
create
(
void
)
{
return
(
U
)
value
;
}
bool
accept
(
U
v
)
{
return
v
==
(
U
)
value
;
}
};
template
<
class
T1
,
class
T2
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment