Skip to content

QuasarApp/constexpr-xxh3

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

constexpr-xxh3

This is a C++20 constexpr implementation of the XXH3 64-bit variant of xxHash

Three functions are implemented: XXH3_64bits_const, XXH3_64bits_withSecret_const, XXH3_64bits_withSeed_const.

Also included is a unit test to ensure they produce exactly the same results as the xxHash library.

Credits to:

Usage

Basic interfaces

Basic interfaces mimic upstream interfaces.

  • XXH3_64bits_const(const T* input, size_t len): Hashes a series of bytes
  • XXH3_64bits_withSecret_const(const T* input, size_t len, const S* secret, size_t secretSize): Hashes a series of bytes, using user-provided secret.
  • XXH3_64bits_withSeed_const(const T* input, size_t len, uint64_t seed): Hashes a series of bytes, using user-provided seed.

Types T and S can be any of the following:

  • char
  • signed char (a.k.a. int8_t)
  • unsigned char (a.k.a uint8_t)
  • char8_t
  • std::byte

We are unable to provide a constexpr interface with parameter type const void* because of limitation imposed by the C++ standard, which apparently does not want constexpr evaluation to depend on byte representation. This means that we cannot directly hash, for example, a structure, at compile time, unless we explicitly copy it member-wise to an array of bytes and manually take care of memory layout (including padding) and endianness.

Convenient interfaces

In a constexpr context, it is often more convenient to be able to pass the input bytes and length as one parameter. This is what the convenient interfaces provide:

  • XXH3_64bits_const(const Bytes& input)
  • XXH3_64bits_withSecret_const(const Bytes& input, const Bytes& secret)
  • XXH3_64bits_withSeed_const(const Bytes& input, uint64_t seed)

Bytes can be any of the following types:

  • String literal type, including conventional "string" and UTF-8 u8"string"
  • An object type that is “like” a string or byte array, e.g.:
    • std::string_view
    • std::u8string_view
    • std::span<const char>
    • std::array<char, N>

Note that null bytes embedded in string literals are considered part of the string, e.g. XXH3_64bits_const("a\0b") is equivalent to XXH3_64bits_const("a\0b", 3) rather than XXH3_64bits_const("a", 1).

Unfortunately, we cannot distinguish a string literal from a “real” const char[]. This means the following code snippet hashes 3 bytes instead of 4.

constexpr char bytes[] = {0xff, 0xfc, 0xfb, 0xfa};
constexpr uint64_t hash = XXH3_64bits_const(bytes);

This is unfortunate, but there appears to be no simple way to work it around. For now, we have to use XXH3_64bits_const(bytes, sizeof(bytes)) or XXH3_64bits_const(std::span(bytes)) in this case.

Usage form Cmake

if you want to include this header directly to your project without copy this file, you my add this repository as submodule and include simple static library into your proeject

git submodule add https://github.com/chys87/constexpr-xxh3.git
add_subdirectory(constexpr-xxh3)
target_link_libraries(${PROJECT_NAME} PUBLIC xxh3)
#include <constexpr-xxh3.h>
constexpr hash = XXH3_64bits_const(constexprdataarray);

TODO

Implement the 128-bit version

About

C++ constexpr implementation of XXH3

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • C++ 95.4%
  • Makefile 2.8%
  • CMake 1.8%