Last active
January 31, 2020 21:13
-
-
Save tadeu/1c905dfbf04b249ff89dedb4d940c68d to your computer and use it in GitHub Desktop.
Eigen Maze
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <tuple> | |
namespace Eigen { | |
template<typename _Scalar> | |
class Array; | |
template<typename _Scalar> | |
class Matrix; | |
template<typename Derived> struct EigenBase | |
{ | |
Derived& derived() { return *static_cast<Derived*>(this); } | |
const Derived& derived() const { return *static_cast<const Derived*>(this); } | |
}; | |
template<typename Derived, | |
int Level = 0 /*internal::accessors_level<Derived>::value*/ > | |
class DenseCoeffsBase; | |
template<typename Derived> | |
class DenseCoeffsBase<Derived, 0 /*ReadOnlyAccessors*/> | |
: public EigenBase<Derived> | |
{ | |
}; | |
template<typename Derived> class DenseBase | |
: public DenseCoeffsBase<Derived> | |
{ | |
}; | |
template<typename Derived> class MatrixBase | |
: public DenseBase<Derived> | |
{ | |
public: | |
// template <typename OtherDerived> | |
// Derived& operator=(const DenseBase<OtherDerived>& other) | |
// { | |
// } | |
// template <typename OtherDerived> | |
// Derived& operator=(const EigenBase<OtherDerived>& other) | |
// { | |
// } | |
}; | |
template<typename Derived> class ArrayBase | |
: public DenseBase<Derived> | |
{ | |
}; | |
namespace internal { | |
struct MatrixXpr {}; | |
struct ArrayXpr {}; | |
template<typename T> struct traits; | |
template<typename T> struct traits<const T> : traits<T> {}; | |
template<typename _Scalar> | |
struct traits<Matrix<_Scalar> > | |
{ | |
typedef _Scalar Scalar; | |
typedef MatrixXpr XprKind; | |
}; | |
template<typename _Scalar> | |
struct traits<Array<_Scalar> > | |
{ | |
typedef _Scalar Scalar; | |
typedef ArrayXpr XprKind; | |
}; | |
template<typename Derived, typename XprKind = typename traits<Derived>::XprKind> | |
struct dense_xpr_base | |
{ | |
/* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */ | |
}; | |
template<typename Derived> | |
struct dense_xpr_base<Derived, MatrixXpr> | |
{ | |
typedef MatrixBase<Derived> type; | |
}; | |
template<typename Derived> | |
struct dense_xpr_base<Derived, ArrayXpr> | |
{ | |
typedef ArrayBase<Derived> type; | |
}; | |
// ----- | |
template<typename T> struct remove_all { typedef T type; }; | |
template<typename T> struct remove_all<const T> { typedef typename remove_all<T>::type type; }; | |
template<typename T> struct remove_all<T const&> { typedef typename remove_all<T>::type type; }; | |
template<typename T> struct remove_all<T&> { typedef typename remove_all<T>::type type; }; | |
template<typename T> struct remove_all<T const*> { typedef typename remove_all<T>::type type; }; | |
template<typename T> struct remove_all<T*> { typedef typename remove_all<T>::type type; }; | |
// ----- | |
template<typename From, typename To> | |
struct is_convertible_impl | |
{ | |
private: | |
struct any_conversion | |
{ | |
template <typename T> any_conversion(const volatile T&); | |
template <typename T> any_conversion(T&); | |
}; | |
struct yes {int a[1];}; | |
struct no {int a[2];}; | |
static yes test(const To&, int); | |
static no test(any_conversion, ...); | |
public: | |
static From ms_from; | |
enum { value = sizeof(test(ms_from, 0))==sizeof(yes) }; | |
}; | |
template<typename From, typename To> | |
struct is_convertible | |
{ | |
enum { value = is_convertible_impl<typename remove_all<From>::type, | |
typename remove_all<To >::type>::value }; | |
}; | |
// ----- | |
template<bool Condition, typename T=void> struct enable_if; | |
template<typename T> | |
struct enable_if<true, T> | |
{ | |
typedef T type; | |
}; | |
} // namespace Eigen::internal | |
template<typename Derived> | |
class PlainObjectBase : public internal::dense_xpr_base<Derived>::type | |
{ | |
protected: | |
PlainObjectBase() | |
{ | |
} | |
template<typename OtherDerived> | |
PlainObjectBase(const DenseBase<OtherDerived> &other) | |
{ | |
} | |
template<typename OtherDerived> | |
PlainObjectBase(const EigenBase<OtherDerived> &other) | |
{ | |
} | |
}; | |
template<typename _Scalar> | |
class Array | |
: public PlainObjectBase<Array<_Scalar> > | |
{ | |
public: | |
typedef PlainObjectBase<Array> Base; | |
typedef typename Eigen::internal::traits<Array>::Scalar Scalar; | |
private: | |
struct PrivateType {}; | |
public: | |
Array() : Base() | |
{ | |
} | |
Array(Array&& other) | |
: Base(std::move(other)) | |
{ | |
} | |
template<typename T> | |
explicit Array(const T& x) | |
{ | |
} | |
// template<typename OtherDerived> | |
// Array( | |
// const EigenBase<OtherDerived> &other | |
// ) | |
// : Base(other.derived()) | |
// { | |
// } | |
template<typename OtherDerived> | |
Array( | |
const EigenBase<OtherDerived> &other, | |
typename internal::enable_if< | |
internal::is_convertible< | |
typename OtherDerived::Scalar, Scalar | |
>::value, | |
PrivateType | |
>::type = PrivateType() | |
) | |
: Base(other.derived()) | |
{ | |
} | |
}; | |
template<typename _Scalar> | |
class Matrix | |
: public PlainObjectBase<Matrix<_Scalar> > | |
{ | |
public: | |
typedef PlainObjectBase<Matrix> Base; | |
typedef typename Eigen::internal::traits<Matrix>::Scalar Scalar; | |
public: | |
Matrix() : Base() | |
{ | |
} | |
}; | |
} // namespace Eigen | |
double f(Eigen::Array<double> const& x) | |
{ | |
return 0.0; | |
} | |
void test() | |
{ | |
Eigen::Matrix<double> m; | |
// All of these work: | |
// Eigen::EigenBase<Eigen::Matrix<double>> const& b = m; | |
// Eigen::Array<double> a = m; | |
// f(m); | |
// But this doesn't compile: | |
std::apply(f, std::make_tuple(m)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment