Description
Consider this code godbolt
The codebase is c++17 - so I cannot just default compare operators...
For any adapted struct (in hana (actually boost::hana) way) I have this strange situation when hana::equal
just works for implementing operator==
while hana::less
cannot be used for implementing operator<
. For me documentation is unclear - should it work?
I dig a little into this problem - and it seems that when I call directly hana::less
from operator<
then less
calls operator<
so infinite recursion - so segfault.
While when it is called directly (not via operator<) then it does not compile with a set of static-assert, starting from complaining about adapted struct being not ordered - well...
When I compared sources for equal
and less
- indeed - support for adapted structs is missing in less
.
The code:
#include <boost/hana/adapt_struct.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/less.hpp>
namespace demo
{
struct Some
{
int a;
int b;
};
}
BOOST_HANA_ADAPT_STRUCT(demo::Some,
a, b);
namespace demo
{
bool operator==(const Some& lhs, const Some& rhs)
{
return boost::hana::equal(lhs, rhs);
}
bool less(const Some& lhs, const Some& rhs)
{
return boost::hana::less(lhs, rhs);
}
bool operator<(const Some& lhs, const Some& rhs)
{
// uncommenting boost::hana::less makes this segfault - because operator< calls itself
//return boost::hana::less(lhs, rhs);
return less(lhs, rhs);
}
}
int main() {
return demo::Some{1, 1} < demo::Some{1, 2};
}
The output:
In file included from <source>:3:
/opt/compiler-explorer/libs/boost_1_84_0/boost/hana/less.hpp: In instantiation of 'constexpr auto boost::hana::less_t::operator()(X&&, Y&&) const [with X = const demo::Some&; Y = const demo::Some&]':
<source>:29:29: required from here
/opt/compiler-explorer/libs/boost_1_84_0/boost/hana/less.hpp:51:43: error: static assertion failed: hana::less(x, y) requires 'x' to be Orderable
51 | static_assert(hana::Orderable<T>::value,
| ^~~~~
/opt/compiler-explorer/libs/boost_1_84_0/boost/hana/less.hpp:51:43: note: 'std::integral_constant<bool, false>::value' evaluates to false
/opt/compiler-explorer/libs/boost_1_84_0/boost/hana/less.hpp:54:43: error: static assertion failed: hana::less(x, y) requires 'y' to be Orderable
54 | static_assert(hana::Orderable<U>::value,
| ^~~~~
/opt/compiler-explorer/libs/boost_1_84_0/boost/hana/less.hpp:54:43: note: 'std::integral_constant<bool, false>::value' evaluates to false
/opt/compiler-explorer/libs/boost_1_84_0/boost/hana/less.hpp:57:53: error: static assertion failed: hana::less(x, y) requires 'x' and 'y' to be embeddable in a common Orderable
57 | static_assert(!is_default<less_impl<T, U>>::value,
| ^~~~~
/opt/compiler-explorer/libs/boost_1_84_0/boost/hana/less.hpp:57:53: note: '!(bool)std::integral_constant<bool, true>::value' evaluates to false
/opt/compiler-explorer/libs/boost_1_84_0/boost/hana/less.hpp:62:27: error: use of deleted function 'static constexpr auto boost::hana::deleted_implementation::apply(T&& ...) [with T = {const demo::Some&, const demo::Some&}]'
62 | return Less::apply(static_cast<X&&>(x), static_cast<Y&&>(y));
| ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /opt/compiler-explorer/libs/boost_1_84_0/boost/hana/core/dispatch.hpp:14,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/hana/value.hpp:18,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/hana/concept/constant.hpp:19,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/hana/core/to.hpp:15,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/hana/bool.hpp:17,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/hana/string.hpp:15,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/hana/detail/struct_macros.hpp:28,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/hana/adapt_struct.hpp:15,
from <source>:1:
/opt/compiler-explorer/libs/boost_1_84_0/boost/hana/detail/dispatch_if.hpp:21:31: note: declared here
21 | static constexpr auto apply(T&& ...) = delete;
| ^~~~~
Compiler returned: 1
P.S.
I tried also to use hana::lexicographical_compare- but I did not manage to use it for adapted structs - any help would be welcome. I ended up with using
hana::all_of`...