#include <iostream>
#include <iomanip>
#include <string>
#include <utility>
#include <vector>
#include <set>
using namespace std;
template <class Ostream>
class Writer
{
Ostream &os;
template <class... Any>
void print(Any&&... any)
{
// это "трюк", дающий небольшое удобство:
// возможность писать в print подряд набор значений;
int _[] = { ((*this)(forward<Any>(any)), 0)... };
// ну и маленькая демонстрация variadic templates :)
}
template <class Name, class Lit, class Cont>
void prints
(
const Name &name,
const Cont &cont,
Lit open,
Lit delim,
Lit close
)
{
print(name, open);
auto p = begin(cont), e = end(cont);
if (p != e)
{
print(*p);
while (++p != e)
print(delim, *p);
}
print(close);
}
public:
explicit Writer(Ostream &os)
: os(os) {}
// общий вариант, полагается на оператор <<
template <class Any>
void operator()(const Any &x)
{
os << x;
}
// вариант для строк, берёт содержимое в кавычки
template <class Char, class Traits, class Alloc>
void operator()(const basic_string<Char, Traits, Alloc> &s)
{
os << quoted(s);
}
template <class Name, class Item, class Alloc>
void operator()(const Name &name, const vector<Item, Alloc> &v)
{
prints(name, v, ": [", ", ", "]");
}
template <class Name, class Item, class Comp, class Alloc>
void operator()(const Name &name, const set<Item, Comp, Alloc> &s)
{
prints(name, s, ": {", ", ", "}");
}
// можно продолжить для других контейнеров
};
template <class Ostream>
inline auto make_writer(Ostream &os)
{
return Writer<Ostream>(os);
}
int main()
{
auto writer = make_writer(cout);
vector<int> a { 1, 2, 3, 42 };
set<string> b { "aleph"s, "beth"s, "daleth"s };
writer("vector"s, a);
cout << endl;
writer("set"s, b);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxzZXQ+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgoKdGVtcGxhdGUgPGNsYXNzIE9zdHJlYW0+CmNsYXNzIFdyaXRlcgp7CiAgT3N0cmVhbSAmb3M7CiAgdGVtcGxhdGUgPGNsYXNzLi4uIEFueT4KICB2b2lkIHByaW50KEFueSYmLi4uIGFueSkKICB7CiAgICAvLyDRjdGC0L4gItGC0YDRjtC6Iiwg0LTQsNGO0YnQuNC5INC90LXQsdC+0LvRjNGI0L7QtSDRg9C00L7QsdGB0YLQstC+OgogICAgLy8g0LLQvtC30LzQvtC20L3QvtGB0YLRjCDQv9C40YHQsNGC0Ywg0LIgcHJpbnQg0L/QvtC00YDRj9C0INC90LDQsdC+0YAg0LfQvdCw0YfQtdC90LjQuTsKICAgIGludCBfW10gPSB7ICgoKnRoaXMpKGZvcndhcmQ8QW55PihhbnkpKSwgMCkuLi4gfTsKICAgIC8vINC90YMg0Lgg0LzQsNC70LXQvdGM0LrQsNGPINC00LXQvNC+0L3RgdGC0YDQsNGG0LjRjyB2YXJpYWRpYyB0ZW1wbGF0ZXMgOikKICB9CgogIHRlbXBsYXRlIDxjbGFzcyBOYW1lLCBjbGFzcyBMaXQsIGNsYXNzIENvbnQ+CiAgdm9pZCBwcmludHMKICAoCiAgICBjb25zdCBOYW1lICZuYW1lLAogICAgY29uc3QgQ29udCAmY29udCwgCiAgICBMaXQgb3BlbiwKICAgIExpdCBkZWxpbSwKICAgIExpdCBjbG9zZQogICkKICB7CiAgICBwcmludChuYW1lLCBvcGVuKTsKICAgIGF1dG8gcCA9IGJlZ2luKGNvbnQpLCBlID0gZW5kKGNvbnQpOwogICAgaWYgKHAgIT0gZSkKCXsKICAgICAgcHJpbnQoKnApOwogICAgICB3aGlsZSAoKytwICE9IGUpCiAgICAgICAgcHJpbnQoZGVsaW0sICpwKTsKCX0KICAgIHByaW50KGNsb3NlKTsgICAgCiAgfQogIApwdWJsaWM6CiAgZXhwbGljaXQgV3JpdGVyKE9zdHJlYW0gJm9zKQogICAgICA6IG9zKG9zKSB7fQoKICAvLyDQvtCx0YnQuNC5INCy0LDRgNC40LDQvdGCLCDQv9C+0LvQsNCz0LDQtdGC0YHRjyDQvdCwINC+0L/QtdGA0LDRgtC+0YAgPDwKICB0ZW1wbGF0ZSA8Y2xhc3MgQW55PgogIHZvaWQgb3BlcmF0b3IoKShjb25zdCBBbnkgJngpCiAgewogICAgb3MgPDwgeDsKICB9CgogIC8vINCy0LDRgNC40LDQvdGCINC00LvRjyDRgdGC0YDQvtC6LCDQsdC10YDRkdGCINGB0L7QtNC10YDQttC40LzQvtC1INCyINC60LDQstGL0YfQutC4CiAgdGVtcGxhdGUgPGNsYXNzIENoYXIsIGNsYXNzIFRyYWl0cywgY2xhc3MgQWxsb2M+CiAgdm9pZCBvcGVyYXRvcigpKGNvbnN0IGJhc2ljX3N0cmluZzxDaGFyLCBUcmFpdHMsIEFsbG9jPiAmcykKICB7CiAgICBvcyA8PCBxdW90ZWQocyk7CiAgfQoKICB0ZW1wbGF0ZSA8Y2xhc3MgTmFtZSwgY2xhc3MgSXRlbSwgY2xhc3MgQWxsb2M+CiAgdm9pZCBvcGVyYXRvcigpKGNvbnN0IE5hbWUgJm5hbWUsIGNvbnN0IHZlY3RvcjxJdGVtLCBBbGxvYz4gJnYpCiAgewogICAgcHJpbnRzKG5hbWUsIHYsICI6IFsiLCAiLCAiLCAiXSIpOwogIH0KCiAgdGVtcGxhdGUgPGNsYXNzIE5hbWUsIGNsYXNzIEl0ZW0sIGNsYXNzIENvbXAsIGNsYXNzIEFsbG9jPgogIHZvaWQgb3BlcmF0b3IoKShjb25zdCBOYW1lICZuYW1lLCBjb25zdCBzZXQ8SXRlbSwgQ29tcCwgQWxsb2M+ICZzKQogIHsKICAgIHByaW50cyhuYW1lLCBzLCAiOiB7IiwgIiwgIiwgIn0iKTsKICB9CiAgCiAgLy8g0LzQvtC20L3QviDQv9GA0L7QtNC+0LvQttC40YLRjCDQtNC70Y8g0LTRgNGD0LPQuNGFINC60L7QvdGC0LXQudC90LXRgNC+0LIKfTsKCgp0ZW1wbGF0ZSA8Y2xhc3MgT3N0cmVhbT4KaW5saW5lIGF1dG8gbWFrZV93cml0ZXIoT3N0cmVhbSAmb3MpCnsKICByZXR1cm4gV3JpdGVyPE9zdHJlYW0+KG9zKTsKfQoKCmludCBtYWluKCkKewogIGF1dG8gd3JpdGVyID0gbWFrZV93cml0ZXIoY291dCk7CiAgdmVjdG9yPGludD4gYSB7IDEsIDIsIDMsIDQyIH07CiAgc2V0PHN0cmluZz4gYiB7ICJhbGVwaCJzLCAiYmV0aCJzLCAiZGFsZXRoInMgfTsKICAKICB3cml0ZXIoInZlY3RvciJzLCBhKTsKICBjb3V0IDw8IGVuZGw7CiAgd3JpdGVyKCJzZXQicywgYik7CiAgcmV0dXJuIDA7Cn0K