Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Olivier B.
pybind11
Commits
10c74c6f
Commit
10c74c6f
authored
Feb 07, 2016
by
Wenzel Jakob
Browse files
transparent std::array conversion (fixes #97)
parent
c91551b3
Changes
6
Hide whitespace changes
Inline
Side-by-side
docs/basics.rst
View file @
10c74c6f
...
...
@@ -251,6 +251,8 @@ as arguments and return values, refer to the section on binding :ref:`classes`.
+------------------------+--------------------------+-----------------------+
| std::complex<T> | Complex numbers | pybind11/complex.h |
+------------------------+--------------------------+-----------------------+
| std::array<T, Size> | STL static array | pybind11/stl.h |
+------------------------+--------------------------+-----------------------+
| std::vector<T> | STL dynamic array | pybind11/stl.h |
+------------------------+--------------------------+-----------------------+
| std::map<T1, T2> | STL ordered map | pybind11/stl.h |
...
...
example/example2.cpp
View file @
10c74c6f
...
...
@@ -66,6 +66,11 @@ public:
return
list
;
}
/* C++ STL data types are automatically casted */
std
::
array
<
std
::
string
,
2
>
get_array
()
{
return
std
::
array
<
std
::
string
,
2
>
{{
"array entry 1"
,
"array entry 2"
}};
}
/* Easily iterate over a dictionary using a C++11 range-based for loop */
void
print_dict
(
py
::
dict
dict
)
{
for
(
auto
item
:
dict
)
...
...
@@ -114,6 +119,13 @@ public:
return
std
::
make_tuple
(
std
::
get
<
2
>
(
input
),
std
::
get
<
1
>
(
input
),
std
::
get
<
0
>
(
input
));
}
/* STL data types (such as arrays) are automatically casted from Python */
void
print_array
(
std
::
array
<
std
::
string
,
2
>
&
array
)
{
int
index
=
0
;
for
(
auto
item
:
array
)
std
::
cout
<<
"array item "
<<
index
++
<<
": "
<<
item
<<
std
::
endl
;
}
void
throw_exception
()
{
throw
std
::
runtime_error
(
"This exception was intentionally thrown."
);
}
...
...
@@ -135,12 +147,14 @@ void init_ex2(py::module &m) {
.
def
(
"get_list_2"
,
&
Example2
::
get_list_2
,
"Return a C++ list"
)
.
def
(
"get_set"
,
&
Example2
::
get_set
,
"Return a Python set"
)
.
def
(
"get_set2"
,
&
Example2
::
get_set
,
"Return a C++ set"
)
.
def
(
"get_array"
,
&
Example2
::
get_array
,
"Return a C++ array"
)
.
def
(
"print_dict"
,
&
Example2
::
print_dict
,
"Print entries of a Python dictionary"
)
.
def
(
"print_dict_2"
,
&
Example2
::
print_dict_2
,
"Print entries of a C++ dictionary"
)
.
def
(
"print_set"
,
&
Example2
::
print_set
,
"Print entries of a Python set"
)
.
def
(
"print_set_2"
,
&
Example2
::
print_set_2
,
"Print entries of a C++ set"
)
.
def
(
"print_list"
,
&
Example2
::
print_list
,
"Print entries of a Python list"
)
.
def
(
"print_list_2"
,
&
Example2
::
print_list_2
,
"Print entries of a C++ list"
)
.
def
(
"print_array"
,
&
Example2
::
print_array
,
"Print entries of a C++ array"
)
.
def
(
"pair_passthrough"
,
&
Example2
::
pair_passthrough
,
"Return a pair in reversed order"
)
.
def
(
"tuple_passthrough"
,
&
Example2
::
tuple_passthrough
,
"Return a triple in reversed order"
)
.
def
(
"throw_exception"
,
&
Example2
::
throw_exception
,
"Throw an exception"
)
...
...
example/example2.py
View file @
10c74c6f
...
...
@@ -46,6 +46,10 @@ list_result = instance.get_list_2()
list_result
.
append
(
'value2'
)
instance
.
print_list_2
(
list_result
)
array_result
=
instance
.
get_array
()
print
(
array_result
)
instance
.
print_array
(
array_result
)
try
:
instance
.
throw_exception
()
except
Exception
as
e
:
...
...
example/example2.ref
View file @
10c74c6f
...
...
@@ -17,6 +17,9 @@ list item 0: overwritten
list item 1: value2
list item 0: value
list item 1: value2
[u'array entry 1', u'array entry 2']
array item 0: array entry 1
array item 1: array entry 2
This exception was intentionally thrown.
(u'test', True)
(5L, u'test', True)
...
...
@@ -30,6 +33,11 @@ class EExxaammppllee22(__builtin__.object)
| ____iinniitt____(...)
| x.__init__(...) initializes x; see help(type(x)) for signature
|
| ggeett__aarrrraayy(...)
| Signature : (example.Example2) -> list<unicode>[2]
|
| Return a C++ array
|
| ggeett__ddiicctt(...)
| Signature : (example.Example2) -> dict
|
...
...
@@ -65,6 +73,11 @@ class EExxaammppllee22(__builtin__.object)
|
| Return a pair in reversed order
|
| pprriinntt__aarrrraayy(...)
| Signature : (example.Example2, list<unicode>[2]) -> NoneType
|
| Print entries of a C++ array
|
| pprriinntt__ddiicctt(...)
| Signature : (example.Example2, dict) -> NoneType
|
...
...
include/pybind11/descr.h
View file @
10c74c6f
...
...
@@ -78,6 +78,15 @@ template <size_t Size> constexpr descr<Size - 1, 0> _(char const(&text)[Size]) {
return
descr
<
Size
-
1
,
0
>
(
text
,
{
nullptr
});
}
template
<
size_t
Rem
,
size_t
...
Digits
>
struct
int_to_str
:
int_to_str
<
Rem
/
10
,
Rem
%
10
,
Digits
...
>
{
};
template
<
size_t
...
Digits
>
struct
int_to_str
<
0
,
Digits
...
>
{
static
constexpr
auto
digits
=
descr
<
sizeof
...(
Digits
),
0
>
({
(
'0'
+
Digits
)...,
'\0'
},
{
nullptr
});
};
template
<
size_t
Size
>
auto
constexpr
_
()
{
return
int_to_str
<
Size
/
10
,
Size
%
10
>::
digits
;
}
template
<
typename
Type
>
constexpr
descr
<
1
,
1
>
_
()
{
return
descr
<
1
,
1
>
({
'%'
,
'\0'
},
{
&
typeid
(
Type
),
nullptr
});
}
...
...
@@ -149,6 +158,11 @@ template <typename Type> PYBIND11_NOINLINE descr _() {
return
descr
(
"%"
,
types
);
}
template
<
size_t
Size
>
PYBIND11_NOINLINE
descr
_
()
{
const
std
::
type_info
*
types
[
1
]
=
{
nullptr
};
return
descr
(
std
::
to_string
(
Size
).
c_str
(),
types
);
}
PYBIND11_NOINLINE
inline
descr
concat
()
{
return
_
(
""
);
}
PYBIND11_NOINLINE
inline
descr
concat
(
descr
&&
d
)
{
return
d
;
}
template
<
typename
...
Args
>
PYBIND11_NOINLINE
descr
concat
(
descr
&&
d
,
Args
&&
...
args
)
{
return
std
::
move
(
d
)
+
_
(
", "
)
+
concat
(
std
::
forward
<
Args
>
(
args
)...);
}
...
...
include/pybind11/stl.h
View file @
10c74c6f
...
...
@@ -22,9 +22,9 @@
NAMESPACE_BEGIN
(
pybind11
)
NAMESPACE_BEGIN
(
detail
)
template
<
typename
Valu
e
,
typename
Alloc
>
struct
type_caster
<
std
::
vector
<
Valu
e
,
Alloc
>>
{
typedef
std
::
vector
<
Valu
e
,
Alloc
>
type
;
typedef
type_caster
<
Valu
e
>
value_conv
;
template
<
typename
Typ
e
,
typename
Alloc
>
struct
type_caster
<
std
::
vector
<
Typ
e
,
Alloc
>>
{
typedef
std
::
vector
<
Typ
e
,
Alloc
>
vector_
type
;
typedef
type_caster
<
Typ
e
>
value_conv
;
public:
bool
load
(
handle
src
,
bool
convert
)
{
list
l
(
src
,
true
);
...
...
@@ -36,12 +36,12 @@ public:
for
(
auto
it
:
l
)
{
if
(
!
conv
.
load
(
it
,
convert
))
return
false
;
value
.
push_back
((
Valu
e
)
conv
);
value
.
push_back
((
Typ
e
)
conv
);
}
return
true
;
}
static
handle
cast
(
const
type
&
src
,
return_value_policy
policy
,
handle
parent
)
{
static
handle
cast
(
const
vector_
type
&
src
,
return_value_policy
policy
,
handle
parent
)
{
list
l
(
src
.
size
());
size_t
index
=
0
;
for
(
auto
const
&
value
:
src
)
{
...
...
@@ -52,7 +52,41 @@ public:
}
return
l
.
release
();
}
PYBIND11_TYPE_CASTER
(
type
,
_
(
"list<"
)
+
value_conv
::
name
()
+
_
(
">"
));
PYBIND11_TYPE_CASTER
(
vector_type
,
_
(
"list<"
)
+
value_conv
::
name
()
+
_
(
">"
));
};
template
<
typename
Type
,
size_t
Size
>
struct
type_caster
<
std
::
array
<
Type
,
Size
>>
{
typedef
std
::
array
<
Type
,
Size
>
array_type
;
typedef
type_caster
<
Type
>
value_conv
;
public:
bool
load
(
handle
src
,
bool
convert
)
{
list
l
(
src
,
true
);
if
(
!
l
.
check
())
return
false
;
if
(
l
.
size
()
!=
Size
)
return
false
;
value_conv
conv
;
size_t
ctr
=
0
;
for
(
auto
it
:
l
)
{
if
(
!
conv
.
load
(
it
,
convert
))
return
false
;
value
[
ctr
++
]
=
(
Type
)
conv
;
}
return
true
;
}
static
handle
cast
(
const
array_type
&
src
,
return_value_policy
policy
,
handle
parent
)
{
list
l
(
Size
);
size_t
index
=
0
;
for
(
auto
const
&
value
:
src
)
{
object
value_
=
object
(
value_conv
::
cast
(
value
,
policy
,
parent
),
false
);
if
(
!
value_
)
return
handle
();
PyList_SET_ITEM
(
l
.
ptr
(),
index
++
,
value_
.
release
().
ptr
());
// steals a reference
}
return
l
.
release
();
}
PYBIND11_TYPE_CASTER
(
array_type
,
_
(
"list<"
)
+
value_conv
::
name
()
+
_
(
">"
)
+
_
(
"["
)
+
_
<
Size
>
()
+
_
(
"]"
));
};
template
<
typename
Key
,
typename
Compare
,
typename
Alloc
>
struct
type_caster
<
std
::
set
<
Key
,
Compare
,
Alloc
>>
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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