I am writing a custom interpreted language, which uses a LIFO-stack for data-manipulation. At two places, I need to be able to construct a tuple from values that are stored on the stack. In principle, this code would look like this:
template<typename... Args>
[[nodiscard]] inline std::tuple<Args...> popTupleFromStack(Stack& stack)
{
return { stack.Pop<Args>()... };
}
However, there is a fundamental problem with the LIFO-ordering of the stack: The initializer-list order dictates that calls happen left-to-right, which means that it would actually try to pop the elements in the completely inverse order. Is there any easy way to inverse this order?
I know that fold-expressions allow you to specify left- or right-folds, but it doesn't seem that you can use fold-expressions when you need to initialize an object with the result.
The closes I've come is manually specifying overloadings for the potential number of arguments in the tuple:
template<typename Arg0>
[[nodiscard]] inline std::tuple<Arg0> popStackTuple(Stack& stack)
{
return { stack.Pop<Arg0>() };
}
template<typename Arg0, typename Arg1>
[[nodiscard]] inline std::tuple<Arg0, Arg1> popStackTuple(Stack& stack)
{
Arg1 arg1 = stack.Pop<Arg1>();
Arg0 arg0 = stack.Pop<Arg0>();
return { arg0, arg1 };
}
But this obviously limits the number of arguments I can support, and/or results in a lot of "unnecessary" code. And it seems like such a minor thing not being able to be done with modern C++ (I have everything up to, including C++20 at my disposal if it makes any difference).