boost-ext / ut

C++20 μ(micro)/Unit Testing Framework
https://boost-ext.github.io/ut
Boost Software License 1.0
1.26k stars 120 forks source link

`operators::eq` makes an error when given an raw array #435

Open onihusube opened 3 years ago

onihusube commented 3 years ago
std::string str = "abcd";
ut::expect(ut::eq(str, "abcd"));

Expected Behavior

Test path.

Actual Behavior

Compile error.

prog.cc:20:25: error: cannot initialize an array element of type 'const char' with an lvalue of type 'char const[4]'
      : lhs_{lhs}, rhs_{rhs}, value_{[&] {
                        ^~~

Steps to Reproduce the Problem

Specifications

Cause

If you give eq() a raw array, class detail::eq_ will try to keep the remove_cvrefed value of that type as a member.

The constructor of detail::eq tries to copy the value, but the raw array cannot be copied, so an error is generated.

willwray commented 3 years ago

A UDL, user defined literal, for string literal will be useful for this particular case (once compilers support the new c++20 CNTTP UDL - so far only gcc does).

Adding general support for C array isn't straightforward. P1997, which adds array copy semantics, would help.

It's possible to work around the lack of C array copy semantics here by special-casing; i.e. detect array type and do a copy (the copy should be recursive in case of nested array - std::ranges::copy fails for nested arrays) .

However, the linked issue suggests that the comparison functors probably should not take copies of the arguments.

My c_array_support library aims to extends std facilities to include C array as if it was a regular type. It extends the std comparison functors to compare array in array_compare.hpp and adds generic assign protocol in array_assign.hpp