store non-nul terminated C string constant in C++ -
before says, "don't bad".
- i understand reasons having nul terminated string.
- i know 1 can state
char mystr[] = { 'm', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g'};however, convenience of c-string representation great.
the rational i'm programming micro-controller , need store data programme's memory. of data in form of bytes, words, dwords , floats. i'd data include strings without nul contiguously.
i've tried templates take <size_t n, char* a> , <size_t n, char (&a)[n]> parameters in order traverse array , store contents static array, can't seem right. think standard may disallow understandable in general case, unfortunate in specific cases (specifically, one. ;) :( )
if remap string boost::mpl::vector_c<char, ...> template, better have other code store properly, dereferencing array within template used const template parameter appears disallowed too.
any ideas?
edit:
psudocode example (this kinda contrived real code larger, wouldn't read byte byte this, nor using literal iterate end of string. embedded in data somewhere.):
// stores bytes in array template<typename x, typename t, t ...numbers> struct x { static progmem volatile const t data[]; }; template<typename x, typename t, t ...numbers> progmem volatile const t x<x, t, numbers...>::data[] = { numbers... }; void main() { // not work, idea have byte 0 1, // byte 1 2 byte 2 3 byte 3 's', byte 4 'o'... // byte 22 'g', byte 23 4, byte 24 5, byte 25 6. typedef x<int, char, 1,2,3,"some embedded string",4,5,6> xx; for(i=0; i<20; ++i) serial.print(pgm_read_byte_near(&xx::data[0] + 3)); } also note not using c++11, c++0x, , possibly extension.
third try
magic , trickery
if using c++11 (i know, in absence think code generation best bet), feels user-defined literal should able handle this. eg, with:
template <char... raw> inline constexpr std::array<char, sizeof...(raw)> operator "" _fixed() { return std::array<char, sizeof...(raw)>{raw...}; } it nice if worked:
const std::array<char, 7> goodbye = goodbye_fixed; ... sadly doesn't (the literal needs numeric, presumably parsing reasons). using "goodbye"_fixed doesn't work either, requires operator "" _fixed(const char *s, int length) overload , compile-time array has decayed pointer again.
eventually come down invoking this:
const auto goodbye = operator "" _fs <'g','o','o','d','b','y','e'>(); and it's no better ugly first version. other ideas?
second try
auto-generate ugliness
i think you're right can't intercept string literal mechanism. honestly, usual approach use build tool generate ugly code in separate file (cf. internationalization libraries, example).
eg, type
fixed_string hello = "hello"; or similar in dedicated file, , build system generates header
const std::array<char, 5> hello; and cpp ugly initialization above below.
first try
missed "looks string literal" requirement
i've tried templates ...
like this?
#include <array> const std::array<char, 5> hello = { 'h', 'e', 'l', 'l', 'o' }; #include <cstdio> int main() { return std::printf("%.*s\n", hello.size(), &hello.front()); } if don't have c++11, boost.array work, or can roll own. note type wrapper around const char[5], should ok go in data segment (i've confirmed goes in .rodata local gcc).
Comments
Post a Comment