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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
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
Hide 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
...
...
@@ -68,7 +68,7 @@ document. Let's assume it will be in a header file called
void move(int dx, int dy);
};
}
and the implementation in the file called :file:`Rectangle.cpp`:
.. sourcecode:: c++
...
...
@@ -104,7 +104,7 @@ and the implementation in the file called :file:`Rectangle.cpp`:
x1 += dx;
y1 += dy;
}
}
This is pretty dumb, but should suffice to demonstrate the steps involved.
...
...
@@ -196,7 +196,7 @@ class name from Rectangle.h and adjust for Cython syntax, so now it becomes::
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Add public attributes
^^^^^^^^^^^^^^^^^^^^^^
...
...
@@ -346,9 +346,9 @@ nested in Cython::
T& at(int)
iterator begin()
iterator end()
cdef vector[int].iterator iter #iter is declared as being of type vector<int>::iterator
Note that the nested class is declared with a ``cppclass`` but without a ``cdef``.
C++ operators not compatible with Python syntax
...
...
@@ -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":
...
...
@@ -437,7 +444,7 @@ For example::
vect.push_back(i)
for i in range(10):
print vect[i]
The pxd files in ``/Cython/Includes/libcpp`` also work as good examples on
how to declare C++ classes.
...
...
@@ -601,7 +608,7 @@ module which:
* includes the needed C headers in an extern "C" block
* contains minimal forwarding functions in C++, each of which calls the
respective pure-C function
respective pure-C function
Declaring/Using References
---------------------------
...
...
@@ -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