First if we want to create a new type for a template parameter we need to create a structural type, this means we cannot use private members or functions.
Our compile time string will contain our string and it will not use new
or delete
, it can be possible to use new
and delete
in a constexpr
function block but in this case we cannot hold dynamic memory in a lifetime constexpr
variable.
I wrote the following template which it holds a fixed string, and can be used with templates as well.
#include <algorithm>
template<std::size_t N>
struct CompTimeStr {
char data[N] {};
consteval CompTimeStr(const char (&str)[N]) {
std::copy_n(str, N, data);
}
consteval bool operator==(const CompTimeStr<N> str) const {
return std::equal(str.data, str.data+N, data);
}
template<std::size_t N2>
consteval bool operator==(const CompTimeStr<N2> s) const {
return false;
}
template<std::size_t N2>
consteval CompTimeStr<N+N2-1> operator+(const CompTimeStr<N2> str) const {
char newchar[N+N2-1] {};
std::copy_n(data, N-1, newchar);
std::copy_n(str.data, N2, newchar+N-1);
return newchar;
}
consteval char operator[](std::size_t n) const {
return data[n];
}
consteval std::size_t size() const {
return N-1;
}
};
template<std::size_t s1, std::size_t s2>
consteval auto operator+(CompTimeStr<s1> fs, const char (&str) [s2]) {
return fs + CompTimeStr<s2>(str);
}
template<std::size_t s1, std::size_t s2>
consteval auto operator+(const char (&str) [s2], CompTimeStr<s1> fs) {
return CompTimeStr<s2>(str) + fs;
}
template<std::size_t s1, std::size_t s2>
consteval auto operator==(CompTimeStr<s1> fs, const char (&str) [s2]) {
return fs == CompTimeStr<s2>(str);
}
template<std::size_t s1, std::size_t s2>
consteval auto operator==(const char (&str) [s2], CompTimeStr<s1> fs) {
return CompTimeStr<s2>(str) == fs;
}
This template will let us to operate over strings at compile time, we can compare and concatenate them at compile time.
Each time we concatenate strings it will return a new CompTimeStr<N>
.
This lets us a world of possibilities, we could even create a search function to find specific words in our string and its position.
Usage example
This is a basic usage of CompTimeStr<N>
#include <iostream>
template<CompTimeStr str>
constexpr auto addBar() {
return str + " bar";
}
constexpr CompTimeStr str = addBar<"foo">();
int main() {
std::cout << str.data << std::endl;
std::cout << std::boolalpha << (str == "foo bar") << std::endl;
}
The output will be:
foo bar
true
If we look at the non-optimized assembly output, we will find this:
We can see foo bar
concatenated at compile time and (str == "foo bar")
condition precalculated as well.
Top comments (1)
Quite a well written article @sgf4
We are in the process of updating some books under our C++ portfolio. Over the next few weeks I am conducting a research in the C++ space to discover the top issues that C++ developers/programmers/experts like yourself are dealing with. We are reaching out to users to understand their needs/expectations and what they are looking for in C++ space.
After reviewing your profile, I believe that you could help me to gain a thorough understanding of what is working and not working for C++ developers like you.
Would you be happy to join me for a 10-minute call to discuss on how we can improvise our C++ books? Your inputs will be critical for us to bring forward a top-notch product for the C++ enthusiasts.