Skip to content

Instantly share code, notes, and snippets.

@tadeu
Last active January 31, 2020 21:13
Show Gist options
  • Save tadeu/1c905dfbf04b249ff89dedb4d940c68d to your computer and use it in GitHub Desktop.
Save tadeu/1c905dfbf04b249ff89dedb4d940c68d to your computer and use it in GitHub Desktop.
Eigen Maze
#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