-
Notifications
You must be signed in to change notification settings - Fork 574
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
Move const time memory comparison utils to ct_utils.h #3760
Conversation
66de83a
to
64c2903
Compare
64c2903
to
6ecef88
Compare
6ecef88
to
e872668
Compare
/** | ||
* Compare two arrays of equal size and return a Mask indicating if | ||
* they are equal or not. The mask is set if they are identical. | ||
*/ | ||
template <typename T> | ||
inline CT::Mask<T> is_equal(const T x[], const T y[], size_t len) { | ||
volatile T difference = 0; | ||
|
||
for(size_t i = 0; i != len; ++i) { | ||
difference = difference | (x[i] ^ y[i]); | ||
} | ||
|
||
return CT::Mask<T>::is_zero(difference); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be based on ranges, no? Something along these lines, with CT::Mask<>
fairy-dust sprinkled in:
/** | |
* Compare two arrays of equal size and return a Mask indicating if | |
* they are equal or not. The mask is set if they are identical. | |
*/ | |
template <typename T> | |
inline CT::Mask<T> is_equal(const T x[], const T y[], size_t len) { | |
volatile T difference = 0; | |
for(size_t i = 0; i != len; ++i) { | |
difference = difference | (x[i] ^ y[i]); | |
} | |
return CT::Mask<T>::is_zero(difference); | |
} | |
template <std::ranges::contiguous_range X, std::ranges::contiguous_range Y> | |
requires std::same_as<std::ranges::range_value_t<X>, std::ranges::range_value_t<Y>> | |
constexpr auto is_equal(X&& x, Y&& y) | |
{ | |
volatile auto difference = static_cast<std::ranges::range_value_t<X>>(std::ranges::size(x) != std::ranges::size(y)); | |
auto ix = std::ranges::begin(x); | |
auto iy = std::ranges::begin(y); | |
// TODO C++23: std::views::zip(x, y) | |
// future-me, please make sure that zip() is constant-time | |
while(ix != std::ranges::end(x) && iy != std::ranges::end(y)) | |
{ | |
difference |= *ix ^ *iy; | |
++ix; | |
++iy; | |
} | |
return difference; | |
}``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe so. But tbh for this kind of code I like writing things in the most brain-dead way possible because it's usually (fairly) obvious what the compiler is going to do with it.
Some span based overloads here might be nice though. As with #3757 the goal here is primarily to remove usage of functions in mem_ops.h
especially when they were already redundant with other functionality.
No description provided.