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
37e22e43
Commit
37e22e43
authored
Sep 08, 2016
by
Dean Moldovan
Browse files
Move common object functions into object_api mixin
parent
2d9220f0
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
89 additions
and
58 deletions
+89
-58
include/pybind11/attr.h
include/pybind11/attr.h
+1
-1
include/pybind11/cast.h
include/pybind11/cast.h
+9
-7
include/pybind11/pytypes.h
include/pybind11/pytypes.h
+79
-50
No files found.
include/pybind11/attr.h
View file @
37e22e43
...
@@ -276,7 +276,7 @@ template <> struct process_attribute<arg_v> : process_attribute_default<arg_v> {
...
@@ -276,7 +276,7 @@ template <> struct process_attribute<arg_v> : process_attribute_default<arg_v> {
/// Process a parent class attribute
/// Process a parent class attribute
template
<
typename
T
>
template
<
typename
T
>
struct
process_attribute
<
T
,
enable_if_t
<
std
::
is_base_of
<
handle
,
T
>::
value
>>
:
process_attribute_default
<
handle
>
{
struct
process_attribute
<
T
,
enable_if_t
<
is_pyobject
<
T
>::
value
>>
:
process_attribute_default
<
handle
>
{
static
void
init
(
const
handle
&
h
,
type_record
*
r
)
{
r
->
bases
.
append
(
h
);
}
static
void
init
(
const
handle
&
h
,
type_record
*
r
)
{
r
->
bases
.
append
(
h
);
}
};
};
...
...
include/pybind11/cast.h
View file @
37e22e43
...
@@ -908,7 +908,7 @@ template <> struct handle_type_name<args> { static PYBIND11_DESCR name() { retur
...
@@ -908,7 +908,7 @@ template <> struct handle_type_name<args> { static PYBIND11_DESCR name() { retur
template
<
>
struct
handle_type_name
<
kwargs
>
{
static
PYBIND11_DESCR
name
()
{
return
_
(
"**kwargs"
);
}
};
template
<
>
struct
handle_type_name
<
kwargs
>
{
static
PYBIND11_DESCR
name
()
{
return
_
(
"**kwargs"
);
}
};
template
<
typename
type
>
template
<
typename
type
>
struct
type_caster
<
type
,
enable_if_t
<
std
::
is_base_of
<
handle
,
type
>::
value
>>
{
struct
type_caster
<
type
,
enable_if_t
<
is_pyobject
<
type
>::
value
>>
{
public:
public:
template
<
typename
T
=
type
,
enable_if_t
<!
std
::
is_base_of
<
object
,
T
>
::
value
,
int
>
=
0
>
template
<
typename
T
=
type
,
enable_if_t
<!
std
::
is_base_of
<
object
,
T
>
::
value
,
int
>
=
0
>
bool
load
(
handle
src
,
bool
/* convert */
)
{
value
=
type
(
src
);
return
value
.
check
();
}
bool
load
(
handle
src
,
bool
/* convert */
)
{
value
=
type
(
src
);
return
value
.
check
();
}
...
@@ -1296,18 +1296,20 @@ unpacking_collector<policy> collect_arguments(Args &&...args) {
...
@@ -1296,18 +1296,20 @@ unpacking_collector<policy> collect_arguments(Args &&...args) {
return
{
std
::
forward
<
Args
>
(
args
)...
};
return
{
std
::
forward
<
Args
>
(
args
)...
};
}
}
NAMESPACE_END
(
detail
)
template
<
typename
Derived
>
template
<
return_value_policy
policy
,
typename
...
Args
>
template
<
return_value_policy
policy
,
typename
...
Args
>
object
handle
::
operator
()(
Args
&&
...
args
)
const
{
object
object_api
<
Derived
>
::
operator
()(
Args
&&
...
args
)
const
{
return
detail
::
collect_arguments
<
policy
>
(
std
::
forward
<
Args
>
(
args
)...).
call
(
m_
ptr
);
return
detail
::
collect_arguments
<
policy
>
(
std
::
forward
<
Args
>
(
args
)...).
call
(
derived
().
ptr
()
);
}
}
template
<
return_value_policy
policy
,
template
<
typename
Derived
>
typename
...
Args
>
object
handle
::
call
(
Args
&&
...
args
)
const
{
template
<
return_value_policy
policy
,
typename
...
Args
>
object
object_api
<
Derived
>::
call
(
Args
&&
...
args
)
const
{
return
operator
()
<
policy
>
(
std
::
forward
<
Args
>
(
args
)...);
return
operator
()
<
policy
>
(
std
::
forward
<
Args
>
(
args
)...);
}
}
NAMESPACE_END
(
detail
)
#define PYBIND11_MAKE_OPAQUE(Type) \
#define PYBIND11_MAKE_OPAQUE(Type) \
namespace pybind11 { namespace detail { \
namespace pybind11 { namespace detail { \
template<> class type_caster<Type> : public type_caster_base<Type> { }; \
template<> class type_caster<Type> : public type_caster_base<Type> { }; \
...
...
include/pybind11/pytypes.h
View file @
37e22e43
...
@@ -16,50 +16,72 @@
...
@@ -16,50 +16,72 @@
NAMESPACE_BEGIN
(
pybind11
)
NAMESPACE_BEGIN
(
pybind11
)
/* A few forward declarations */
/* A few forward declarations */
class
object
;
class
str
;
class
iterator
;
class
handle
;
class
object
;
class
str
;
class
iterator
;
struct
arg
;
struct
arg_v
;
struct
arg
;
struct
arg_v
;
namespace
detail
{
class
accessor
;
class
args_proxy
;
class
kwargs_proxy
;
}
NAMESPACE_BEGIN
(
detail
)
class
accessor
;
class
args_proxy
;
/// Tag and check to identify a class which implements the Python object API
class
pyobject_tag
{
};
template
<
typename
T
>
using
is_pyobject
=
std
::
is_base_of
<
pyobject_tag
,
T
>
;
/// Mixin which adds common functions to handle, object and various accessors.
/// The only requirement for `Derived` is to implement `PyObject *Derived::ptr() const`.
template
<
typename
Derived
>
class
object_api
:
public
pyobject_tag
{
const
Derived
&
derived
()
const
{
return
static_cast
<
const
Derived
&>
(
*
this
);
}
public:
iterator
begin
()
const
;
iterator
end
()
const
;
accessor
operator
[](
handle
key
)
const
;
accessor
operator
[](
const
char
*
key
)
const
;
accessor
attr
(
handle
key
)
const
;
accessor
attr
(
const
char
*
key
)
const
;
args_proxy
operator
*
()
const
;
template
<
return_value_policy
policy
=
return_value_policy
::
automatic_reference
,
typename
...
Args
>
object
operator
()(
Args
&&
...
args
)
const
;
template
<
return_value_policy
policy
=
return_value_policy
::
automatic_reference
,
typename
...
Args
>
PYBIND11_DEPRECATED
(
"call(...) was deprecated in favor of operator()(...)"
)
object
call
(
Args
&&
...
args
)
const
;
bool
is_none
()
const
{
return
derived
().
ptr
()
==
Py_None
;
}
pybind11
::
str
str
()
const
;
pybind11
::
str
repr
()
const
;
int
ref_count
()
const
{
return
static_cast
<
int
>
(
Py_REFCNT
(
derived
().
ptr
()));
}
handle
get_type
()
const
;
};
NAMESPACE_END
(
detail
)
/// Holds a reference to a Python object (no reference counting)
/// Holds a reference to a Python object (no reference counting)
class
handle
{
class
handle
:
public
detail
::
object_api
<
handle
>
{
public:
public:
handle
()
:
m_ptr
(
nullptr
)
{
}
handle
()
=
default
;
handle
(
const
handle
&
other
)
:
m_ptr
(
other
.
m_ptr
)
{
}
handle
(
PyObject
*
ptr
)
:
m_ptr
(
ptr
)
{
}
handle
(
PyObject
*
ptr
)
:
m_ptr
(
ptr
)
{
}
PyObject
*
ptr
()
const
{
return
m_ptr
;
}
PyObject
*
ptr
()
const
{
return
m_ptr
;
}
PyObject
*&
ptr
()
{
return
m_ptr
;
}
PyObject
*&
ptr
()
{
return
m_ptr
;
}
const
handle
&
inc_ref
()
const
{
Py_XINCREF
(
m_ptr
);
return
*
this
;
}
const
handle
&
inc_ref
()
const
{
Py_XINCREF
(
m_ptr
);
return
*
this
;
}
const
handle
&
dec_ref
()
const
{
Py_XDECREF
(
m_ptr
);
return
*
this
;
}
const
handle
&
dec_ref
()
const
{
Py_XDECREF
(
m_ptr
);
return
*
this
;
}
int
ref_count
()
const
{
return
(
int
)
Py_REFCNT
(
m_ptr
);
}
handle
get_type
()
const
{
return
handle
((
PyObject
*
)
Py_TYPE
(
m_ptr
));
}
inline
iterator
begin
()
const
;
inline
iterator
end
()
const
;
inline
detail
::
accessor
operator
[](
handle
key
)
const
;
inline
detail
::
accessor
operator
[](
const
char
*
key
)
const
;
inline
detail
::
accessor
attr
(
handle
key
)
const
;
inline
detail
::
accessor
attr
(
const
char
*
key
)
const
;
inline
pybind11
::
str
str
()
const
;
inline
pybind11
::
str
repr
()
const
;
bool
is_none
()
const
{
return
m_ptr
==
Py_None
;
}
template
<
typename
T
>
T
cast
()
const
;
template
<
typename
T
>
T
cast
()
const
;
template
<
return_value_policy
policy
=
return_value_policy
::
automatic_reference
,
typename
...
Args
>
PYBIND11_DEPRECATED
(
"call(...) was deprecated in favor of operator()(...)"
)
object
call
(
Args
&&
...
args
)
const
;
template
<
return_value_policy
policy
=
return_value_policy
::
automatic_reference
,
typename
...
Args
>
object
operator
()(
Args
&&
...
args
)
const
;
operator
bool
()
const
{
return
m_ptr
!=
nullptr
;
}
operator
bool
()
const
{
return
m_ptr
!=
nullptr
;
}
bool
operator
==
(
const
handle
&
h
)
const
{
return
m_ptr
==
h
.
m_ptr
;
}
bool
operator
==
(
const
handle
&
h
)
const
{
return
m_ptr
==
h
.
m_ptr
;
}
bool
operator
!=
(
const
handle
&
h
)
const
{
return
m_ptr
!=
h
.
m_ptr
;
}
bool
operator
!=
(
const
handle
&
h
)
const
{
return
m_ptr
!=
h
.
m_ptr
;
}
bool
check
()
const
{
return
m_ptr
!=
nullptr
;
}
bool
check
()
const
{
return
m_ptr
!=
nullptr
;
}
inline
detail
::
args_proxy
operator
*
()
const
;
protected:
protected:
PyObject
*
m_ptr
;
PyObject
*
m_ptr
=
nullptr
;
};
};
/// Holds a reference to a Python object (with reference counting)
/// Holds a reference to a Python object (with reference counting)
class
object
:
public
handle
{
class
object
:
public
handle
{
public:
public:
object
()
{
}
object
()
=
default
;
object
(
const
object
&
o
)
:
handle
(
o
)
{
inc_ref
();
}
object
(
const
object
&
o
)
:
handle
(
o
)
{
inc_ref
();
}
object
(
const
handle
&
h
,
bool
borrowed
)
:
handle
(
h
)
{
if
(
borrowed
)
inc_ref
();
}
object
(
const
handle
&
h
,
bool
borrowed
)
:
handle
(
h
)
{
if
(
borrowed
)
inc_ref
();
}
object
(
PyObject
*
ptr
,
bool
borrowed
)
:
handle
(
ptr
)
{
if
(
borrowed
)
inc_ref
();
}
object
(
PyObject
*
ptr
,
bool
borrowed
)
:
handle
(
ptr
)
{
if
(
borrowed
)
inc_ref
();
}
...
@@ -347,14 +369,6 @@ public:
...
@@ -347,14 +369,6 @@ public:
PYBIND11_OBJECT_DEFAULT
(
iterable
,
object
,
detail
::
PyIterable_Check
)
PYBIND11_OBJECT_DEFAULT
(
iterable
,
object
,
detail
::
PyIterable_Check
)
};
};
inline
detail
::
accessor
handle
::
operator
[](
handle
key
)
const
{
return
detail
::
accessor
(
*
this
,
key
,
false
);
}
inline
detail
::
accessor
handle
::
operator
[](
const
char
*
key
)
const
{
return
detail
::
accessor
(
*
this
,
key
,
false
);
}
inline
detail
::
accessor
handle
::
attr
(
handle
key
)
const
{
return
detail
::
accessor
(
*
this
,
key
,
true
);
}
inline
detail
::
accessor
handle
::
attr
(
const
char
*
key
)
const
{
return
detail
::
accessor
(
*
this
,
key
,
true
);
}
inline
iterator
handle
::
begin
()
const
{
return
iterator
(
PyObject_GetIter
(
ptr
()),
false
);
}
inline
iterator
handle
::
end
()
const
{
return
iterator
(
nullptr
,
false
);
}
inline
detail
::
args_proxy
handle
::
operator
*
()
const
{
return
detail
::
args_proxy
(
*
this
);
}
class
bytes
;
class
bytes
;
class
str
:
public
object
{
class
str
:
public
object
{
...
@@ -400,24 +414,6 @@ inline namespace literals {
...
@@ -400,24 +414,6 @@ inline namespace literals {
inline
str
operator
""
_s
(
const
char
*
s
,
size_t
size
)
{
return
{
s
,
size
};
}
inline
str
operator
""
_s
(
const
char
*
s
,
size_t
size
)
{
return
{
s
,
size
};
}
}
}
inline
pybind11
::
str
handle
::
str
()
const
{
PyObject
*
strValue
=
PyObject_Str
(
m_ptr
);
#if PY_MAJOR_VERSION < 3
PyObject
*
unicode
=
PyUnicode_FromEncodedObject
(
strValue
,
"utf-8"
,
nullptr
);
Py_XDECREF
(
strValue
);
strValue
=
unicode
;
#endif
return
pybind11
::
str
(
strValue
,
false
);
}
inline
pybind11
::
str
handle
::
repr
()
const
{
PyObject
*
strValue
=
PyObject_Repr
(
m_ptr
);
#if PY_MAJOR_VERSION < 3
PyObject
*
unicode
=
PyUnicode_FromEncodedObject
(
strValue
,
"utf-8"
,
nullptr
);
Py_XDECREF
(
strValue
);
strValue
=
unicode
;
#endif
return
pybind11
::
str
(
strValue
,
false
);
}
class
bytes
:
public
object
{
class
bytes
:
public
object
{
public:
public:
PYBIND11_OBJECT_DEFAULT
(
bytes
,
object
,
PYBIND11_BYTES_CHECK
)
PYBIND11_OBJECT_DEFAULT
(
bytes
,
object
,
PYBIND11_BYTES_CHECK
)
...
@@ -691,4 +687,37 @@ inline size_t len(handle h) {
...
@@ -691,4 +687,37 @@ inline size_t len(handle h) {
return
(
size_t
)
result
;
return
(
size_t
)
result
;
}
}
NAMESPACE_BEGIN
(
detail
)
template
<
typename
D
>
iterator
object_api
<
D
>::
begin
()
const
{
return
{
PyObject_GetIter
(
derived
().
ptr
()),
false
};
}
template
<
typename
D
>
iterator
object_api
<
D
>::
end
()
const
{
return
{
nullptr
,
false
};
}
template
<
typename
D
>
accessor
object_api
<
D
>::
operator
[](
handle
key
)
const
{
return
{
derived
(),
key
,
false
};
}
template
<
typename
D
>
accessor
object_api
<
D
>::
operator
[](
const
char
*
key
)
const
{
return
{
derived
(),
key
,
false
};
}
template
<
typename
D
>
accessor
object_api
<
D
>::
attr
(
handle
key
)
const
{
return
{
derived
(),
key
,
true
};
}
template
<
typename
D
>
accessor
object_api
<
D
>::
attr
(
const
char
*
key
)
const
{
return
{
derived
(),
key
,
true
};
}
template
<
typename
D
>
args_proxy
object_api
<
D
>::
operator
*
()
const
{
return
{
derived
().
ptr
()};
}
template
<
typename
D
>
pybind11
::
str
object_api
<
D
>::
str
()
const
{
PyObject
*
str_value
=
PyObject_Str
(
derived
().
ptr
());
#if PY_MAJOR_VERSION < 3
PyObject
*
unicode
=
PyUnicode_FromEncodedObject
(
str_value
,
"utf-8"
,
nullptr
);
Py_XDECREF
(
str_value
);
str_value
=
unicode
;
#endif
return
{
str_value
,
false
};
}
template
<
typename
D
>
pybind11
::
str
object_api
<
D
>::
repr
()
const
{
PyObject
*
str_value
=
PyObject_Repr
(
derived
().
ptr
());
#if PY_MAJOR_VERSION < 3
PyObject
*
unicode
=
PyUnicode_FromEncodedObject
(
str_value
,
"utf-8"
,
nullptr
);
Py_XDECREF
(
str_value
);
str_value
=
unicode
;
#endif
return
{
str_value
,
false
};
}
template
<
typename
D
>
handle
object_api
<
D
>::
get_type
()
const
{
return
(
PyObject
*
)
Py_TYPE
(
derived
().
ptr
());
}
NAMESPACE_END
(
detail
)
NAMESPACE_END
(
pybind11
)
NAMESPACE_END
(
pybind11
)
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