#include <iostream>
#include <vector>
template <typename RAI>
std::string string_join(RAI begin, RAI end, std::string delimiter) {
if (begin == end) { return ""; }
std::string joint = std::to_string(*begin);
++begin;
for (; begin != end; begin++) {
joint += delimiter + std::to_string(*begin);
}
return joint;
}
template <int depth>
struct string_join_recursive {
template <typename RAI>
std::string operator()(RAI iterator, RAI end, const std::string *delimiters) const {
if (iterator == end) { return ""; }
std::string joint = string_join_recursive<depth-1>()(std::begin(*iterator), std::end(*iterator), delimiters+1);
for (++iterator; iterator != end; ++iterator) {
joint += *delimiters + string_join_recursive<depth-1>()(std::begin(*iterator), std::end(*iterator), delimiters+1);
}
return joint;
}
};
template <>
struct string_join_recursive<1> {
template <typename RAI>
std::string operator()(RAI iterator, RAI end, const std::string *delimiters) const {
return string_join(iterator, end, *delimiters);
}
};
int main() {
const std::vector<std::vector<std::vector<int>>> v = {{{1, 2, 3}, {4, 5, 6}}, {{7, 8}, {}, {9, 10, 11}}};
const std::string delimiters[3] = {"\n", ";", ","};
std::cout << string_join_recursive<3>()(v.begin(), v.end(), delimiters) << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFJBST4Kc3RkOjpzdHJpbmcgc3RyaW5nX2pvaW4oUkFJIGJlZ2luLCBSQUkgZW5kLCBzdGQ6OnN0cmluZyBkZWxpbWl0ZXIpIHsKICAgIGlmIChiZWdpbiA9PSBlbmQpIHsgcmV0dXJuICIiOyB9CiAgICBzdGQ6OnN0cmluZyBqb2ludCA9IHN0ZDo6dG9fc3RyaW5nKCpiZWdpbik7CiAgICArK2JlZ2luOwogICAgZm9yICg7IGJlZ2luICE9IGVuZDsgYmVnaW4rKykgewogICAgICAgIGpvaW50ICs9IGRlbGltaXRlciArIHN0ZDo6dG9fc3RyaW5nKCpiZWdpbik7CiAgICB9CiAgICByZXR1cm4gam9pbnQ7Cn0KCnRlbXBsYXRlIDxpbnQgZGVwdGg+CnN0cnVjdCBzdHJpbmdfam9pbl9yZWN1cnNpdmUgewogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFJBST4KICAgIHN0ZDo6c3RyaW5nIG9wZXJhdG9yKCkoUkFJIGl0ZXJhdG9yLCBSQUkgZW5kLCBjb25zdCBzdGQ6OnN0cmluZyAqZGVsaW1pdGVycykgY29uc3QgewogICAgICAgIGlmIChpdGVyYXRvciA9PSBlbmQpIHsgcmV0dXJuICIiOyB9CiAgICAgICAgc3RkOjpzdHJpbmcgam9pbnQgPSBzdHJpbmdfam9pbl9yZWN1cnNpdmU8ZGVwdGgtMT4oKShzdGQ6OmJlZ2luKCppdGVyYXRvciksIHN0ZDo6ZW5kKCppdGVyYXRvciksIGRlbGltaXRlcnMrMSk7CiAgICAgICAgZm9yICgrK2l0ZXJhdG9yOyBpdGVyYXRvciAhPSBlbmQ7ICsraXRlcmF0b3IpIHsKICAgICAgICAgICAgam9pbnQgKz0gKmRlbGltaXRlcnMgKyBzdHJpbmdfam9pbl9yZWN1cnNpdmU8ZGVwdGgtMT4oKShzdGQ6OmJlZ2luKCppdGVyYXRvciksIHN0ZDo6ZW5kKCppdGVyYXRvciksIGRlbGltaXRlcnMrMSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBqb2ludDsKICAgIH0KfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCBzdHJpbmdfam9pbl9yZWN1cnNpdmU8MT4gewogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFJBST4KICAgIHN0ZDo6c3RyaW5nIG9wZXJhdG9yKCkoUkFJIGl0ZXJhdG9yLCBSQUkgZW5kLCBjb25zdCBzdGQ6OnN0cmluZyAqZGVsaW1pdGVycykgY29uc3QgewogICAgICAgIHJldHVybiBzdHJpbmdfam9pbihpdGVyYXRvciwgZW5kLCAqZGVsaW1pdGVycyk7CiAgICB9Cn07CgppbnQgbWFpbigpIHsKICAgIGNvbnN0IHN0ZDo6dmVjdG9yPHN0ZDo6dmVjdG9yPHN0ZDo6dmVjdG9yPGludD4+PiB2ID0ge3t7MSwgMiwgM30sIHs0LCA1LCA2fX0sIHt7NywgOH0sIHt9LCB7OSwgMTAsIDExfX19OwogICAgY29uc3Qgc3RkOjpzdHJpbmcgZGVsaW1pdGVyc1szXSA9IHsiXG4iLCAiOyIsICIsIn07CiAgICBzdGQ6OmNvdXQgPDwgc3RyaW5nX2pvaW5fcmVjdXJzaXZlPDM+KCkodi5iZWdpbigpLCB2LmVuZCgpLCBkZWxpbWl0ZXJzKSA8PCBzdGQ6OmVuZGw7Cn0K