@@ -20,6 +20,28 @@ template <typename T>
2020struct is_eigen
2121 : bool_constant<is_base_pointer_convertible<Eigen::EigenBase, T>::value> {};
2222
23+ namespace internal {
24+ // primary template handles types that have no nested ::type member:
25+ template <class , class = void >
26+ struct has_internal_trait : std::false_type {};
27+
28+ // specialization recognizes types that do have a nested ::type member:
29+ template <class T >
30+ struct has_internal_trait <T,
31+ std::void_t <Eigen::internal::traits<std::decay_t <T>>>>
32+ : std::true_type {};
33+
34+ // primary template handles types that have no nested ::type member:
35+ template <class , class = void >
36+ struct has_scalar_trait : std::false_type {};
37+
38+ // specialization recognizes types that do have a nested ::type member:
39+ template <class T >
40+ struct has_scalar_trait <T, std::void_t <typename std::decay_t <T>::Scalar>>
41+ : std::true_type {};
42+
43+ } // namespace internal
44+
2345/* *
2446 * Template metaprogram defining the base scalar type of
2547 * values stored in an Eigen matrix.
@@ -28,7 +50,9 @@ struct is_eigen
2850 * @ingroup type_trait
2951 */
3052template <typename T>
31- struct scalar_type <T, std::enable_if_t <is_eigen<T>::value>> {
53+ struct scalar_type <T,
54+ std::enable_if_t <is_eigen<T>::value
55+ && internal::has_scalar_trait<T>::value>> {
3256 using type = scalar_type_t <typename std::decay_t <T>::Scalar>;
3357};
3458
@@ -40,10 +64,41 @@ struct scalar_type<T, std::enable_if_t<is_eigen<T>::value>> {
4064 * @ingroup type_trait
4165 */
4266template <typename T>
43- struct value_type <T, std::enable_if_t <is_eigen<T>::value>> {
67+ struct value_type <T,
68+ std::enable_if_t <is_eigen<T>::value
69+ && internal::has_scalar_trait<T>::value>> {
4470 using type = typename std::decay_t <T>::Scalar;
4571};
4672
73+ /* *
74+ * Template metaprogram defining the base scalar type of
75+ * values stored in an Eigen matrix.
76+ *
77+ * @tparam T type to check.
78+ * @ingroup type_trait
79+ */
80+ template <typename T>
81+ struct scalar_type <T,
82+ std::enable_if_t <is_eigen<T>::value
83+ && !internal::has_scalar_trait<T>::value>> {
84+ using type = scalar_type_t <
85+ typename Eigen::internal::traits<std::decay_t <T>>::Scalar>;
86+ };
87+
88+ /* *
89+ * Template metaprogram defining the type of values stored in an
90+ * Eigen matrix, vector, or row vector.
91+ *
92+ * @tparam T type to check
93+ * @ingroup type_trait
94+ */
95+ template <typename T>
96+ struct value_type <T,
97+ std::enable_if_t <is_eigen<T>::value
98+ && !internal::has_scalar_trait<T>::value>> {
99+ using type = typename Eigen::internal::traits<std::decay_t <T>>::Scalar;
100+ };
101+
47102/* ! \ingroup require_eigens_types */
48103/* ! \defgroup eigen_types eigen */
49104/* ! \addtogroup eigen_types */
0 commit comments