C++ Logo

std-proposals

Advanced search

Re: [std-proposals] consteval hashing of compile-time constant compound literals

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Wed, 15 May 2024 08:21:55 +0100
As Jonathan already pointed out this approach inherently can't deal with padding bits.

I found abseil's way if hash customisation ghe most generic. It allows defining an MD5 (or any stateful) hasher that skips over padding bits, and it should work out of the box with tuple. I don't know if their implementation is constexpr friendly or not, but the approach itself should work in constexpr.
 

On 14 May 2024 23:52:52 BST, Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> wrote:
>I'm experimenting with a consteval implementation of the MD5 hash
>algorithm. I can write a switch statement with compile-time hashes as
>follows:
>
> switch ( md5(some_runtime_value) )
> {
> case md5("dog"): return 1;
> case md5("cat"): return 2;
> case md5("cow"): return 3;
> }
>
>The consteval implementation of 'md5' deals with a consteval array of
>char's -- which is fine when you're hashing strings. It's a little
>more complicated if you want to hash one of the following:
>
> int[3]
> tuple<int,char,bool>
> struct Monkey { int a, b; };
>
>It gets complicated when you want to use std::bit_cast to convert one
>of these three types to an std::array<char,N>, because std::bit_cast
>doesn't yield a compile-time constant if the source type isn't
>trivially copiable. (Most implementations of std::tuple are not
>trivially copiable -- not even when all of the internal types are).
>
>__builtin_bit_cast isn't much better. Nor is __builtin_memcpy.
>
>If I want to hash an array of integers, I can use the following
>consteval function to turn it into a char array:
>
> template<typename T, std::size_t N> requires std::is_integral_v<T>
> constexpr auto FromIntegralArray( T const (&arg)[N] )
> {
> using std::size_t;
> std::array<char, sizeof(arg)> retval{};
> for ( size_t i = 0u; i < sizeof(arg); ++i )
> {
> size_t const a = i / sizeof(T),
> b = i % sizeof(T);
>
> retval[i] = arg[a] >> (CHAR_BIT * b);
> }
> return retval;
> }
>
>But then I would need to (try to) write a function that would work
>with floating points, tuples, and so on.
>
>So is anyone talking about making bit_cast more versatile? Or even
>allowing a consteval memcpy, so we can do this:
>
> template<typename T>
> constexpr auto FromIntegralArray( T const &arg )
> {
> using std::size_t;
> std::array<char, sizeof(arg)> retval{};
> std::memcpy( &retval.front(), &arg, sizeof retval );
> return retval;
> }

Received on 2024-05-15 07:22:03