#include <iostream>
#include <tuple>
#include <sstream>
#include <string>
#include <vector>
#include <memory>
//FRAMEWORK - HELPER ETC
template<int ...>
struct seq {};
template<int M, int ...N>
struct genseq : genseq<M-1,M-1, N...> {};
template<int ...N>
struct genseq<0,N...>
{
typedef seq<N...> type;
};
template<typename...args>
struct tuple_maker
{
template<int ...N>
std::tuple<args...> make(std::istream & stream, const seq<N...> &)
{
return std::make_tuple(args(read_arg<N>(stream))...);
}
std::vector<std::string> m_params;
std::vector<std::unique_ptr<std::stringstream>> m_streams;
template<int Index>
std::stringstream & read_arg(std::istream & stream)
{
if ( m_params.empty() )
{
std::string line;
while ( std::getline(stream, line) ) //read all at once!
{
m_params.push_back(line);
}
}
auto pstream = new std::stringstream(m_params.at(Index));
m_streams.push_back(std::unique_ptr<std::stringstream>(pstream));
return *pstream;
}
};
//PARSE FUNCTION
template<typename... args>
std::tuple<args...> parse(std::istream &stream)
{
const int N = sizeof...(args);
return tuple_maker<args...>().make(stream, typename genseq<N>::type() );
}
///TEST CODE
template<int N>
struct A
{
std::string data;
A(std::istream & stream)
{
stream >> data;
}
friend std::ostream& operator << (std::ostream & out, A<N> const & a)
{
return out << "A" << N << "::data = " << a.data ;
}
};
typedef A<1> A1;
typedef A<2> A2;
typedef A<3> A3;
int main()
{
std::stringstream ss("A1\nA2\nA3\n");
auto tuple = parse<A1,A2,A3>(ss);
std::cout << std::get<0>(tuple) << std::endl;
std::cout << std::get<1>(tuple) << std::endl;
std::cout << std::get<2>(tuple) << std::endl;
}
CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPG1lbW9yeT4KCi8vRlJBTUVXT1JLIC0gSEVMUEVSIEVUQwoKCnRlbXBsYXRlPGludCAuLi4+CnN0cnVjdCBzZXEge307Cgp0ZW1wbGF0ZTxpbnQgTSwgaW50IC4uLk4+CnN0cnVjdCBnZW5zZXEgIDogZ2Vuc2VxPE0tMSxNLTEsIE4uLi4+IHt9OwoKdGVtcGxhdGU8aW50IC4uLk4+CnN0cnVjdCBnZW5zZXE8MCxOLi4uPgp7CiAgIHR5cGVkZWYgc2VxPE4uLi4+IHR5cGU7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZS4uLmFyZ3M+CnN0cnVjdCB0dXBsZV9tYWtlcgp7CiAgIHRlbXBsYXRlPGludCAuLi5OPgogICBzdGQ6OnR1cGxlPGFyZ3MuLi4+IG1ha2Uoc3RkOjppc3RyZWFtICYgc3RyZWFtLCBjb25zdCBzZXE8Ti4uLj4gJikKICAgewogICAgIHJldHVybiBzdGQ6Om1ha2VfdHVwbGUoYXJncyhyZWFkX2FyZzxOPihzdHJlYW0pKS4uLik7CiAgIH0KICAgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IG1fcGFyYW1zOwogICBzdGQ6OnZlY3RvcjxzdGQ6OnVuaXF1ZV9wdHI8c3RkOjpzdHJpbmdzdHJlYW0+PiBtX3N0cmVhbXM7CiAgIHRlbXBsYXRlPGludCBJbmRleD4KICAgc3RkOjpzdHJpbmdzdHJlYW0gJiByZWFkX2FyZyhzdGQ6OmlzdHJlYW0gJiBzdHJlYW0pIAogICB7CiAgICAgaWYgKCBtX3BhcmFtcy5lbXB0eSgpICkKICAgICB7CiAgICAgICAgc3RkOjpzdHJpbmcgbGluZTsKICAgICAgICB3aGlsZSAoIHN0ZDo6Z2V0bGluZShzdHJlYW0sIGxpbmUpICkgLy9yZWFkIGFsbCBhdCBvbmNlIQogICAgICAgIHsKICAgICAgICAgICAgICAgIG1fcGFyYW1zLnB1c2hfYmFjayhsaW5lKTsKICAgICAgICB9CiAgICAgfQogICAgIGF1dG8gcHN0cmVhbSA9IG5ldyBzdGQ6OnN0cmluZ3N0cmVhbShtX3BhcmFtcy5hdChJbmRleCkpOwogICAgIG1fc3RyZWFtcy5wdXNoX2JhY2soc3RkOjp1bmlxdWVfcHRyPHN0ZDo6c3RyaW5nc3RyZWFtPihwc3RyZWFtKSk7CiAgICAgcmV0dXJuICpwc3RyZWFtOwogICB9Cn07CgovL1BBUlNFIEZVTkNUSU9OIAp0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBhcmdzPgpzdGQ6OnR1cGxlPGFyZ3MuLi4+IHBhcnNlKHN0ZDo6aXN0cmVhbSAmc3RyZWFtKSAKewogIGNvbnN0IGludCBOID0gc2l6ZW9mLi4uKGFyZ3MpOwogIHJldHVybiB0dXBsZV9tYWtlcjxhcmdzLi4uPigpLm1ha2Uoc3RyZWFtLCB0eXBlbmFtZSBnZW5zZXE8Tj46OnR5cGUoKSApOwp9CgovLy9URVNUIENPREUKCnRlbXBsYXRlPGludCBOPgpzdHJ1Y3QgQSAKewogICAgc3RkOjpzdHJpbmcgZGF0YTsKCUEoc3RkOjppc3RyZWFtICYgc3RyZWFtKSAKCXsKCQlzdHJlYW0gPj4gZGF0YTsKCX0KCWZyaWVuZCBzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yIDw8IChzdGQ6Om9zdHJlYW0gJiBvdXQsIEE8Tj4gY29uc3QgJiBhKQoJewoJCXJldHVybiBvdXQgPDwgIkEiIDw8IE4gPDwgIjo6ZGF0YSA9ICIgPDwgYS5kYXRhIDsKCX0KfTsKdHlwZWRlZiBBPDE+IEExOwp0eXBlZGVmIEE8Mj4gQTI7CnR5cGVkZWYgQTwzPiBBMzsKCmludCBtYWluKCkKewoJc3RkOjpzdHJpbmdzdHJlYW0gc3MoIkExXG5BMlxuQTNcbiIpOwoJYXV0byB0dXBsZSA9IHBhcnNlPEExLEEyLEEzPihzcyk7CglzdGQ6OmNvdXQgPDwgc3RkOjpnZXQ8MD4odHVwbGUpIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCBzdGQ6OmdldDwxPih0dXBsZSkgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8IHN0ZDo6Z2V0PDI+KHR1cGxlKSA8PCBzdGQ6OmVuZGw7Cn0K