Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
22859bb8
Commit
22859bb8
authored
Aug 22, 2018
by
Chris Rusby
Committed by
Wenzel Jakob
Jun 11, 2019
Browse files
Support more natural syntax for vector extend
parent
1aa8dd17
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
63 additions
and
1 deletion
+63
-1
docs/changelog.rst
docs/changelog.rst
+5
-0
include/pybind11/pytypes.h
include/pybind11/pytypes.h
+15
-0
include/pybind11/stl_bind.h
include/pybind11/stl_bind.h
+23
-1
tests/test_stl_binders.py
tests/test_stl_binders.py
+20
-0
No files found.
docs/changelog.rst
View file @
22859bb8
...
@@ -94,6 +94,11 @@ v2.2.4 (September 11, 2018)
...
@@ -94,6 +94,11 @@ v2.2.4 (September 11, 2018)
* A few minor typo fixes and improvements to the test suite, and
* A few minor typo fixes and improvements to the test suite, and
patches that silence compiler warnings.
patches that silence compiler warnings.
* Vectors now support construction from generators, as well as ``extend()`` from a
list or generator.
`#1496 <https://github.com/pybind/pybind11/pull/1496>`_.
v2.2.3 (April 29, 2018)
v2.2.3 (April 29, 2018)
-----------------------------------------------------
-----------------------------------------------------
...
...
include/pybind11/pytypes.h
View file @
22859bb8
...
@@ -1346,6 +1346,21 @@ inline size_t len(handle h) {
...
@@ -1346,6 +1346,21 @@ inline size_t len(handle h) {
return
(
size_t
)
result
;
return
(
size_t
)
result
;
}
}
inline
size_t
len_hint
(
handle
h
)
{
#if PY_VERSION_HEX >= 0x03040000
ssize_t
result
=
PyObject_LengthHint
(
h
.
ptr
(),
0
);
#else
ssize_t
result
=
PyObject_Length
(
h
.
ptr
());
#endif
if
(
result
<
0
)
{
// Sometimes a length can't be determined at all (eg generators)
// In which case simply return 0
PyErr_Clear
();
return
0
;
}
return
(
size_t
)
result
;
}
inline
str
repr
(
handle
h
)
{
inline
str
repr
(
handle
h
)
{
PyObject
*
str_value
=
PyObject_Repr
(
h
.
ptr
());
PyObject
*
str_value
=
PyObject_Repr
(
h
.
ptr
());
if
(
!
str_value
)
throw
error_already_set
();
if
(
!
str_value
)
throw
error_already_set
();
...
...
include/pybind11/stl_bind.h
View file @
22859bb8
...
@@ -122,7 +122,7 @@ void vector_modifiers(enable_if_t<is_copy_constructible<typename Vector::value_t
...
@@ -122,7 +122,7 @@ void vector_modifiers(enable_if_t<is_copy_constructible<typename Vector::value_t
cl
.
def
(
init
([](
iterable
it
)
{
cl
.
def
(
init
([](
iterable
it
)
{
auto
v
=
std
::
unique_ptr
<
Vector
>
(
new
Vector
());
auto
v
=
std
::
unique_ptr
<
Vector
>
(
new
Vector
());
v
->
reserve
(
len
(
it
));
v
->
reserve
(
len
_hint
(
it
));
for
(
handle
h
:
it
)
for
(
handle
h
:
it
)
v
->
push_back
(
h
.
cast
<
T
>
());
v
->
push_back
(
h
.
cast
<
T
>
());
return
v
.
release
();
return
v
.
release
();
...
@@ -136,6 +136,28 @@ void vector_modifiers(enable_if_t<is_copy_constructible<typename Vector::value_t
...
@@ -136,6 +136,28 @@ void vector_modifiers(enable_if_t<is_copy_constructible<typename Vector::value_t
"Extend the list by appending all the items in the given list"
"Extend the list by appending all the items in the given list"
);
);
cl
.
def
(
"extend"
,
[](
Vector
&
v
,
iterable
it
)
{
const
size_t
old_size
=
v
.
size
();
v
.
reserve
(
old_size
+
len_hint
(
it
));
try
{
for
(
handle
h
:
it
)
{
v
.
push_back
(
h
.
cast
<
T
>
());
}
}
catch
(
const
cast_error
&
)
{
v
.
erase
(
v
.
begin
()
+
static_cast
<
typename
Vector
::
difference_type
>
(
old_size
),
v
.
end
());
try
{
v
.
shrink_to_fit
();
}
catch
(
const
std
::
exception
&
)
{
// Do nothing
}
throw
;
}
},
arg
(
"L"
),
"Extend the list by appending all the items in the given list"
);
cl
.
def
(
"insert"
,
cl
.
def
(
"insert"
,
[](
Vector
&
v
,
SizeType
i
,
const
T
&
x
)
{
[](
Vector
&
v
,
SizeType
i
,
const
T
&
x
)
{
if
(
i
>
v
.
size
())
if
(
i
>
v
.
size
())
...
...
tests/test_stl_binders.py
View file @
22859bb8
...
@@ -11,6 +11,10 @@ def test_vector_int():
...
@@ -11,6 +11,10 @@ def test_vector_int():
assert
len
(
v_int
)
==
2
assert
len
(
v_int
)
==
2
assert
bool
(
v_int
)
is
True
assert
bool
(
v_int
)
is
True
# test construction from a generator
v_int1
=
m
.
VectorInt
(
x
for
x
in
range
(
5
))
assert
v_int1
==
m
.
VectorInt
([
0
,
1
,
2
,
3
,
4
])
v_int2
=
m
.
VectorInt
([
0
,
0
])
v_int2
=
m
.
VectorInt
([
0
,
0
])
assert
v_int
==
v_int2
assert
v_int
==
v_int2
v_int2
[
1
]
=
1
v_int2
[
1
]
=
1
...
@@ -33,6 +37,22 @@ def test_vector_int():
...
@@ -33,6 +37,22 @@ def test_vector_int():
del
v_int2
[
0
]
del
v_int2
[
0
]
assert
v_int2
==
m
.
VectorInt
([
0
,
99
,
2
,
3
])
assert
v_int2
==
m
.
VectorInt
([
0
,
99
,
2
,
3
])
v_int2
.
extend
(
m
.
VectorInt
([
4
,
5
]))
assert
v_int2
==
m
.
VectorInt
([
0
,
99
,
2
,
3
,
4
,
5
])
v_int2
.
extend
([
6
,
7
])
assert
v_int2
==
m
.
VectorInt
([
0
,
99
,
2
,
3
,
4
,
5
,
6
,
7
])
# test error handling, and that the vector is unchanged
with
pytest
.
raises
(
RuntimeError
):
v_int2
.
extend
([
8
,
'a'
])
assert
v_int2
==
m
.
VectorInt
([
0
,
99
,
2
,
3
,
4
,
5
,
6
,
7
])
# test extending from a generator
v_int2
.
extend
(
x
for
x
in
range
(
5
))
assert
v_int2
==
m
.
VectorInt
([
0
,
99
,
2
,
3
,
4
,
5
,
6
,
7
,
0
,
1
,
2
,
3
,
4
])
# related to the PyPy's buffer protocol.
# related to the PyPy's buffer protocol.
@
pytest
.
unsupported_on_pypy
@
pytest
.
unsupported_on_pypy
...
...
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