Skip to content

Commit 262e238

Browse files
authored
Eigen check for get_member to avoid invocable branch (#1458)
1 parent 87f457b commit 262e238

File tree

4 files changed

+39
-17
lines changed

4 files changed

+39
-17
lines changed

include/glaze/concepts/container_concepts.hpp

+15
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,21 @@ namespace glz
220220
requires !std::same_as<void, decltype(t.end())>;
221221
requires std::input_iterator<decltype(t.begin())>;
222222
};
223+
224+
template <class T>
225+
concept matrix_t = requires(T matrix) {
226+
matrix.resize(2, 4);
227+
matrix.data();
228+
{
229+
matrix.rows()
230+
} -> std::convertible_to<size_t>;
231+
{
232+
matrix.cols()
233+
} -> std::convertible_to<size_t>;
234+
{
235+
matrix.size()
236+
} -> std::convertible_to<size_t>;
237+
} && !range<T>;
223238

224239
// range like
225240
template <class T>

include/glaze/core/common.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,10 @@ namespace glz
422422
else if constexpr (std::is_member_function_pointer_v<V>) {
423423
return element;
424424
}
425-
else if constexpr (std::invocable<Element, Value>) {
425+
else if constexpr (std::invocable<Element, Value> && not matrix_t<Element>) {
426+
// Eigen places a static_assert inside of the operator()(), so we must target
427+
// matrix types and reject them from the invocable check
428+
// Eigen ought to put the check in the `enable_if` for operator()()
426429
return std::invoke(std::forward<Element>(element), std::forward<Value>(value));
427430
}
428431
else if constexpr (std::is_pointer_v<V>) {

include/glaze/ext/eigen.hpp

-15
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,6 @@ namespace glz
2424
{
2525
namespace detail
2626
{
27-
template <class T>
28-
concept matrix_t = requires(T matrix) {
29-
matrix.resize(2, 4);
30-
matrix.data();
31-
{
32-
matrix.rows()
33-
} -> std::convertible_to<size_t>;
34-
{
35-
matrix.cols()
36-
} -> std::convertible_to<size_t>;
37-
{
38-
matrix.size()
39-
} -> std::convertible_to<size_t>;
40-
} && !range<T>;
41-
4227
template <matrix_t T>
4328
requires(T::RowsAtCompileTime >= 0 && T::ColsAtCompileTime >= 0)
4429
struct from<BEVE, T>

tests/eigen_test/eigen_test.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,28 @@
1919
#include "glaze/json/write.hpp"
2020
#include "ut/ut.hpp"
2121

22+
using namespace ut;
23+
24+
struct test_struct
25+
{
26+
Eigen::Matrix3d d = Eigen::Matrix3d::Identity();
27+
} test_value;
28+
29+
suite matrix3d = [] {
30+
"eigen Matrix3d"_test = [] {
31+
auto result = glz::write_json(test_value.d).value();
32+
expect(result == "[1,0,0,0,1,0,0,0,1]") << result;
33+
34+
static_assert(glz::reflect<test_struct>::size == 1);
35+
static_assert(glz::reflect<test_struct>::keys[0] == "d");
36+
37+
result = glz::write_json(test_value).value();
38+
expect(result == R"({"d":[1,0,0,0,1,0,0,0,1]})") << result;
39+
};
40+
};
41+
2242
int main()
2343
{
24-
using namespace ut;
2544
"write_json"_test = [] {
2645
Eigen::Matrix<double, 2, 2> m{};
2746
m << 5, 1, 1, 7;

0 commit comments

Comments
 (0)