-
-
Save afabri/acc723427888dc49c60099bdb6220c53 to your computer and use it in GitHub Desktop.
#include <boost/operators.hpp> | |
#include <boost/multiprecision/cpp_int.hpp> | |
#include <Eigen/Dense> | |
// Quotient | |
template <class NT_> | |
class Toto | |
: boost::additive2 < Toto<NT_>, NT_ > | |
{ | |
public: | |
NT_ num, den; | |
Toto() {} | |
Toto(const NT_& a) {} | |
Toto(const NT_& a, const NT_&b) {} | |
template <class T> | |
Toto operator+=(const T&) { return *this; } | |
}; | |
// Sqrt_extension: | |
template <class NT_> | |
class Toto2 | |
: boost::additive2 < Toto2<NT_>, NT_ > | |
{ | |
public: | |
NT_ num, den; | |
Toto2() {} | |
Toto2(const NT_& nt) | |
{} | |
template <class T> | |
Toto2 operator+=(const T&) { return *this; } | |
}; | |
void toto(Toto<boost::multiprecision::cpp_int>& x) | |
{ | |
x.den; | |
} | |
// No idea if needed | |
namespace Eigen { | |
template<class> struct NumTraits; | |
template<class NT> struct NumTraits<Toto<NT> > | |
{ | |
typedef Toto<NT> Real; | |
typedef Toto<NT> NonInteger; | |
typedef Toto<NT> Nested; | |
typedef Toto<NT> Literal; | |
static inline Real epsilon() { return NumTraits<NT>::epsilon(); } | |
static inline Real dummy_precision() { return NumTraits<NT>::dummy_precision(); } | |
enum { | |
IsInteger = 0, | |
IsSigned = 1, | |
IsComplex = 0, | |
RequireInitialization = NumTraits<NT>::RequireInitialization, | |
ReadCost = 2 * NumTraits<NT>::ReadCost, | |
AddCost = 150, | |
MulCost = 100 | |
}; | |
}; | |
template<class NT> struct NumTraits<Toto2<NT> > | |
{ | |
typedef Toto2<NT> Real; | |
typedef Toto2<NT> NonInteger; | |
typedef Toto2<NT> Nested; | |
typedef Toto2<NT> Literal; | |
static inline Real epsilon() { return NumTraits<NT>::epsilon(); } | |
static inline Real dummy_precision() { return NumTraits<NT>::dummy_precision(); } | |
enum { | |
IsInteger = 0, | |
IsSigned = 1, | |
IsComplex = 0, | |
RequireInitialization = NumTraits<NT>::RequireInitialization, | |
ReadCost = 2 * NumTraits<NT>::ReadCost, | |
AddCost = 150, | |
MulCost = 100 | |
}; | |
}; | |
} | |
int main() { | |
typedef Toto2<int> NT; | |
Eigen::Matrix<NT, 3, 3> m(3, 3); | |
m + m; | |
return 0; | |
} |
With boost 1.79 it works. We would like to also support older boost versions for CGAL users.
BTW I've tried to reproduce this locally, but failed so far.
What version of boost did you use?
I tried several going back to 1.73.
I can reproduce the same errors as @afabri with Boost 1.74, Eigen 3.4 and MSVC 2017.
For consitency of our tests, here is the CMakeLists I am using
cmake_minimum_required(VERSION 3.1...3.23)
project(Number_types_Tests)
find_package(Boost 1.74 REQUIRED)
find_package(Eigen3 3.2.0 REQUIRED)
add_executable(boost-mp-operator-eigen-VC2017bug "boost-mp-operator-eigen-VC2017bug.cpp" )
target_link_libraries(boost-mp-operator-eigen-VC2017bug PUBLIC Eigen3::Eigen)
target_link_libraries(boost-mp-operator-eigen-VC2017bug PUBLIC Boost::boost)
In my tests, the example does not compile with
- Eigen 3.4 and master version
- MSVC 2017, 2019 and 2022 compilers
- boost 1.74
It does compile when I switch to boost 1.80
@sloriot had suggested to git bisect on boost::mp
@jzmaddock could it be a hacky fix to add a specialization of is_byte_container
for Eigen::Matrix
?
typedef Eigen::Matrix<NT, 3, 3>::const_iterator It;
std::cout << typeid(It).name() << std::endl;
The output is void
.
Adding this solves my problem above:
namespace boost {
namespace multiprecision {
namespace detail {
template <class A, int B, int C, int D, int E, int F>
struct is_byte_container< Eigen::Matrix<A,B,C,D,E,F>>
{
static const bool value = false;
};
} } }
In the real code I would also need a specialization for Ref<Eigen::Matrix<..>,..>
, and maybe even more :<
could it be a hacky fix to add a specialization of is_byte_container for Eigen::Matrix ?
It that fixes things, then I don't see why not - it would have to be to your code as a workaround, and you could predicate it on BOOST_VERSION should you wish - that would also protect you from any future changes to is_byte_container
given that it's an implementation detail (not that I'm planning to change it, but you know, 12 months from now I'll probably have forgotten this conversation!).
I added these specializations in CGAL/config.h
I'm fairly sure I remember fixing something around this area, can you please try a more up to date Boost version?
BTW I've tried to reproduce this locally, but failed so far.