#include <functional>
#include <utility>
#include <iterator>
#include <memory>
#include <set>
#include <iostream>
#include <vector>
template<typename T>
struct for_each_helper_interface {
virtual ~for_each_helper_interface() {}
virtual void for_each( std::function< void(T) > const& ) = 0;
};
template<typename C, typename T>
struct for_each_helper:for_each_helper_interface<T> {
C& c;
for_each_helper( C& in ):c(in) {}
virtual void for_each( std::function< void(T) > const& f ) override final {
for( auto&& x:c ) {
f(x);
}
}
};
template<typename T>
struct for_each_adaptor {
std::unique_ptr<for_each_helper_interface<T>> pImpl;
void for_each( std::function< void(T) > const& f ) {
if (pImpl) {
pImpl->for_each(f);
}
}
template<typename C>
for_each_adaptor( C&& c ): pImpl( new for_each_helper<C, T>( std::forward<C>(c) ) ) {}
};
void print_stuff( for_each_adaptor<std::string const&> c ) {
c.for_each([&](std::string const&s){
std::cout << s << "\n";
});
}
int main() {
std::set<std::string> s;
s.insert("hello");
s.insert("world");
print_stuff(s);
std::vector<std::string> v;
v.push_back("hola");
v.push_back("bola");
print_stuff(v);
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxtZW1vcnk+CiNpbmNsdWRlIDxzZXQ+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHZlY3Rvcj4KIAp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3QgZm9yX2VhY2hfaGVscGVyX2ludGVyZmFjZSB7CiAgdmlydHVhbCB+Zm9yX2VhY2hfaGVscGVyX2ludGVyZmFjZSgpIHt9CiAgdmlydHVhbCB2b2lkIGZvcl9lYWNoKCBzdGQ6OmZ1bmN0aW9uPCB2b2lkKFQpID4gY29uc3QmICkgPSAwOwp9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBDLCB0eXBlbmFtZSBUPgpzdHJ1Y3QgZm9yX2VhY2hfaGVscGVyOmZvcl9lYWNoX2hlbHBlcl9pbnRlcmZhY2U8VD4gewogIEMmIGM7CiAgZm9yX2VhY2hfaGVscGVyKCBDJiBpbiApOmMoaW4pIHt9CiAgdmlydHVhbCB2b2lkIGZvcl9lYWNoKCBzdGQ6OmZ1bmN0aW9uPCB2b2lkKFQpID4gY29uc3QmIGYgKSBvdmVycmlkZSBmaW5hbCB7CiAgICBmb3IoIGF1dG8mJiB4OmMgKSB7CiAgICAgIGYoeCk7CiAgICB9CiAgfQp9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3QgZm9yX2VhY2hfYWRhcHRvciB7CiAgc3RkOjp1bmlxdWVfcHRyPGZvcl9lYWNoX2hlbHBlcl9pbnRlcmZhY2U8VD4+IHBJbXBsOwogIHZvaWQgZm9yX2VhY2goIHN0ZDo6ZnVuY3Rpb248IHZvaWQoVCkgPiBjb25zdCYgZiApIHsKICAgIGlmIChwSW1wbCkgewogICAgICBwSW1wbC0+Zm9yX2VhY2goZik7CiAgICB9CiAgfQogIHRlbXBsYXRlPHR5cGVuYW1lIEM+CiAgZm9yX2VhY2hfYWRhcHRvciggQyYmIGMgKTogcEltcGwoIG5ldyBmb3JfZWFjaF9oZWxwZXI8QywgVD4oIHN0ZDo6Zm9yd2FyZDxDPihjKSApICkge30KfTsKdm9pZCBwcmludF9zdHVmZiggZm9yX2VhY2hfYWRhcHRvcjxzdGQ6OnN0cmluZyBjb25zdCY+IGMgKSB7CiAgYy5mb3JfZWFjaChbJl0oc3RkOjpzdHJpbmcgY29uc3Qmcyl7CiAgICBzdGQ6OmNvdXQgPDwgcyA8PCAiXG4iOwogIH0pOwp9CmludCBtYWluKCkgewogIHN0ZDo6c2V0PHN0ZDo6c3RyaW5nPiBzOwogIHMuaW5zZXJ0KCJoZWxsbyIpOwogIHMuaW5zZXJ0KCJ3b3JsZCIpOwogIHByaW50X3N0dWZmKHMpOwogIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiB2OwogIHYucHVzaF9iYWNrKCJob2xhIik7CiAgdi5wdXNoX2JhY2soImJvbGEiKTsKICBwcmludF9zdHVmZih2KTsKfQogCiAKCg==