Search code examples
c++variadic-templatestemplate-meta-programmingconstexpr

How to create a `std::integer_sequence` out of `__func__`?


I'm trying to create a function foobar() that can be used as...

int main()
{
    auto x = foobar(__func__);
    // decltype(x) = std::integer_sequence<char, 'm', 'a', 'i', 'n'>
}

Any hints?

The code does not need to work on MSVC.


Solution

  • Here is the approach that works with GCC and Clang without need for C++20 using the statement expression language extension:

    template<std::size_t n>
    struct helper {
        const char(& s)[n];
        
        constexpr helper(const char(& str)[n]) : s(str)
        {}
        
        template<class Fn, std::size_t... is>
        static constexpr auto apply(Fn fn, std::index_sequence<is...>) {
            return fn(std::integral_constant<std::size_t, is>{}...);
        }
    
        template<class Fn>
        static constexpr auto apply(Fn fn) {
            return apply(fn, std::make_index_sequence<n - 1>{});
        }
    };
    
    
    #define arr_as_char_sequence(ARR)                                         \
        ({ constexpr helper my_helper(ARR); my_helper.apply([](auto... is)    \
              { return std::integer_sequence<char, my_helper.s[is]...>{}; }); });
    
    void foo() {
        auto name = arr_as_char_sequence(__func__);
        static_assert(std::is_same_v<
            decltype(name), std::integer_sequence<char, 'f', 'o', 'o'>>);
    }
    
    

    Demo