-
Notifications
You must be signed in to change notification settings - Fork 216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Defaulting <=> and == where possible (c++20) #478
Comments
Defaulting operator== can make constexpr functions much faster. #include <boost/hana/tuple.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/not_equal.hpp>
#include <boost/hana/less.hpp>
#include <array>
#include <algorithm>
namespace hana = boost::hana;
static constexpr std::size_t inner_size = 1<<6;
static constexpr std::size_t outer_size = 1<<6;
constexpr unsigned fnv_hash(unsigned in) {
constexpr unsigned prime = 16777619;
constexpr unsigned offset_basis = 2166136261;
unsigned out_hash = offset_basis;
for (unsigned i = 0; i < 4; ++i) {
out_hash ^= (in >> (8 * i)) & 0xff;
out_hash *= prime;
}
return out_hash;
}
constexpr auto values = [] {
std::array<std::array<hana::tuple<std::size_t>, inner_size>, outer_size> arr;
for (std::size_t i = 0; i < outer_size; ++i) {
for (std::size_t j = 0; j < inner_size; ++j) {
arr[i][j] = {fnv_hash(j) ^ fnv_hash(i)};
}
}
return arr;
}();
template <std::equality_comparable T, std::size_t inner_size,
std::size_t outer_size>
requires requires (const T& t) {
{ t < t } -> std::convertible_to<bool>;
}
consteval bool all_values_unique(
std::array<std::array<T, inner_size>, outer_size>
values) {
for (std::size_t i = 0; i < values.size(); ++i) {
auto& sub_values = values[i];
#ifdef SORT_IMPL
std::sort(sub_values.begin(), sub_values.end());
auto it = std::unique(sub_values.begin(), sub_values.end());
if(it != sub_values.end()) {
return false;
}
#else
for (std::size_t j = 0; j < sub_values.size(); ++j) {
for (std::size_t k = 0; k < j; ++k) {
if (sub_values[j] == sub_values[k]) {
return false;
}
}
}
#endif
}
return true;
}
// probably all unique for small sizes...
static_assert(all_values_unique(values)); I ran some hacked together benchmarks on my system with hyperfine. My branch with hacked in defaulted operator== and operator<=> for just tuple is here: https://github.com/rgreenblatt/hana/tree/hacky_default_compare Unfortunately, the static assert fails on hacked in operator== with gcc. This seems like a gcc bug. I will look into it later. |
The operators in Boost.Hana alias function objects like Is everything working with your changes? Do all of the tests pass? (ie For compile-time benchmarking, I highly recommend https://github.com/ldionne/metabench. |
Nope. It can't build on clang because clang doesn't have P2002R1 fully implemented which allows for operator{==,<=>} to be declared without constexpr and deduce constexpr. (I was originally testing using just clang and with all of the operators declared constexpr - this breaks if any of the tuple types don't have constexpr compare) On gcc it should theoretically work with all of the operator{==,<=>} not declared constexpr (except the ones which are always constexpr), but there are a few issues:
|
They must always return an object wrapping a constexpr bool convertible to bool. There is also the complication that an implementation of #include <boost/hana/equal.hpp>
#include <boost/hana/tuple.hpp>
#include <boost/hana/ext/std/tuple.hpp>
namespace hana = boost::hana;
static_assert(hana::tuple(1, 2, 3) == std::tuple(1, 2, 3)); |
If there was a three_way_compare.hpp this would reduce compile times and the number of distinct headers which must be included for hana types to be totally ordered (where applicable).
This also could make it possible to default <=> for types that contain hana::tuple.
The text was updated successfully, but these errors were encountered: