Yes, this topic may look as asked already a hundred times, but what I am asking is very different.
Please, don't let me be misunderstood: template recursion can be great and the only way for some idioms when used in C++03, but the problem may arise when using in MSVS 2017/2019 compiler and getting the dreadful fatal error C1202: recursive type or function dependency context too complex.
I know that gcc and clang manage much better recursion than MSVS, but this time the compiler is a contractual subject and can not be changed.
I began using boost::hana::string, but with complex strings (over 2000 characters) that error arises.
I wonder if there is some way to replicate the behaviour of BOOST_HANA_STRING macro (basically it takes a string and converts it into a char sequence, or wchar depending of input string) but getting rid of recursion.
I guess that the price to pay is to use C++17 exclusively, by using fold instead, but for me this is affordable.
By the way, please do not provide operator""_cs solutions, due that MSVS is neither compatible with such gcc extension.
Pseudocode of what I want to achieve:
STRING("Hello") => my_static_string<char, 'H', 'e', 'l', 'l', 'o'>
I wonder if there is some way to replicate the behaviour of
BOOST_HANA_STRINGmacro (basically it takes a string and converts it into a char sequence, or wchar depending of input string) but getting rid of recursion.
Well, that's going to be difficult as BOOST_HANA_STRING doesn't use recursion:
namespace string_detail {
template <typename S, std::size_t ...N>
constexpr string<S::get()[N]...>
prepare_impl(S, std::index_sequence<N...>)
{ return {}; }
template <typename S>
constexpr decltype(auto) prepare(S s) {
return prepare_impl(s,
std::make_index_sequence<sizeof(S::get()) - 1>{});
}
}
#define BOOST_HANA_STRING(s) \
(::boost::hana::string_detail::prepare([]{ \
struct tmp { \
static constexpr decltype(auto) get() { return s; } \
}; \
return tmp{}; \
}())) \
Note the lack of recursion. It's just getting the size of the string, using that to build an index sequence, and using that sequence to build a pack expansion over the elements of the string. It's always exactly 2 function calls deep; no more, no less.
Your problem is not recursion; your problem is that Visual Studio does not support "2000" element parameter packs. The C++ standard only recommends that a compiler support 1024 template arguments, and Visual C++ support 2046. I would not bank on this number getting bigger in the future, so you need to find alternate ways of doing whatever it is you're doing here.
Besides, C++20 allows you to create a real compile-time string class that stores an actual array of actual characters that you can actually use in normal, actual code rather than metaprogramming. And they can be used as template parameters; a single template parameter. And VC++ already has support for this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With