#include<array>
#include<cstddef>
#include<utility>

using namespace std;

template<size_t N> using string_literal_t = char[N];

template<class T> struct StrSize; ///< metafunction to get the size of string literal alikes 

/// specialize StrSize for string literals
template<size_t N>
struct StrSize <string_literal_t<N>>{ static constexpr size_t value = N-1; };

/// template variable, just for convenience
template <class T>
constexpr size_t str_size = StrSize<T>::value;

/// now do the same but with constexpr function
template<class T>
constexpr auto strsize(const T&) noexcept-> decltype(str_size<T>) {
   return str_size<T>;
}

template<class S, size_t... Is>
constexpr auto test_helper(const S& s, index_sequence<Is...>) noexcept-> array<char, str_size<S>> {
   return {s[Is]...};
}

template<class S>
constexpr auto test(const S& s) noexcept-> decltype(auto) {
// return test_helper(s, make_index_sequence<str_size<S>>{}); // this work in both clang and gcc
   return test_helper(s, make_index_sequence<strsize(s)>{});  // this works only in gcc
}

auto main(int argc, char *argv[])-> int {
   static_assert(strsize("qwe") == 3, "");
   static_assert(noexcept(test("qwe")) == true, "");
   
   return 0;
}
