#include <iostream>
#include <vector>
#include <memory>
#include <list>
using namespace std;
template <typename T>
struct ref_or_copy
{
ref_or_copy(T&& rval)
: storage(new T(std::move(rval)))
, val(*storage) { }
ref_or_copy(T& lval) : val(lval) { }
std::unique_ptr<T> storage;
T& val;
};
template <typename C1, typename C2>
struct chain_obj_struct {
ref_or_copy<std::remove_reference_t<C1>> c1;
ref_or_copy<std::remove_reference_t<C2>> c2;
struct iterator {
decltype(std::begin(c1.val)) it1;
decltype(std::begin(c1.val)) it1_end;
decltype(std::begin(c2.val)) it2;
bool in_first;
iterator& operator++() {
if (in_first) {
++it1;
if (it1 == it1_end) {
in_first = false;
}
} else {
++it2;
}
return *this;
}
typename std::conditional<
std::is_const<std::remove_reference_t<decltype(*it1)>>::value,
decltype(*it1),
decltype(*it2)>::type
operator*()
{
if (in_first) return *it1;
return *it2;
}
bool operator==(const iterator& i2) {
if (in_first != i2.in_first) return false;
if (in_first)
return it1 == i2.it1;
else
return it2 == i2.it2;
}
bool operator!=(const iterator& i2) {
return !this->operator==(i2);
}
};
iterator begin() {
return iterator{std::begin(c1.val), std::end(c1.val), std::begin(c2.val), true};
}
iterator end() {
return iterator{std::end(c1.val), std::end(c1.val), std::end(c2.val), false};
}
};
template <typename C1, typename C2>
chain_obj_struct<C1, C2> chain_obj(C1&& c1, C2&& c2) {
return chain_obj_struct<C1, C2>{std::forward<C1>(c1), std::forward<C2>(c2)};
}
template <typename C>
auto chain_it(C&& c) { return std::forward<C>(c); }
template <typename C1, typename C2, typename... Cs>
auto chain_it(C1&& c1, C2&& c2)
{
return chain_obj(std::forward<C1>(c1), std::forward<C2>(c2));
}
template <typename C1, typename... Cs>
auto chain_it(C1&& c1, Cs&&... cs)
{
return chain_obj(std::forward<C1>(c1), chain_it(std::forward<Cs>(cs)...));
}
int main() {
vector<int> a = {1, 2, 3, 4};
vector<int> b = {5, 6, 7, 8};
list<int> c = {9, 9, 4};
const auto& ca = a;
const auto& cb = b;
for (auto& i : chain_it(a, cb, ca, b, c)) {
cout << i << " ";
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8bGlzdD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgcmVmX29yX2NvcHkKewoJcmVmX29yX2NvcHkoVCYmIHJ2YWwpIAoJICAgIDogc3RvcmFnZShuZXcgVChzdGQ6Om1vdmUocnZhbCkpKQoJICAgICwgdmFsKCpzdG9yYWdlKSB7IH0KCXJlZl9vcl9jb3B5KFQmIGx2YWwpIDogdmFsKGx2YWwpIHsgfQoKCXN0ZDo6dW5pcXVlX3B0cjxUPiBzdG9yYWdlOwoJVCYgdmFsOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEMxLCB0eXBlbmFtZSBDMj4Kc3RydWN0IGNoYWluX29ial9zdHJ1Y3QgewogIHJlZl9vcl9jb3B5PHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZV90PEMxPj4gYzE7CiAgcmVmX29yX2NvcHk8c3RkOjpyZW1vdmVfcmVmZXJlbmNlX3Q8QzI+PiBjMjsKICBzdHJ1Y3QgaXRlcmF0b3IgewogICAgZGVjbHR5cGUoc3RkOjpiZWdpbihjMS52YWwpKSBpdDE7CiAgCWRlY2x0eXBlKHN0ZDo6YmVnaW4oYzEudmFsKSkgaXQxX2VuZDsKICAgIGRlY2x0eXBlKHN0ZDo6YmVnaW4oYzIudmFsKSkgaXQyOwogICAgYm9vbCBpbl9maXJzdDsKICAgIAogICAgaXRlcmF0b3ImIG9wZXJhdG9yKysoKSB7CiAgICAgIGlmIChpbl9maXJzdCkgewogICAgICAgICsraXQxOwogICAgICAgIGlmIChpdDEgPT0gaXQxX2VuZCkgewogICAgICAgICAgaW5fZmlyc3QgPSBmYWxzZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7IAogICAgICAgICsraXQyOwogICAgICB9CiAgICAgIHJldHVybiAqdGhpczsKICAgIH0KICAgIAogICAgdHlwZW5hbWUgc3RkOjpjb25kaXRpb25hbDwKICAgICAgICBzdGQ6OmlzX2NvbnN0PHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZV90PGRlY2x0eXBlKCppdDEpPj46OnZhbHVlLAogICAgICAgIGRlY2x0eXBlKCppdDEpLAogICAgICAgIGRlY2x0eXBlKCppdDIpPjo6dHlwZQogICAgb3BlcmF0b3IqKCkgCiAgICB7CiAgICAgIGlmIChpbl9maXJzdCkgcmV0dXJuICppdDE7CiAgICAgIHJldHVybiAqaXQyOwogICAgfQoKICAgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBpdGVyYXRvciYgaTIpIHsgCiAgICAgIGlmIChpbl9maXJzdCAhPSBpMi5pbl9maXJzdCkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaW5fZmlyc3QpCiAgICAgICAgcmV0dXJuIGl0MSA9PSBpMi5pdDE7CiAgICAgIGVsc2UKICAgICAgICByZXR1cm4gaXQyID09IGkyLml0MjsKICAgIH0KICAgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBpdGVyYXRvciYgaTIpIHsKICAgIAlyZXR1cm4gIXRoaXMtPm9wZXJhdG9yPT0oaTIpOwogICAgfQogIH07CgogIGl0ZXJhdG9yIGJlZ2luKCkgewogICAgcmV0dXJuIGl0ZXJhdG9ye3N0ZDo6YmVnaW4oYzEudmFsKSwgc3RkOjplbmQoYzEudmFsKSwgc3RkOjpiZWdpbihjMi52YWwpLCB0cnVlfTsKICB9CiAgCiAgaXRlcmF0b3IgZW5kKCkgewogICAgcmV0dXJuIGl0ZXJhdG9ye3N0ZDo6ZW5kKGMxLnZhbCksIHN0ZDo6ZW5kKGMxLnZhbCksIHN0ZDo6ZW5kKGMyLnZhbCksIGZhbHNlfTsKICB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgQzEsIHR5cGVuYW1lIEMyPgpjaGFpbl9vYmpfc3RydWN0PEMxLCBDMj4gY2hhaW5fb2JqKEMxJiYgYzEsIEMyJiYgYzIpIHsKCXJldHVybiBjaGFpbl9vYmpfc3RydWN0PEMxLCBDMj57c3RkOjpmb3J3YXJkPEMxPihjMSksIHN0ZDo6Zm9yd2FyZDxDMj4oYzIpfTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIEM+CmF1dG8gY2hhaW5faXQoQyYmIGMpIHsgcmV0dXJuIHN0ZDo6Zm9yd2FyZDxDPihjKTsgfQoKdGVtcGxhdGUgPHR5cGVuYW1lIEMxLCB0eXBlbmFtZSBDMiwgdHlwZW5hbWUuLi4gQ3M+CmF1dG8gY2hhaW5faXQoQzEmJiBjMSwgQzImJiBjMikKewoJcmV0dXJuIGNoYWluX29iaihzdGQ6OmZvcndhcmQ8QzE+KGMxKSwgc3RkOjpmb3J3YXJkPEMyPihjMikpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgQzEsIHR5cGVuYW1lLi4uIENzPgphdXRvIGNoYWluX2l0KEMxJiYgYzEsIENzJiYuLi4gY3MpCnsKCXJldHVybiBjaGFpbl9vYmooc3RkOjpmb3J3YXJkPEMxPihjMSksIGNoYWluX2l0KHN0ZDo6Zm9yd2FyZDxDcz4oY3MpLi4uKSk7Cn0KCgppbnQgbWFpbigpIHsKCXZlY3RvcjxpbnQ+IGEgPSB7MSwgMiwgMywgNH07Cgl2ZWN0b3I8aW50PiBiID0gezUsIDYsIDcsIDh9OwoJbGlzdDxpbnQ+IGMgPSB7OSwgOSwgNH07Cgljb25zdCBhdXRvJiBjYSA9IGE7Cgljb25zdCBhdXRvJiBjYiA9IGI7Cglmb3IgKGF1dG8mIGkgOiBjaGFpbl9pdChhLCBjYiwgY2EsIGIsIGMpKSB7IAoJCWNvdXQgPDwgaSA8PCAiICI7IAoJfQoJCglyZXR1cm4gMDsKfQ==