Is it possible to create a user defined literal, which converts string literals to an array of own-type?

Viewed 185

Is it possible to create a user defined literal, which converts string literals to an array of own type?

Suppose that I have an own byte type, mylib::byte:

namespace mylib {
    enum class byte: unsigned char { };
}

So, for example, "Hello"_X should have the type mylib::byte[5], with the value of { 'H', 'e', 'l', 'l', 'o' }.


Here's the background, so maybe you can recommend some other solution.

I have a utf-8 class, which stores a mylib::byte *, and a length (this works like std::string_view, it doesn't own the memory area):

namespace mylib {
    class utf8 {
        const byte *m_string;
        int m_length;
    };
}

I'd like to able to construct mylib::utf8 with string literals in the code conveniently, something like this:

mylib::utf8 u = "Hello";

Currently, I use reinterpret_cast, which is UB:

namespace mylib {
    class utf8 {
        const byte *m_string;
        int m_length;

    public:
        utf8(const byte *s) {
            m_string = s;
            m_length = ...;
        }
        utf8(const char *s) {
            m_string = reinterpret_cast<const byte *>(s); // causes UB afterwards
            m_length = ...;
        }
    };
}

So I thought, I'd like to have something like this, to avoid UB:

mylib::utf8 u = "Hello"_X; // I'd like to have the constructor with `const byte *` to be called here

Note: using mylib::byte is mandatory, I cannot change it.

1 Answers
mylib::utf8 operator "" _X(const char* c, std::size_t n) {
  auto* r = new mylib::byte[n];
  std::transform(c, c+n, r, [](auto c){ return (mylib::byte)(unsigned char)(c););
  return {r,n};
}

this meets all of your criteria as written; you didn't demand zero leaks.

Related