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
5699986d
Commit
5699986d
authored
Sep 29, 2016
by
Wenzel Jakob
Committed by
GitHub
Sep 29, 2016
Browse files
Merge pull request #427 from dean0x7d/eigen-bases
Simplify base class detection for Eigen types
parents
88628878
71af3b07
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
28 additions
and
39 deletions
+28
-39
include/pybind11/common.h
include/pybind11/common.h
+15
-0
include/pybind11/eigen.h
include/pybind11/eigen.h
+13
-39
No files found.
include/pybind11/common.h
View file @
5699986d
...
...
@@ -390,6 +390,21 @@ template <template<class> class Predicate, class Default, class... T> using firs
template
<
typename
T
,
typename
...
/*Us*/
>
struct
deferred_type
{
using
type
=
T
;
};
template
<
typename
T
,
typename
...
Us
>
using
deferred_t
=
typename
deferred_type
<
T
,
Us
...
>::
type
;
template
<
template
<
typename
...
>
class
Base
>
struct
is_template_base_of_impl
{
template
<
typename
...
Us
>
static
std
::
true_type
check
(
Base
<
Us
...
>
*
);
static
std
::
false_type
check
(...);
};
/// Check if a template is the base of a type. For example:
/// `is_template_base_of<Base, T>` is true if `struct T : Base<U> {}` where U can be anything
template
<
template
<
typename
...
>
class
Base
,
typename
T
>
#if !defined(_MSC_VER)
using
is_template_base_of
=
decltype
(
is_template_base_of_impl
<
Base
>::
check
((
T
*
)
nullptr
));
#else // MSVC2015 has trouble with decltype in template aliases
struct
is_template_base_of
:
decltype
(
is_template_base_of_impl
<
Base
>::
check
((
T
*
)
nullptr
))
{
};
#endif
/// Ignore that a variable is unused in compiler warnings
inline
void
ignore_unused
(
const
int
*
)
{
}
...
...
include/pybind11/eigen.h
View file @
5699986d
...
...
@@ -34,47 +34,18 @@
NAMESPACE_BEGIN
(
pybind11
)
NAMESPACE_BEGIN
(
detail
)
template
<
typename
T
>
class
is_eigen_dense
{
private:
template
<
typename
Derived
>
static
std
::
true_type
test
(
const
Eigen
::
DenseBase
<
Derived
>
&
);
static
std
::
false_type
test
(...);
public:
static
constexpr
bool
value
=
decltype
(
test
(
std
::
declval
<
T
>
()))
::
value
;
};
// Eigen::Ref<Derived> satisfies is_eigen_dense, but isn't constructible, so it needs a special
// type_caster to handle argument copying/forwarding.
template
<
typename
T
>
class
is_eigen_ref
{
private:
template
<
typename
Derived
>
static
enable_if_t
<
std
::
is_same
<
typename
std
::
remove_const
<
T
>::
type
,
Eigen
::
Ref
<
Derived
>>::
value
,
Derived
>
test
(
const
Eigen
::
Ref
<
Derived
>
&
);
static
void
test
(...);
public:
typedef
decltype
(
test
(
std
::
declval
<
T
>
()))
Derived
;
static
constexpr
bool
value
=
!
std
::
is_void
<
Derived
>::
value
;
};
template
<
typename
T
>
class
is_eigen_sparse
{
private:
template
<
typename
Derived
>
static
std
::
true_type
test
(
const
Eigen
::
SparseMatrixBase
<
Derived
>
&
);
static
std
::
false_type
test
(...);
public:
static
constexpr
bool
value
=
decltype
(
test
(
std
::
declval
<
T
>
()))
::
value
;
};
template
<
typename
T
>
using
is_eigen_dense
=
is_template_base_of
<
Eigen
::
DenseBase
,
T
>
;
template
<
typename
T
>
using
is_eigen_sparse
=
is_template_base_of
<
Eigen
::
SparseMatrixBase
,
T
>
;
template
<
typename
T
>
using
is_eigen_ref
=
is_template_base_of
<
Eigen
::
RefBase
,
T
>
;
// Test for objects inheriting from EigenBase<Derived> that aren't captured by the above. This
// basically covers anything that can be assigned to a dense matrix but that don't have a typical
// matrix data layout that can be copied from their .data(). For example, DiagonalMatrix and
// SelfAdjointView fall into this category.
template
<
typename
T
>
class
is_eigen_base
{
private:
template
<
typename
Derived
>
static
std
::
true_type
test
(
const
Eigen
::
EigenBase
<
Derived
>
&
);
static
std
::
false_type
test
(...);
public:
static
constexpr
bool
value
=
!
is_eigen_dense
<
T
>::
value
&&
!
is_eigen_sparse
<
T
>::
value
&&
decltype
(
test
(
std
::
declval
<
T
>
()))
::
value
;
};
template
<
typename
T
>
using
is_eigen_base
=
bool_constant
<
is_template_base_of
<
Eigen
::
EigenBase
,
T
>::
value
&&
!
is_eigen_dense
<
T
>::
value
&&
!
is_eigen_sparse
<
T
>::
value
>
;
template
<
typename
Type
>
struct
type_caster
<
Type
,
enable_if_t
<
is_eigen_dense
<
Type
>::
value
&&
!
is_eigen_ref
<
Type
>::
value
>>
{
...
...
@@ -159,10 +130,13 @@ protected:
static
PYBIND11_DESCR
cols
()
{
return
_
<
T
::
ColsAtCompileTime
>
();
}
};
template
<
typename
Type
>
struct
type_caster
<
Type
,
enable_if_t
<
is_eigen_dense
<
Type
>::
value
&&
is_eigen_ref
<
Type
>::
value
>>
{
// Eigen::Ref<Derived> satisfies is_eigen_dense, but isn't constructable, so it needs a special
// type_caster to handle argument copying/forwarding.
template
<
typename
CVDerived
,
int
Options
,
typename
StrideType
>
struct
type_caster
<
Eigen
::
Ref
<
CVDerived
,
Options
,
StrideType
>>
{
protected:
using
Derived
=
typename
std
::
remove_const
<
typename
is_eigen_ref
<
Type
>::
Derived
>::
type
;
using
Type
=
Eigen
::
Ref
<
CVDerived
,
Options
,
StrideType
>
;
using
Derived
=
typename
std
::
remove_const
<
CVDerived
>::
type
;
using
DerivedCaster
=
type_caster
<
Derived
>
;
DerivedCaster
derived_caster
;
std
::
unique_ptr
<
Type
>
value
;
...
...
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