Skip to content

dice-group/dice-hash

Repository files navigation

dice-hash: A Hashing framework

dice-hash provides a framework to generate stable hashes. It provides state-of-the-art hash functions, supports STL containers out of the box and helps you to defines stable hashes for your own structs and classes.

🔋 batteries included: dice-hash defines policies to support different hash algorithms. It comes with predefined policies for three state-of-the-art hash functions:

📦 STL out of the box: dice-hash supports many common STL types already: arithmetic types like bool, int, double, ... etc.; collections like std::unordered_map/set, std::map/set, std::vector, std::tuple, std::pair, std::optional, std::variant, std::array and; all combinations of them.

🔩 extensible: dice-hash supports you with helper functions to define hashes for your own classes. Checkout usage.

Requirements

A C++20 compatible compiler. Code was only tested on x86_64.

Include it into your projects

CMake

conan

To use it with conan you need to add the repository:

conan remote add dice-group https://conan.dice-research.org/artifactory/api/conan/tentris

To use it add dice-hash/0.4.8 to the [requires] section of your conan file.

You can now add it to your target with:

target_link_libraries(your_target
        dice-hash::dice-hash
        )

build and run tests

#get it 
git clone https://github.com/dice-group/dice-hash.git
cd dice-hash
#build it
wget https://github.com/conan-io/cmake-conan/raw/develop2/conan_provider.cmake -O conan_provider.cmake
mkdir build
cd build
cmake -DBUILD_TESTING -DCMAKE_BUILD_TYPE=Release ..  -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=conan_provider.cmake
make -j tests_dice_hash
./test/tests_dice_hash

Note: This example uses conan as dependency provider, other providers are possible. See https://cmake.org/cmake/help/latest/guide/using-dependencies/index.html#dependency-providers

usage

You need to include a single header:

#include <dice/hash.hpp>

The hash is already defined for a lot of common types. In that case you can use the DiceHash just like std::hash.

dice::hash::DiceHash<int> hash;
hash(42);

basicUsage is a run able example for this use-case.

If you need DiceHash to be able to work on your own types, you can specialize the dice::hash::dice_hash_overload template:

struct YourType{};
namespace dice::hash {
    template <typename Policy>
    struct dice_hash_overload<Policy, YourType> {
        static std::size_t dice_hash(YourType const& x) noexcept {
            return 42;
        }
    };
}

Here is an compilable example.

If you want to combine the hash of two or more objects you can use the hash_combine or hash_invertible_combine function. These are part of the Policy, however they can be called via the DiceHash object. An example can be seen here.

If your own type is a container type, there is an easier and faster way to define the hash for you. There are the two typetraits is_ordered_container and is_unordered_container. You just need to set these typetraits for your own type, and the hash will automatically loop over the entries and hash them.

struct YourOwnOrderedContainer{...};
namespace dice::hash {
    template<> struct is_ordered_container<YourOwnOrderedContainer> : std::true_type {};
}

Now you can use DiceHash with your container.

However: Your container needs to have begin, end and size functions. One simple example can be found here.

If you want to use DiceHash in a different structure (like std::unordered_map), you will need to set DiceHash as the correct template parameter. This is one example.