1

I'm experimenting with the idea of creating a jump table at compile time that is then used during runtime. It would work something like so:

struct blah { constexpr blah() {} int operator()() const { return 42; }};
int fun(std::string const& str)
{
    return switch_ {
        case_{ "hello"_s, [](){ return 5; }
        case_{ "blah"_s, blah{} }
    }(str);
}

In this case, _s is a constexpr string.

The idea is that this will create a hash table at compile time using a constexpr hash function.

I believe I have solved every issue with exception to one, which if it can't be solves probably makes this idea impossible to implement. That is initialization.

The hash is implemented with an array. Collisions will get placed in empty cells within that array. So then I am required to find a way to store all data types as a single type. Basic type erasure techniques don't appear to work. Also can't use placement new or cast the value into bytes and copy them into an array. Also tried to use a UB invoking union trick that generally would work at runtime but isn't allowed in constexpr context.

The only option that seems to be available is to render a union of sorts that is actually more like a tuple. So it only stores one value but occupies memory of all types in the hash. This doesn't seem good to me.

So, can anyone think of a way to store an arbitrary type into a constexpr generated array?

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
  • I think I've solved the problem I'm trying to solve, in my crazy brain at least. When I get an implementation I'll post. If you're interested in watching it develop check here: https://github.com/crazy-eddie/experiments/constexpr-datastructures. Hasn't yet been imported so for now the link fails, but that's where it'll end up. – Edward Strange Apr 02 '16 at 03:06
  • Make that https://github.com/crazy-eddie/experiments/tree/master/constexpr-datastructures – Edward Strange Apr 02 '16 at 03:56

1 Answers1

0

I don't think there's a general way to solve your problem. But in case of the string literal recently I proposed a (not perfect) way of passing it to template class as parameter you can find it here.

Using this you could create kind of array indexed by the string literal e.g. by specialization:

#include <iostream>
#include <functional>

#include "string_literal.h"

template <class SLiteral>
struct switch_;

template <>
struct switch_<STRING_LITERAL(3, "abc")> {
   int do_something() { return 1; }
};

template <>
struct switch_<STRING_LITERAL(12, "123456789012")> {
   int do_something() { return [](){ return 5;}(); }
};

template <>
struct switch_<STRING_LITERAL(8, "blahblah")> {
   std::function<int()> foo;
   template <class T>
   switch_(T t) {
      foo = t;
   }
   int do_something() { return foo(); }
};

int main() {
   std::cout << switch_<STRING_LITERAL(3, "abc")>().do_something() << std::endl;
   std::cout << switch_<STRING_LITERAL(12, "123456789012")>().do_something() << std::endl;
   std::cout << switch_<STRING_LITERAL(8, "blahblah")>([](){return 10;}).do_something() << std::endl;
}

output of a program is:

1
5
10
Community
  • 1
  • 1
W.F.
  • 13,888
  • 2
  • 34
  • 81
  • I'm narrowing in on a solution. See the comment to my OP. – Edward Strange Apr 02 '16 at 19:25
  • @CrazyEddie I looked through your code. After reading your question and pseudo code I got the impression that you want to implement constexpr map (indexed with the arbitrary constexpr type) rather than the array of constexpr type. Sorry, I've misunderstood your question... – W.F. Apr 02 '16 at 19:56