Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hash template metafunction and function

Tags:

c++

c++11

Any computation is possible at compile-time with C++ template metafunctions. Therefore, I was considering, if the following were possible:

void my_function(char const* string_ptr)
{
  switch (hash_function(string_ptr))
  {
    case hash_metafunction<"yoohooo">::value:
      ...
      break;

    case hash_metafunction<"woooooo">::value:
      ...
      break;

    ...
  }
}

Can you give leads as to where to find code (library) for both the hash function and template metafunction. If none such library exists, can you give hints on how I might roll the template metafunction myself? I am particularly worried about the char const* parameter to the template metafunction. Maybe some preprocessor magic is possible?

like image 853
user1095108 Avatar asked Mar 07 '26 03:03

user1095108


1 Answers

How about a constexpr function? Of course implementing that hash could be a pain. You'll have something like this:

// maybe another return type
constexpr uint64_t hash_metafunction(const char* input) {
    // replace some_value with the hash implementation
    return some_value;
}

void my_function(char const* string_ptr)
{
  switch (hash_function(string_ptr))
  {
    case hash_metafunction("yoohooo"):
      ...
      break;

    case hash_metafunction("woooooo"):
      ...
      break;

    ...
  }
}

The hash_metafunction function would be executed on compile-time.

Edit: This is a naive implementation, which basically converts the input string to a uint64_t:

constexpr uint64_t do_the_hash(const char* input, uint64_t value_so_far) {
    return *input ? do_the_hash(input + 1, (value_so_far << 8) | *input) : value_so_far;
}

constexpr uint64_t hash_metafunction(const char* input) {
    return do_the_hash(input, 0);
}

Live demo here.

Edit: I've implemented a compile time MD5, you can find the source code here. In order to use it, do the following:

#include <iostream>
#include "md5.h"

int main() {
    constexpr auto value = ConstexprHashes::md5("constexpr rulz");

    std::cout << std::hex;
    for(auto v : value) {
        if(((size_t)v & 0xff) < 0x10)
            std::cout << '0';
        std::cout << ((size_t)v & 0xff);
    }
    std::cout << std::endl;
}

This prints out the hash: "b8b4e2be16d2b11a5902b80f9c0fe6d6".

like image 57
mfontanini Avatar answered Mar 09 '26 16:03

mfontanini