Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pybind11
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
pybind11
Commits
678d787c
Commit
678d787c
authored
Jan 17, 2016
by
Wenzel Jakob
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
do more work with classes from pytypes.h (especially for STL container casting)
parent
d561cb01
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
128 additions
and
105 deletions
+128
-105
README.md
+7
-7
docs/intro.rst
+7
-7
example/example4.ref
+1
-1
example/run_test.py
+2
-0
include/pybind11/common.h
+5
-2
include/pybind11/pybind11.h
+18
-21
include/pybind11/pytypes.h
+50
-26
include/pybind11/stl.h
+28
-32
include/pybind11/typeid.h
+2
-1
setup.py
+8
-8
No files found.
README.md
View file @
678d787c
...
@@ -22,13 +22,13 @@ C++11-compatible compilers are widely available, this heavy machinery has
...
@@ -22,13 +22,13 @@ C++11-compatible compilers are widely available, this heavy machinery has
become an excessively large and unnecessary dependency.
become an excessively large and unnecessary dependency.
Think of this library as a tiny self-contained version of Boost.Python with
Think of this library as a tiny self-contained version of Boost.Python with
everything stripped away that isn't relevant for binding generation.
The core
everything stripped away that isn't relevant for binding generation.
Without
header files only require ~2.5K lines of code and depend on Python (2.7 or 3.x)
comments, the core header files only require ~2.5K lines of code and depend on
and the C++ standard library. This compact implementation was possible thanks
Python (2.7 or 3.x) and the C++ standard library. This compact implementation
to some of the new C++11 language features (specifically: tuples, lambda
was possible thanks to some of the new C++11 language features (specifically:
functions and variadic templates). Since its creation, this library has grown
tuples, lambda functions and variadic templates). Since its creation, this
beyond Boost.Python in many ways, leading to dramatically simpler binding code
library has grown beyond Boost.Python in many ways, leading to dramatically
in many common situations.
simpler binding code
in many common situations.
Tutorial and reference documentation is provided at
Tutorial and reference documentation is provided at
[
http://pybind11.readthedocs.org/en/latest
](
http://pybind11.readthedocs.org/en/latest
)
.
[
http://pybind11.readthedocs.org/en/latest
](
http://pybind11.readthedocs.org/en/latest
)
.
...
...
docs/intro.rst
View file @
678d787c
...
@@ -19,13 +19,13 @@ C++11-compatible compilers are widely available, this heavy machinery has
...
@@ -19,13 +19,13 @@ C++11-compatible compilers are widely available, this heavy machinery has
become an excessively large and unnecessary dependency.
become an excessively large and unnecessary dependency.
Think of this library as a tiny self-contained version of Boost.Python with
Think of this library as a tiny self-contained version of Boost.Python with
everything stripped away that isn't relevant for binding generation.
The core
everything stripped away that isn't relevant for binding generation.
Without
header files only require ~2.5K lines of code and depend on Python (2.7 or 3.x)
comments, the core header files only require ~2.5K lines of code and depend on
and the C++ standard library. This compact implementation was possible thanks
Python (2.7 or 3.x) and the C++ standard library. This compact implementation
to some of the new C++11 language features (specifically: tuples, lambda
was possible thanks to some of the new C++11 language features (specifically:
functions and variadic templates). Since its creation, this library has grown
tuples, lambda functions and variadic templates). Since its creation, this
beyond Boost.Python in many ways, leading to dramatically simpler binding code
library has grown beyond Boost.Python in many ways, leading to dramatically
in many common situations.
simpler binding code
in many common situations.
Core features
Core features
*************
*************
...
...
example/example4.ref
View file @
678d787c
...
@@ -10,7 +10,7 @@ test_function(enum=1)
...
@@ -10,7 +10,7 @@ test_function(enum=1)
None
None
test_function(enum=2)
test_function(enum=2)
None
None
<class '
Example4
.EMode'>
<class '
example
.EMode'>
EMode.EFirstMode
EMode.EFirstMode
EMode.EFirstMode
EMode.EFirstMode
Example4::test_function(enum=1)
Example4::test_function(enum=1)
...
...
example/run_test.py
View file @
678d787c
...
@@ -22,6 +22,8 @@ def sanitize(lines):
...
@@ -22,6 +22,8 @@ def sanitize(lines):
line
=
line
.
replace
(
'__builtin__'
,
'builtins'
)
line
=
line
.
replace
(
'__builtin__'
,
'builtins'
)
line
=
line
.
replace
(
'example.'
,
''
)
line
=
line
.
replace
(
'example.'
,
''
)
line
=
line
.
replace
(
'unicode'
,
'str'
)
line
=
line
.
replace
(
'unicode'
,
'str'
)
line
=
line
.
replace
(
'Example4.EMode'
,
'EMode'
)
line
=
line
.
replace
(
'example.EMode'
,
'EMode'
)
line
=
line
.
replace
(
'method of builtins.PyCapsule instance'
,
''
)
line
=
line
.
replace
(
'method of builtins.PyCapsule instance'
,
''
)
line
=
line
.
strip
()
line
=
line
.
strip
()
if
sys
.
platform
==
'win32'
:
if
sys
.
platform
==
'win32'
:
...
...
include/pybind11/common.h
View file @
678d787c
...
@@ -225,8 +225,8 @@ struct argument_entry {
...
@@ -225,8 +225,8 @@ struct argument_entry {
/// Internal data struture used to track registered instances and types
/// Internal data struture used to track registered instances and types
struct
internals
{
struct
internals
{
std
::
unordered_map
<
const
void
*
,
void
*>
registered_types_cpp
;
// std::type_info* -> type_info
std
::
unordered_map
<
const
void
*
,
void
*>
registered_types_cpp
;
// std::type_info* -> type_info
std
::
unordered_map
<
const
void
*
,
void
*>
registered_types_py
;
// PyTypeObject* -> type_info
std
::
unordered_map
<
const
void
*
,
void
*>
registered_types_py
;
// PyTypeObject* -> type_info
std
::
unordered_map
<
const
void
*
,
void
*>
registered_instances
;
// void * -> PyObject*
std
::
unordered_map
<
const
void
*
,
void
*>
registered_instances
;
// void * -> PyObject*
std
::
unordered_set
<
std
::
pair
<
const
PyObject
*
,
const
char
*>
,
overload_hash
>
inactive_overload_cache
;
std
::
unordered_set
<
std
::
pair
<
const
PyObject
*
,
const
char
*>
,
overload_hash
>
inactive_overload_cache
;
};
};
...
@@ -271,4 +271,7 @@ struct error_already_set : public std::runtime_error { public: error_already_set
...
@@ -271,4 +271,7 @@ struct error_already_set : public std::runtime_error { public: error_already_set
/// Thrown when pybind11::cast or handle::call fail due to a type casting error
/// Thrown when pybind11::cast or handle::call fail due to a type casting error
struct
cast_error
:
public
std
::
runtime_error
{
public
:
cast_error
(
const
std
::
string
&
w
=
""
)
:
std
::
runtime_error
(
w
)
{}
};
struct
cast_error
:
public
std
::
runtime_error
{
public
:
cast_error
(
const
std
::
string
&
w
=
""
)
:
std
::
runtime_error
(
w
)
{}
};
PYBIND11_NOINLINE
inline
void
pybind11_fail
(
const
char
*
reason
)
{
throw
std
::
runtime_error
(
reason
);
}
PYBIND11_NOINLINE
inline
void
pybind11_fail
(
const
std
::
string
&
reason
)
{
throw
std
::
runtime_error
(
reason
);
}
NAMESPACE_END
(
pybind11
)
NAMESPACE_END
(
pybind11
)
include/pybind11/pybind11.h
View file @
678d787c
...
@@ -24,7 +24,6 @@
...
@@ -24,7 +24,6 @@
#endif
#endif
#include "cast.h"
#include "cast.h"
#include <iostream>
NAMESPACE_BEGIN
(
pybind11
)
NAMESPACE_BEGIN
(
pybind11
)
...
@@ -196,9 +195,9 @@ protected:
...
@@ -196,9 +195,9 @@ protected:
a
.
value
,
return_value_policy
::
automatic
,
nullptr
);
a
.
value
,
return_value_policy
::
automatic
,
nullptr
);
if
(
obj
==
nullptr
)
if
(
obj
==
nullptr
)
throw
std
::
runtime_error
(
"arg(): could not convert default keyword "
pybind11_fail
(
"arg(): could not convert default keyword "
"argument into a Python object (type not "
"argument into a Python object (type not "
"registered yet?)"
);
"registered yet?)"
);
entry
->
args
.
emplace_back
(
a
.
name
,
a
.
descr
,
obj
);
entry
->
args
.
emplace_back
(
a
.
name
,
a
.
descr
,
obj
);
}
}
...
@@ -490,7 +489,7 @@ protected:
...
@@ -490,7 +489,7 @@ protected:
}
else
if
(
c
==
'%'
)
{
}
else
if
(
c
==
'%'
)
{
const
std
::
type_info
*
t
=
types
[
type_index
++
];
const
std
::
type_info
*
t
=
types
[
type_index
++
];
if
(
!
t
)
if
(
!
t
)
throw
std
::
runtime_error
(
"Internal error while parsing type signature (1)"
);
pybind11_fail
(
"Internal error while parsing type signature (1)"
);
auto
it
=
registered_types
.
find
(
t
);
auto
it
=
registered_types
.
find
(
t
);
if
(
it
!=
registered_types
.
end
())
{
if
(
it
!=
registered_types
.
end
())
{
signature
+=
((
const
detail
::
type_info
*
)
it
->
second
)
->
type
->
tp_name
;
signature
+=
((
const
detail
::
type_info
*
)
it
->
second
)
->
type
->
tp_name
;
...
@@ -504,7 +503,7 @@ protected:
...
@@ -504,7 +503,7 @@ protected:
}
}
}
}
if
(
type_depth
!=
0
||
types
[
type_index
]
!=
nullptr
)
if
(
type_depth
!=
0
||
types
[
type_index
]
!=
nullptr
)
throw
std
::
runtime_error
(
"Internal error while parsing type signature (2)"
);
pybind11_fail
(
"Internal error while parsing type signature (2)"
);
#if !defined(PYBIND11_CPP14)
#if !defined(PYBIND11_CPP14)
delete
[]
types
;
delete
[]
types
;
...
@@ -519,7 +518,7 @@ protected:
...
@@ -519,7 +518,7 @@ protected:
#endif
#endif
if
(
!
m_entry
->
args
.
empty
()
&&
(
int
)
m_entry
->
args
.
size
()
!=
args
)
if
(
!
m_entry
->
args
.
empty
()
&&
(
int
)
m_entry
->
args
.
size
()
!=
args
)
throw
std
::
runtime_error
(
pybind11_fail
(
"cpp_function(): function
\"
"
+
std
::
string
(
m_entry
->
name
)
+
"
\"
takes "
+
"cpp_function(): function
\"
"
+
std
::
string
(
m_entry
->
name
)
+
"
\"
takes "
+
std
::
to_string
(
args
)
+
" arguments, but "
+
std
::
to_string
(
m_entry
->
args
.
size
())
+
std
::
to_string
(
args
)
+
" arguments, but "
+
std
::
to_string
(
m_entry
->
args
.
size
())
+
" pybind11::arg entries were specified!"
);
" pybind11::arg entries were specified!"
);
...
@@ -555,7 +554,7 @@ protected:
...
@@ -555,7 +554,7 @@ protected:
});
});
m_ptr
=
PyCFunction_New
(
m_entry
->
def
,
entry_capsule
.
ptr
());
m_ptr
=
PyCFunction_New
(
m_entry
->
def
,
entry_capsule
.
ptr
());
if
(
!
m_ptr
)
if
(
!
m_ptr
)
throw
std
::
runtime_error
(
"cpp_function::cpp_function(): Could not allocate function object"
);
pybind11_fail
(
"cpp_function::cpp_function(): Could not allocate function object"
);
}
else
{
}
else
{
/* Append at the end of the overload chain */
/* Append at the end of the overload chain */
m_ptr
=
m_entry
->
sibling
;
m_ptr
=
m_entry
->
sibling
;
...
@@ -597,7 +596,7 @@ protected:
...
@@ -597,7 +596,7 @@ protected:
m_ptr
=
PyMethod_New
(
m_ptr
,
nullptr
,
entry
->
class_
);
m_ptr
=
PyMethod_New
(
m_ptr
,
nullptr
,
entry
->
class_
);
#endif
#endif
if
(
!
m_ptr
)
if
(
!
m_ptr
)
throw
std
::
runtime_error
(
"cpp_function::cpp_function(): Could not allocate instance method object"
);
pybind11_fail
(
"cpp_function::cpp_function(): Could not allocate instance method object"
);
Py_DECREF
(
func
);
Py_DECREF
(
func
);
}
}
}
}
...
@@ -621,7 +620,7 @@ public:
...
@@ -621,7 +620,7 @@ public:
m_ptr
=
Py_InitModule3
(
name
,
nullptr
,
doc
);
m_ptr
=
Py_InitModule3
(
name
,
nullptr
,
doc
);
#endif
#endif
if
(
m_ptr
==
nullptr
)
if
(
m_ptr
==
nullptr
)
throw
std
::
runtime_error
(
"Internal error in module::module()"
);
pybind11_fail
(
"Internal error in module::module()"
);
inc_ref
();
inc_ref
();
}
}
...
@@ -647,7 +646,7 @@ public:
...
@@ -647,7 +646,7 @@ public:
static
module
import
(
const
char
*
name
)
{
static
module
import
(
const
char
*
name
)
{
PyObject
*
obj
=
PyImport_ImportModule
(
name
);
PyObject
*
obj
=
PyImport_ImportModule
(
name
);
if
(
!
obj
)
if
(
!
obj
)
throw
std
::
runtime_error
(
"Module
\"
"
+
std
::
string
(
name
)
+
"
\"
not found!"
);
pybind11_fail
(
"Module
\"
"
+
std
::
string
(
name
)
+
"
\"
not found!"
);
return
module
(
obj
,
false
);
return
module
(
obj
,
false
);
}
}
};
};
...
@@ -668,7 +667,7 @@ public:
...
@@ -668,7 +667,7 @@ public:
auto
type
=
(
PyHeapTypeObject
*
)
type_holder
.
ptr
();
auto
type
=
(
PyHeapTypeObject
*
)
type_holder
.
ptr
();
if
(
!
type_holder
||
!
name
)
if
(
!
type_holder
||
!
name
)
throw
std
::
runtime_error
(
"generic_type: unable to create type object!"
);
pybind11_fail
(
"generic_type: unable to create type object!"
);
/* Register supplemental type information in C++ dict */
/* Register supplemental type information in C++ dict */
auto
&
internals
=
get_internals
();
auto
&
internals
=
get_internals
();
...
@@ -732,7 +731,7 @@ public:
...
@@ -732,7 +731,7 @@ public:
}
}
if
(
PyType_Ready
(
&
type
->
ht_type
)
<
0
)
if
(
PyType_Ready
(
&
type
->
ht_type
)
<
0
)
throw
std
::
runtime_error
(
"generic_type: PyType_Ready failed!"
);
pybind11_fail
(
"generic_type: PyType_Ready failed!"
);
m_ptr
=
type_holder
.
ptr
();
m_ptr
=
type_holder
.
ptr
();
...
@@ -756,7 +755,7 @@ protected:
...
@@ -756,7 +755,7 @@ protected:
object
type_holder
(
PyType_Type
.
tp_alloc
(
&
PyType_Type
,
0
),
false
);
object
type_holder
(
PyType_Type
.
tp_alloc
(
&
PyType_Type
,
0
),
false
);
object
name
(
PYBIND11_FROM_STRING
(
name_
.
c_str
()),
false
);
object
name
(
PYBIND11_FROM_STRING
(
name_
.
c_str
()),
false
);
if
(
!
type_holder
||
!
name
)
if
(
!
type_holder
||
!
name
)
throw
std
::
runtime_error
(
"generic_type::metaclass(): unable to create type object!"
);
pybind11_fail
(
"generic_type::metaclass(): unable to create type object!"
);
auto
type
=
(
PyHeapTypeObject
*
)
type_holder
.
ptr
();
auto
type
=
(
PyHeapTypeObject
*
)
type_holder
.
ptr
();
type
->
ht_name
=
name
.
release
();
type
->
ht_name
=
name
.
release
();
...
@@ -767,7 +766,7 @@ protected:
...
@@ -767,7 +766,7 @@ protected:
~
Py_TPFLAGS_HAVE_GC
;
~
Py_TPFLAGS_HAVE_GC
;
if
(
PyType_Ready
(
&
type
->
ht_type
)
<
0
)
if
(
PyType_Ready
(
&
type
->
ht_type
)
<
0
)
throw
std
::
runtime_error
(
"generic_type::metaclass(): PyType_Ready failed!"
);
pybind11_fail
(
"generic_type::metaclass(): PyType_Ready failed!"
);
ob_type
=
(
PyTypeObject
*
)
type_holder
.
release
();
ob_type
=
(
PyTypeObject
*
)
type_holder
.
release
();
}
}
...
@@ -798,7 +797,7 @@ protected:
...
@@ -798,7 +797,7 @@ protected:
auto
&
registered_instances
=
detail
::
get_internals
().
registered_instances
;
auto
&
registered_instances
=
detail
::
get_internals
().
registered_instances
;
auto
it
=
registered_instances
.
find
(
self
->
value
);
auto
it
=
registered_instances
.
find
(
self
->
value
);
if
(
it
==
registered_instances
.
end
())
if
(
it
==
registered_instances
.
end
())
throw
std
::
runtime_error
(
"generic_type::dealloc(): Tried to deallocate unregistered instance!"
);
pybind11_fail
(
"generic_type::dealloc(): Tried to deallocate unregistered instance!"
);
registered_instances
.
erase
(
it
);
registered_instances
.
erase
(
it
);
}
}
Py_XDECREF
(
self
->
parent
);
Py_XDECREF
(
self
->
parent
);
...
@@ -1096,14 +1095,12 @@ PYBIND11_NOINLINE inline void keep_alive_impl(int Nurse, int Patient, PyObject *
...
@@ -1096,14 +1095,12 @@ PYBIND11_NOINLINE inline void keep_alive_impl(int Nurse, int Patient, PyObject *
handle
patient
(
Patient
>
0
?
PyTuple_GetItem
(
arg
,
Patient
-
1
)
:
ret
);
handle
patient
(
Patient
>
0
?
PyTuple_GetItem
(
arg
,
Patient
-
1
)
:
ret
);
if
(
!
nurse
||
!
patient
)
if
(
!
nurse
||
!
patient
)
throw
std
::
runtime_error
(
"Could not activate keep_alive!"
);
pybind11_fail
(
"Could not activate keep_alive!"
);
cpp_function
disable_lifesupport
(
cpp_function
disable_lifesupport
(
[
patient
](
handle
weakref
)
{
patient
.
dec_ref
();
weakref
.
dec_ref
();
});
[
patient
](
handle
weakref
)
{
patient
.
dec_ref
();
weakref
.
dec_ref
();
});
weakref
wr
(
nurse
,
disable_lifesupport
);
weakref
wr
(
nurse
,
disable_lifesupport
);
if
(
!
wr
)
throw
std
::
runtime_error
(
"Could not allocate weak reference!"
);
patient
.
inc_ref
();
/* reference patient and leak the weak reference */
patient
.
inc_ref
();
/* reference patient and leak the weak reference */
(
void
)
wr
.
release
();
(
void
)
wr
.
release
();
...
@@ -1138,7 +1135,7 @@ template <typename InputType, typename OutputType> void implicitly_convertible()
...
@@ -1138,7 +1135,7 @@ template <typename InputType, typename OutputType> void implicitly_convertible()
auto
&
registered_types
=
detail
::
get_internals
().
registered_types_cpp
;
auto
&
registered_types
=
detail
::
get_internals
().
registered_types_cpp
;
auto
it
=
registered_types
.
find
(
&
typeid
(
OutputType
));
auto
it
=
registered_types
.
find
(
&
typeid
(
OutputType
));
if
(
it
==
registered_types
.
end
())
if
(
it
==
registered_types
.
end
())
throw
std
::
runtime_error
(
"implicitly_convertible: Unable to find type "
+
type_id
<
OutputType
>
());
pybind11_fail
(
"implicitly_convertible: Unable to find type "
+
type_id
<
OutputType
>
());
((
detail
::
type_info
*
)
it
->
second
)
->
implicit_conversions
.
push_back
(
implicit_caster
);
((
detail
::
type_info
*
)
it
->
second
)
->
implicit_conversions
.
push_back
(
implicit_caster
);
}
}
...
@@ -1196,7 +1193,7 @@ inline function get_overload(const void *this_ptr, const char *name) {
...
@@ -1196,7 +1193,7 @@ inline function get_overload(const void *this_ptr, const char *name) {
#define PYBIND11_OVERLOAD_PURE(ret_type, class_name, name, ...) \
#define PYBIND11_OVERLOAD_PURE(ret_type, class_name, name, ...) \
PYBIND11_OVERLOAD_INT(ret_type, class_name, name, __VA_ARGS__) \
PYBIND11_OVERLOAD_INT(ret_type, class_name, name, __VA_ARGS__) \
throw std::runtime_error
("Tried to call pure virtual function \"" #name "\"");
pybind11::pybind11_fail
("Tried to call pure virtual function \"" #name "\"");
NAMESPACE_END
(
pybind11
)
NAMESPACE_END
(
pybind11
)
...
...
include/pybind11/pytypes.h
View file @
678d787c
...
@@ -88,12 +88,12 @@ public:
...
@@ -88,12 +88,12 @@ public:
iterator
(
PyObject
*
obj
,
bool
borrowed
=
false
)
:
object
(
obj
,
borrowed
)
{
++*
this
;
}
iterator
(
PyObject
*
obj
,
bool
borrowed
=
false
)
:
object
(
obj
,
borrowed
)
{
++*
this
;
}
iterator
&
operator
++
()
{
iterator
&
operator
++
()
{
if
(
ptr
())
if
(
ptr
())
value
=
object
(
PyIter_Next
(
ptr
()
),
false
);
value
=
object
(
PyIter_Next
(
m_ptr
),
false
);
return
*
this
;
return
*
this
;
}
}
bool
operator
==
(
const
iterator
&
it
)
const
{
return
*
it
==
**
this
;
}
bool
operator
==
(
const
iterator
&
it
)
const
{
return
*
it
==
**
this
;
}
bool
operator
!=
(
const
iterator
&
it
)
const
{
return
*
it
!=
**
this
;
}
bool
operator
!=
(
const
iterator
&
it
)
const
{
return
*
it
!=
**
this
;
}
const
object
&
operator
*
()
const
{
return
value
;
}
const
handle
&
operator
*
()
const
{
return
value
;
}
bool
check
()
const
{
return
PyIter_Check
(
ptr
());
}
bool
check
()
const
{
return
PyIter_Check
(
ptr
());
}
private
:
private
:
object
value
;
object
value
;
...
@@ -127,10 +127,10 @@ public:
...
@@ -127,10 +127,10 @@ public:
void
operator
=
(
const
handle
&
h
)
{
void
operator
=
(
const
handle
&
h
)
{
if
(
attr
)
{
if
(
attr
)
{
if
(
PyObject_SetAttr
(
obj
,
key
,
(
PyObject
*
)
h
.
ptr
())
<
0
)
if
(
PyObject_SetAttr
(
obj
,
key
,
(
PyObject
*
)
h
.
ptr
())
<
0
)
throw
std
::
runtime_error
(
"Unable to set object attribute"
);
pybind11_fail
(
"Unable to set object attribute"
);
}
else
{
}
else
{
if
(
PyObject_SetItem
(
obj
,
key
,
(
PyObject
*
)
h
.
ptr
())
<
0
)
if
(
PyObject_SetItem
(
obj
,
key
,
(
PyObject
*
)
h
.
ptr
())
<
0
)
throw
std
::
runtime_error
(
"Unable to set object item"
);
pybind11_fail
(
"Unable to set object item"
);
}
}
}
}
...
@@ -164,12 +164,12 @@ public:
...
@@ -164,12 +164,12 @@ public:
void
operator
=
(
const
handle
&
o
)
{
void
operator
=
(
const
handle
&
o
)
{
o
.
inc_ref
();
// PyList_SetItem steals a reference
o
.
inc_ref
();
// PyList_SetItem steals a reference
if
(
PyList_SetItem
(
list
,
(
ssize_t
)
index
,
(
PyObject
*
)
o
.
ptr
())
<
0
)
if
(
PyList_SetItem
(
list
,
(
ssize_t
)
index
,
(
PyObject
*
)
o
.
ptr
())
<
0
)
throw
std
::
runtime_error
(
"Unable to assign value in Python list!"
);
pybind11_fail
(
"Unable to assign value in Python list!"
);
}
}
operator
object
()
const
{
operator
object
()
const
{
PyObject
*
result
=
PyList_GetItem
(
list
,
(
ssize_t
)
index
);
PyObject
*
result
=
PyList_GetItem
(
list
,
(
ssize_t
)
index
);
if
(
!
result
)
if
(
!
result
)
throw
std
::
runtime_error
(
"Unable to retrieve value from Python list!"
);
pybind11_fail
(
"Unable to retrieve value from Python list!"
);
return
object
(
result
,
true
);
return
object
(
result
,
true
);
}
}
private
:
private
:
...
@@ -184,12 +184,12 @@ public:
...
@@ -184,12 +184,12 @@ public:
void
operator
=
(
const
handle
&
o
)
{
void
operator
=
(
const
handle
&
o
)
{
o
.
inc_ref
();
// PyTuple_SetItem steals a reference
o
.
inc_ref
();
// PyTuple_SetItem steals a reference
if
(
PyTuple_SetItem
(
tuple
,
(
ssize_t
)
index
,
(
PyObject
*
)
o
.
ptr
())
<
0
)
if
(
PyTuple_SetItem
(
tuple
,
(
ssize_t
)
index
,
(
PyObject
*
)
o
.
ptr
())
<
0
)
throw
std
::
runtime_error
(
"Unable to assign value in Python tuple!"
);
pybind11_fail
(
"Unable to assign value in Python tuple!"
);
}
}
operator
object
()
const
{
operator
object
()
const
{
PyObject
*
result
=
PyTuple_GetItem
(
tuple
,
(
ssize_t
)
index
);
PyObject
*
result
=
PyTuple_GetItem
(
tuple
,
(
ssize_t
)
index
);
if
(
!
result
)
if
(
!
result
)
throw
std
::
runtime_error
(
"Unable to retrieve value from Python tuple!"
);
pybind11_fail
(
"Unable to retrieve value from Python tuple!"
);
return
object
(
result
,
true
);
return
object
(
result
,
true
);
}
}
private
:
private
:
...
@@ -205,8 +205,8 @@ public:
...
@@ -205,8 +205,8 @@ public:
pos
=
-
1
;
pos
=
-
1
;
return
*
this
;
return
*
this
;
}
}
std
::
pair
<
object
,
object
>
operator
*
()
const
{
std
::
pair
<
handle
,
handle
>
operator
*
()
const
{
return
std
::
make_pair
(
object
(
key
,
true
),
object
(
value
,
true
)
);
return
std
::
make_pair
(
key
,
value
);
}
}
bool
operator
==
(
const
dict_iterator
&
it
)
const
{
return
it
.
pos
==
pos
;
}
bool
operator
==
(
const
dict_iterator
&
it
)
const
{
return
it
.
pos
==
pos
;
}
bool
operator
!=
(
const
dict_iterator
&
it
)
const
{
return
it
.
pos
!=
pos
;
}
bool
operator
!=
(
const
dict_iterator
&
it
)
const
{
return
it
.
pos
!=
pos
;
}
...
@@ -242,7 +242,10 @@ inline iterator handle::end() const { return iterator(nullptr); }
...
@@ -242,7 +242,10 @@ inline iterator handle::end() const { return iterator(nullptr); }
class
str
:
public
object
{
class
str
:
public
object
{
public
:
public
:
PYBIND11_OBJECT_DEFAULT
(
str
,
object
,
PyUnicode_Check
)
PYBIND11_OBJECT_DEFAULT
(
str
,
object
,
PyUnicode_Check
)
str
(
const
std
::
string
&
s
)
:
object
(
PyUnicode_FromStringAndSize
(
s
.
c_str
(),
s
.
length
()),
false
)
{
}
str
(
const
std
::
string
&
s
)
:
object
(
PyUnicode_FromStringAndSize
(
s
.
c_str
(),
s
.
length
()),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate string object!"
);
}
operator
std
::
string
()
const
{
operator
std
::
string
()
const
{
#if PY_MAJOR_VERSION >= 3
#if PY_MAJOR_VERSION >= 3
...
@@ -250,7 +253,7 @@ public:
...
@@ -250,7 +253,7 @@ public:
#else
#else
object
temp
(
PyUnicode_AsUTF8String
(
m_ptr
),
false
);
object
temp
(
PyUnicode_AsUTF8String
(
m_ptr
),
false
);
if
(
temp
.
ptr
()
==
nullptr
)
if
(
temp
.
ptr
()
==
nullptr
)
throw
std
::
runtime_error
(
"Unable to extract string contents!"
);
pybind11_fail
(
"Unable to extract string contents!"
);
return
PyString_AsString
(
temp
.
ptr
());
return
PyString_AsString
(
temp
.
ptr
());
#endif
#endif
}
}
...
@@ -270,14 +273,16 @@ public:
...
@@ -270,14 +273,16 @@ public:
PYBIND11_OBJECT_DEFAULT
(
bytes
,
object
,
PYBIND11_BYTES_CHECK
)
PYBIND11_OBJECT_DEFAULT
(
bytes
,
object
,
PYBIND11_BYTES_CHECK
)
bytes
(
const
std
::
string
&
s
)
bytes
(
const
std
::
string
&
s
)
:
object
(
PYBIND11_BYTES_FROM_STRING_AND_SIZE
(
s
.
data
(),
s
.
size
()),
false
)
{
}
:
object
(
PYBIND11_BYTES_FROM_STRING_AND_SIZE
(
s
.
data
(),
s
.
size
()),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate bytes object!"
);
}
operator
std
::
string
()
const
{
operator
std
::
string
()
const
{
char
*
buffer
;
char
*
buffer
;
ssize_t
length
;
ssize_t
length
;
int
err
=
PYBIND11_BYTES_AS_STRING_AND_SIZE
(
m_ptr
,
&
buffer
,
&
length
);
int
err
=
PYBIND11_BYTES_AS_STRING_AND_SIZE
(
m_ptr
,
&
buffer
,
&
length
);
if
(
err
==
-
1
)
if
(
err
==
-
1
)
throw
std
::
runtime_error
(
"Unable to extract bytes contents!"
);
pybind11_fail
(
"Unable to extract bytes contents!"
);
return
std
::
string
(
buffer
,
length
);
return
std
::
string
(
buffer
,
length
);
}
}
};
};
...
@@ -306,6 +311,7 @@ public:
...
@@ -306,6 +311,7 @@ public:
else
else
m_ptr
=
PyLong_FromUnsignedLongLong
((
unsigned
long
long
)
value
);
m_ptr
=
PyLong_FromUnsignedLongLong
((
unsigned
long
long
)
value
);
}
}
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate int object!"
);
}
}
template
<
typename
T
,
template
<
typename
T
,
...
@@ -328,8 +334,12 @@ public:
...
@@ -328,8 +334,12 @@ public:
class
float_
:
public
object
{
class
float_
:
public
object
{
public
:
public
:
PYBIND11_OBJECT_DEFAULT
(
float_
,
object
,
PyFloat_Check
)
PYBIND11_OBJECT_DEFAULT
(
float_
,
object
,
PyFloat_Check
)
float_
(
float
value
)
:
object
(
PyFloat_FromDouble
((
double
)
value
),
false
)
{
}
float_
(
float
value
)
:
object
(
PyFloat_FromDouble
((
double
)
value
),
false
)
{
float_
(
double
value
)
:
object
(
PyFloat_FromDouble
((
double
)
value
),
false
)
{
}
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate float object!"
);
}
float_
(
double
value
)
:
object
(
PyFloat_FromDouble
((
double
)
value
),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate float object!"
);
}
operator
float
()
const
{
return
(
float
)
PyFloat_AsDouble
(
m_ptr
);
}
operator
float
()
const
{
return
(
float
)
PyFloat_AsDouble
(
m_ptr
);
}
operator
double
()
const
{
return
(
double
)
PyFloat_AsDouble
(
m_ptr
);
}
operator
double
()
const
{
return
(
double
)
PyFloat_AsDouble
(
m_ptr
);
}
};
};
...
@@ -337,7 +347,9 @@ public:
...
@@ -337,7 +347,9 @@ public:
class
weakref
:
public
object
{
class
weakref
:
public
object
{
public
:
public
:
PYBIND11_OBJECT_DEFAULT
(
weakref
,
object
,
PyWeakref_Check
)
PYBIND11_OBJECT_DEFAULT
(
weakref
,
object
,
PyWeakref_Check
)
weakref
(
handle
obj
,
handle
callback
=
handle
())
:
object
(
PyWeakref_NewRef
(
obj
.
ptr
(),
callback
.
ptr
()),
false
)
{
}
weakref
(
handle
obj
,
handle
callback
=
handle
())
:
object
(
PyWeakref_NewRef
(
obj
.
ptr
(),
callback
.
ptr
()),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate weak reference!"
);
}
};
};
class
slice
:
public
object
{
class
slice
:
public
object
{
...
@@ -346,6 +358,7 @@ public:
...
@@ -346,6 +358,7 @@ public:
slice
(
ssize_t
start_
,
ssize_t
stop_
,
ssize_t
step_
)
{
slice
(
ssize_t
start_
,
ssize_t
stop_
,
ssize_t
step_
)
{
int_
start
(
start_
),
stop
(
stop_
),
step
(
step_
);
int_
start
(
start_
),
stop
(
stop_
),
step
(
step_
);
m_ptr
=
PySlice_New
(
start
.
ptr
(),
stop
.
ptr
(),
step
.
ptr
());
m_ptr
=
PySlice_New
(
start
.
ptr
(),
stop
.
ptr
(),
step
.
ptr
());
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate slice object!"
);
}
}
bool
compute
(
ssize_t
length
,
ssize_t
*
start
,
ssize_t
*
stop
,
ssize_t
*
step
,
ssize_t
*
slicelength
)
const
{
bool
compute
(
ssize_t
length
,
ssize_t
*
start
,
ssize_t
*
stop
,
ssize_t
*
step
,
ssize_t
*
slicelength
)
const
{
return
PySlice_GetIndicesEx
((
PYBIND11_SLICE_OBJECT
*
)
m_ptr
,
length
,
return
PySlice_GetIndicesEx
((
PYBIND11_SLICE_OBJECT
*
)
m_ptr
,
length
,
...
@@ -357,10 +370,13 @@ class capsule : public object {
...
@@ -357,10 +370,13 @@ class capsule : public object {
public
:
public
:
PYBIND11_OBJECT_DEFAULT
(
capsule
,
object
,
PyCapsule_CheckExact
)
PYBIND11_OBJECT_DEFAULT
(
capsule
,
object
,
PyCapsule_CheckExact
)
capsule
(
PyObject
*
obj
,
bool
borrowed
)
:
object
(
obj
,
borrowed
)
{
}
capsule
(
PyObject
*
obj
,
bool
borrowed
)
:
object
(
obj
,
borrowed
)
{
}
capsule
(
void
*
value
,
void
(
*
destruct
)(
PyObject
*
)
=
nullptr
)
:
object
(
PyCapsule_New
(
value
,
nullptr
,
destruct
),
false
)
{
}
capsule
(
void
*
value
,
void
(
*
destruct
)(
PyObject
*
)
=
nullptr
)
:
object
(
PyCapsule_New
(
value
,
nullptr
,
destruct
),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate capsule object!"
);
}
template
<
typename
T
>
operator
T
*
()
const
{
template
<
typename
T
>
operator
T
*
()
const
{
T
*
result
=
static_cast
<
T
*>
(
PyCapsule_GetPointer
(
m_ptr
,
nullptr
));
T
*
result
=
static_cast
<
T
*>
(
PyCapsule_GetPointer
(
m_ptr
,
nullptr
));
if
(
!
result
)
throw
std
::
runtime_error
(
"Unable to extract capsule contents!"
);
if
(
!
result
)
pybind11_fail
(
"Unable to extract capsule contents!"
);
return
result
;
return
result
;
}
}
};
};
...
@@ -368,7 +384,9 @@ public:
...
@@ -368,7 +384,9 @@ public:
class
tuple
:
public
object
{
class
tuple
:
public
object
{
public
:
public
:
PYBIND11_OBJECT
(
tuple
,
object
,
PyTuple_Check
)
PYBIND11_OBJECT
(
tuple
,
object
,
PyTuple_Check
)
tuple
(
size_t
size
=
0
)
:
object
(
PyTuple_New
((
ssize_t
)
size
),
false
)
{
}
tuple
(
size_t
size
=
0
)
:
object
(
PyTuple_New
((
ssize_t
)
size
),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate tuple object!"
);
}
size_t
size
()
const
{
return
(
size_t
)
PyTuple_Size
(
m_ptr
);
}
size_t
size
()
const
{
return
(
size_t
)
PyTuple_Size
(
m_ptr
);
}
detail
::
tuple_accessor
operator
[](
size_t
index
)
const
{
return
detail
::
tuple_accessor
(
ptr
(),
index
);
}
detail
::
tuple_accessor
operator
[](
size_t
index
)
const
{
return
detail
::
tuple_accessor
(
ptr
(),
index
);
}
};
};
...
@@ -376,7 +394,9 @@ public:
...
@@ -376,7 +394,9 @@ public:
class
dict
:
public
object
{
class
dict
:
public
object
{
public
:
public
:
PYBIND11_OBJECT
(
dict
,
object
,
PyDict_Check
)
PYBIND11_OBJECT
(
dict
,
object
,
PyDict_Check
)
dict
()
:
object
(
PyDict_New
(),
false
)
{
}
dict
()
:
object
(
PyDict_New
(),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate dict object!"
);
}
size_t
size
()
const
{
return
(
size_t
)
PyDict_Size
(
m_ptr
);
}
size_t
size
()
const
{
return
(
size_t
)
PyDict_Size
(
m_ptr
);
}
detail
::
dict_iterator
begin
()
const
{
return
(
++
detail
::
dict_iterator
(
ptr
(),
0
));
}
detail
::
dict_iterator
begin
()
const
{
return
(
++
detail
::
dict_iterator
(
ptr
(),
0
));
}
detail
::
dict_iterator
end
()
const
{
return
detail
::
dict_iterator
();
}
detail
::
dict_iterator
end
()
const
{
return
detail
::
dict_iterator
();
}
...
@@ -386,7 +406,9 @@ public:
...
@@ -386,7 +406,9 @@ public:
class
list
:
public
object
{
class
list
:
public
object
{
public
:
public
:
PYBIND11_OBJECT
(
list
,
object
,
PyList_Check
)
PYBIND11_OBJECT
(
list
,
object
,
PyList_Check
)
list
(
size_t
size
=
0
)
:
object
(
PyList_New
((
ssize_t
)
size
),
false
)
{
}
list
(
size_t
size
=
0
)
:
object
(
PyList_New
((
ssize_t
)
size
),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate list object!"
);
}
size_t
size
()
const
{
return
(
size_t
)
PyList_Size
(
m_ptr
);
}
size_t
size
()
const
{
return
(
size_t
)
PyList_Size
(
m_ptr
);
}
detail
::
list_accessor
operator
[](
size_t
index
)
const
{
return
detail
::
list_accessor
(
ptr
(),
index
);
}
detail
::
list_accessor
operator
[](
size_t
index
)
const
{
return
detail
::
list_accessor
(
ptr
(),
index
);
}
void
append
(
const
object
&
object
)
const
{
PyList_Append
(
m_ptr
,
(
PyObject
*
)
object
.
ptr
());
}
void
append
(
const
object
&
object
)
const
{
PyList_Append
(
m_ptr
,
(
PyObject
*
)
object
.
ptr
());
}
...
@@ -395,10 +417,12 @@ public:
...
@@ -395,10 +417,12 @@ public:
class
set
:
public
object
{
class
set
:
public
object
{
public
:
public
:
PYBIND11_OBJECT
(
set
,
object
,
PySet_Check
)
PYBIND11_OBJECT
(
set
,
object
,
PySet_Check
)
set
()
:
object
(
PySet_New
(
nullptr
),
false
)
{
}
set
()
:
object
(
PySet_New
(
nullptr
),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate set object!"
);
}
size_t
size
()
const
{
return
(
size_t
)
PySet_Size
(
m_ptr
);
}
size_t
size
()
const
{
return
(
size_t
)
PySet_Size
(
m_ptr
);
}
void
add
(
const
object
&
object
)
const
{
PySet_Add
(
m_ptr
,
(
PyObject
*
)
object
.
ptr
())
;
}
bool
add
(
const
object
&
object
)
const
{
return
PySet_Add
(
m_ptr
,
(
PyObject
*
)
object
.
ptr
())
==
0
;
}
void
clear
()
const
{
PySet_Clear
(
ptr
()
);
}
void
clear
()
const
{
PySet_Clear
(
m_ptr
);
}
};
};
class
function
:
public
object
{
class
function
:
public
object
{
...
@@ -448,7 +472,7 @@ PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) {
...
@@ -448,7 +472,7 @@ PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) {
return
(
detail
::
type_info
*
)
it
->
second
;
return
(
detail
::
type_info
*
)
it
->
second
;
type
=
type
->
tp_base
;
type
=
type
->
tp_base
;
if
(
type
==
nullptr
)
if
(
type
==
nullptr
)
throw
std
::
runtime_error
(
"pybind11::detail::get_type_info: unable to find type object!"
);
pybind11_fail
(
"pybind11::detail::get_type_info: unable to find type object!"
);
}
while
(
true
);
}
while
(
true
);
}
}
...
...
include/pybind11/stl.h
View file @
678d787c
...
@@ -14,7 +14,6 @@
...
@@ -14,7 +14,6 @@
#include <set>
#include <set>
#include <iostream>
#include <iostream>
#if defined(_MSC_VER)
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(push)
#pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
#pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
...
@@ -28,14 +27,14 @@ template <typename Value, typename Alloc> struct type_caster<std::vector<Value,
...
@@ -28,14 +27,14 @@ template <typename Value, typename Alloc> struct type_caster<std::vector<Value,
typedef
type_caster
<
Value
>
value_conv
;
typedef
type_caster
<
Value
>
value_conv
;
public
:
public
:
bool
load
(
PyObject
*
src
,
bool
convert
)
{
bool
load
(
PyObject
*
src
,
bool
convert
)
{
if
(
!
PyList_Check
(
src
))
list
l
(
src
,
true
);
if
(
!
l
.
check
())
return
false
;
return
false
;
size_t
size
=
(
size_t
)
PyList_GET_SIZE
(
src
);
value
.
reserve
(
l
.
size
());
value
.
reserve
(
size
);
value
.
clear
();
value
.
clear
();
value_conv
conv
;
value_conv
conv
;
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
for
(
auto
it
:
l
)
{
if
(
!
conv
.
load
(
PyList_GetItem
(
src
,
(
ssize_t
)
i
),
convert
))
if
(
!
conv
.
load
(
it
.
ptr
(
),
convert
))
return
false
;
return
false
;
value
.
push_back
((
Value
)
conv
);
value
.
push_back
((
Value
)
conv
);
}
}
...
@@ -43,17 +42,15 @@ public:
...
@@ -43,17 +42,15 @@ public:
}
}
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
object
list
(
PyList_New
(
src
.
size
()),
false
);
list
l
(
src
.
size
());
if
(
!
list
)
return
nullptr
;
size_t
index
=
0
;
size_t
index
=
0
;
for
(
auto
const
&
value
:
src
)
{
for
(
auto
const
&
value
:
src
)
{
object
value_
(
value_conv
::
cast
(
value
,
policy
,
parent
),
false
);
object
value_
(
value_conv
::
cast
(
value
,
policy
,
parent
),
false
);
if
(
!
value_
)
if
(
!
value_
)
return
nullptr
;
return
nullptr
;
PyList_SET_ITEM
(
l
ist
.
ptr
(),
index
++
,
value_
.
release
());
// steals a reference
PyList_SET_ITEM
(
l
.
ptr
(),
index
++
,
value_
.
release
());
// steals a reference
}
}
return
l
ist
.
release
();
return
l
.
release
();
}
}
PYBIND11_TYPE_CASTER
(
type
,
_
(
"list<"
)
+
value_conv
::
name
()
+
_
(
">"
));
PYBIND11_TYPE_CASTER
(
type
,
_
(
"list<"
)
+
value_conv
::
name
()
+
_
(
">"
));
};
};
...
@@ -68,8 +65,8 @@ public:
...
@@ -68,8 +65,8 @@ public:
return
false
;
return
false
;
value
.
clear
();
value
.
clear
();
key_conv
conv
;
key_conv
conv
;
for
(
const
object
&
o
:
s
)
{
for
(
auto
entry
:
s
)
{
if
(
!
conv
.
load
(
(
PyObject
*
)
o
.
ptr
(),
convert
))
if
(
!
conv
.
load
(
entry
.
ptr
(),
convert
))
return
false
;
return
false
;
value
.
insert
((
Key
)
conv
);
value
.
insert
((
Key
)
conv
);
}
}
...
@@ -77,15 +74,13 @@ public:
...
@@ -77,15 +74,13 @@ public:
}
}
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
object
set
(
PySet_New
(
nullptr
),
false
);
pybind11
::
set
s
;
if
(
!
set
)
return
nullptr
;
for
(
auto
const
&
value
:
src
)
{
for
(
auto
const
&
value
:
src
)
{
object
value_
(
key_conv
::
cast
(
value
,
policy
,
parent
),
false
);
object
value_
(
key_conv
::
cast
(
value
,
policy
,
parent
),
false
);
if
(
!
value_
||
PySet_Add
(
set
.
ptr
(),
value_
.
ptr
())
!=
0
)
if
(
!
value_
||
!
s
.
add
(
value
)
)
return
nullptr
;
return
nullptr
;
}
}
return
s
et
.
release
();
return
s
.
release
();
}
}
PYBIND11_TYPE_CASTER
(
type
,
_
(
"set<"
)
+
key_conv
::
name
()
+
_
(
">"
));
PYBIND11_TYPE_CASTER
(
type
,
_
(
"set<"
)
+
key_conv
::
name
()
+
_
(
">"
));
};
};
...
@@ -97,16 +92,15 @@ public:
...
@@ -97,16 +92,15 @@ public:
typedef
type_caster
<
Value
>
value_conv
;
typedef
type_caster
<
Value
>
value_conv
;
bool
load
(
PyObject
*
src
,
bool
convert
)
{
bool
load
(
PyObject
*
src
,
bool
convert
)
{
if
(
!
PyDict_Check
(
src
))
dict
d
(
src
,
true
);
if
(
!
d
.
check
())
return
false
;
return
false
;
value
.
clear
();
PyObject
*
key_
,
*
value_
;
ssize_t
pos
=
0
;
key_conv
kconv
;
key_conv
kconv
;
value_conv
vconv
;
value_conv
vconv
;
while
(
PyDict_Next
(
src
,
&
pos
,
&
key_
,
&
value_
))
{
value
.
clear
();
if
(
!
kconv
.
load
(
key_
,
convert
)
||
!
vconv
.
load
(
value_
,
convert
))
for
(
auto
it
:
d
)
{
if
(
!
kconv
.
load
(
it
.
first
.
ptr
(),
convert
)
||
!
vconv
.
load
(
it
.
second
.
ptr
(),
convert
))
return
false
;
return
false
;
value
[(
Key
)
kconv
]
=
(
Value
)
vconv
;
value
[(
Key
)
kconv
]
=
(
Value
)
vconv
;
}
}
...
@@ -114,16 +108,15 @@ public:
...
@@ -114,16 +108,15 @@ public:
}
}
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
static
PyObject
*
cast
(
const
type
&
src
,
return_value_policy
policy
,
PyObject
*
parent
)
{
object
dict
(
PyDict_New
(),
false
);
dict
d
;
if
(
!
dict
)
return
nullptr
;
for
(
auto
const
&
kv
:
src
)
{
for
(
auto
const
&
kv
:
src
)
{
object
key
(
key_conv
::
cast
(
kv
.
first
,
policy
,
parent
),
false
);
object
key
(
key_conv
::
cast
(
kv
.
first
,
policy
,
parent
),
false
);
object
value
(
value_conv
::
cast
(
kv
.
second
,
policy
,
parent
),
false
);
object
value
(
value_conv
::
cast
(
kv
.
second
,
policy
,
parent
),
false
);
if
(
!
key
||
!
value
||
PyDict_SetItem
(
dict
.
ptr
(),
key
.
ptr
(),
value
.
ptr
())
!=
0
)
if
(
!
key
||
!
value
)
return
nullptr
;
return
nullptr
;
d
[
key
]
=
value
;
}
}
return
d
ict
.
release
();
return
d
.
release
();
}
}
PYBIND11_TYPE_CASTER
(
type
,
_
(
"dict<"
)
+
key_conv
::
name
()
+
_
(
", "
)
+
value_conv
::
name
()
+
_
(
">"
));
PYBIND11_TYPE_CASTER
(
type
,
_
(
"dict<"
)
+
key_conv
::
name
()
+
_
(
", "
)
+
value_conv
::
name
()
+
_
(
">"
));
...
@@ -131,7 +124,10 @@ public:
...
@@ -131,7 +124,10 @@ public:
NAMESPACE_END
(
detail
)
NAMESPACE_END
(
detail
)
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
object
&
obj
)
{
os
<<
(
std
::
string
)
obj
.
str
();
return
os
;
}
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
handle
&
obj
)
{
os
<<
(
std
::
string
)
obj
.
str
();
return
os
;
}
NAMESPACE_END
(
pybind11
)
NAMESPACE_END
(
pybind11
)
...
...
include/pybind11/typeid.h
View file @
678d787c
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
#include <cstdio>
#include <cstdio>
#include <cstdlib>
#include <cstdlib>
#if defined(__GNUG__)
#if defined(__GNUG__)
#include <cxxabi.h>
#include <cxxabi.h>
#endif
#endif
...
@@ -26,7 +27,7 @@ inline void erase_all(std::string &string, const std::string &search) {
...
@@ -26,7 +27,7 @@ inline void erase_all(std::string &string, const std::string &search) {
}
}
}
}
inline
void
clean_type_id
(
std
::
string
&
name
)
{
PYBIND11_NOINLINE
inline
void
clean_type_id
(
std
::
string
&
name
)
{
#if defined(__GNUG__)
#if defined(__GNUG__)
int
status
=
0
;
int
status
=
0
;
std
::
unique_ptr
<
char
,
void
(
*
)(
void
*
)
>
res
{
std
::
unique_ptr
<
char
,
void
(
*
)(
void
*
)
>
res
{
...
...
setup.py
View file @
678d787c
...
@@ -17,6 +17,7 @@ setup(
...
@@ -17,6 +17,7 @@ setup(
headers
=
[
headers
=
[
'include/pybind11/cast.h'
,
'include/pybind11/cast.h'
,
'include/pybind11/complex.h'
,
'include/pybind11/complex.h'
,
'include/pybind11/descr.h'
,
'include/pybind11/numpy.h'
,
'include/pybind11/numpy.h'
,
'include/pybind11/pybind11.h'
,
'include/pybind11/pybind11.h'
,
'include/pybind11/stl.h'
,
'include/pybind11/stl.h'
,
...
@@ -57,11 +58,10 @@ C++11-compatible compilers are widely available, this heavy machinery has
...
@@ -57,11 +58,10 @@ C++11-compatible compilers are widely available, this heavy machinery has
become an excessively large and unnecessary dependency.
become an excessively large and unnecessary dependency.
Think of this library as a tiny self-contained version of Boost.Python with
Think of this library as a tiny self-contained version of Boost.Python with
everything stripped away that isn't relevant for binding generation. The whole
everything stripped away that isn't relevant for binding generation. The core
codebase requires less than 3000 lines of code and only depends on Python (2.7
header files only require ~2.5K lines of code and depend on Python (2.7 or 3.x)
or 3.x) and the C++ standard library. This compact implementation was
and the C++ standard library. This compact implementation was possible thanks
possible thanks to some of the new C++11 language features (tuples, lambda
to some of the new C++11 language features (specifically: tuples, lambda
functions and variadic templates). Since its creation, this library has
functions and variadic templates). Since its creation, this library has grown
grown beyond Boost.Python in many ways, leading to dramatically simpler binding
beyond Boost.Python in many ways, leading to dramatically simpler binding code
code in many common situations."""
,
in many common situations."""
)
)
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