Turn C string literal into std::integer_sequence at compile-time with C++17

Viewed 270

Is it possible to write a construct that turns any C string literal "XY..." into a type std::integer_sequence<char, 'X', 'Y', ...> at compile time? I really want a character pack, not a std::array.

Something like

using MyStringType = magic_const_expr("MyString");

A nice approach using the literal operator was demonstrated here but unfortunately it requires a non-standard compiler extension.

1 Answers

Something like this might do it:

template <size_t N, typename F, size_t... indexes>
constexpr auto make_seq_helper(F f, std::index_sequence<indexes...> is) {
    return std::integer_sequence<char, (f()[indexes])...>{};
}

template <typename F>
constexpr auto make_seq(F f) {
    constexpr size_t N = f().size();
    using indexes = std::make_index_sequence<N>;
    return make_seq_helper<N>(f, indexes{});
};


template<const char* str>
struct IntegerSequenceFromString {
    
    private:
    constexpr static auto value = make_seq([](){return std::string_view{str}; });
    
    public:
    using type = decltype(value);
};

Usage would then be:

 constexpr static const char str[] = "lala";
 IntegerSequenceFromString<str>::type i{};

Here is a live example of it working.

I am sure, there is a way to reduce some of this extra stuff as well, but from the assembly, it looks like we don't generate any real runtime variables: https://godbolt.org/z/f65cjGfzn

Related