My project contains lots of string literals for which I need to store some other properties as well (like a fnv1a hash for example).
- I want these strings (together with other meta information) to be stored as global (const) objects of type
UniqueString
. - I want to inspect the objects using ELF tools, so the constants should be really there
- There should be only one instance per content, even though the same string literal may be used in many places. Some kind of deduplication.
- I want the string literal in the caller location to be optimized away
- It's an embedded project without heap
I tried the following which does obviously not work:
// uniquestring.h
template<char... letters>
struct UniqueString
{
static constexpr size_t length = sizeof...(letters);
static constexpr char storage[length] = {letters...};
// may contain more stuff
};
template<char... letters>
constexpr auto makeUniqueString(const char* string);
template<char... letters>
constexpr auto makeUniqueString(const char* string)
{
switch(string[0]) {
case '\0':
return UniqueString<letters..., '\0'>::storage; // termination
case 'A':
return makeUniqueString<letters..., 'A'>(&string[1]);
// all other letters if necessary
default:
return (const char*)nullptr;
}
}
// file1.cpp
#include "uniquestring.h"
void someFunction() {
// We have only implemented the A case, so let's use a simple string
const char* result = makeUniqueString("AAA");
}
// file2.cpp
#include "uniquestring.h"
void someOtherFunction() {
const char* result = makeUniqueString("AAA");
}
// this should result in one UniqueString type stored as a constant in my application binary.
G++ says fatal error: template instantiation depth exceeds maximum of 900
. Is there a way to achieve my goal?