I am writing code for an ARM Cortex. Processor cycles are precious and I am trying to get the most work possible from my compiler. I have many calls to UART_WriteStr(), the majority of which use a string literal.
main() {
...
UART_WriteStr("Initialization complete");
...
}
Currently UART_WriteStr() looks something like this:
void UART_WriteStr(boost::string_view data) {
uint32_t timeout = UINT32_MAX;
for (auto el: data) {
//UART peripheral control logic
}
}
(My ARM compiler can not handle C++17 or above, which is why I am using boost::string_view)
That is pretty nice, string_view takes the pointer and doesn't do any new allocation. But I can see in the assembly for the string_view constructor that it determines the length by iterating over the string looking for a null character. I find that annoying, the compiler knows the length and string_view has a constructor that takes a pointer and length. But how to use that constructor?
I could do this:
int constexpr const_cstr_length(const char* str) {
return *str ? 1 + const_cstr_length(str + 1) : 0;
}
boost::string_view constexpr CCstr(const char * msg) {
return {msg, static_cast<size_t>(const_cstr_length(msg))};
}
main() {
...
UART_WriteStr(CCstr("Initialization complete"));
...
}
But why should I have to decorate my strings with a special function? Why can't I overload UART_WriteStr() to get the behavior I want?
I tried this:
static inline void UART_WriteStr(const char * data) {
UART0_WriteFIFO(boost::string_view(data, const_cstr_length(data)));
}
But data
is no longer constant and const_cstr_length() has devolved into an execution time loop again.
How can I overload UART_WriteStr() in such a way that I can create the boost::string_view from a compile time length? I was on the verge of declaring this impossible due to how C/C++ handle strings in function arguments, but the CCstr() gave me hope that I was wrong.
Another alternative is with template:
template <std::size_t N>
void UART_WriteStr(const char (&data)[N]) {
UART_WriteStr(boost::string_view(data, N - 1));
}
Note: string might contain '\0'
inside it (as ""_bs
solution).