#include <iostream>
#include <string>
#include <ostream>
#include <array>
using namespace std;
class Logger{
private:
ostream &m_oss;
public:
Logger(ostream &oss) : m_oss(oss){}
void log(const string &str){
m_oss << str << endl;
}
};
struct IDrawable{
virtual void draw() = 0;
};
struct ILogable{
virtual Logger *logger() const = 0;
virtual void logger(Logger *) = 0;
};
class Shape : IDrawable{
protected:
virtual string info() = 0;
};
class RegisteredShape : public Shape, ILogable{
protected:
Logger *m_logger;
public:
Logger *logger() const{ return m_logger; }
void logger(Logger *l){ m_logger = l; }
void draw(){
m_logger->log("drawing " + info());
}
};
class RegRectangle : public RegisteredShape{
protected:
string info() { return "Rectangle"; }
};
class RegCircle : public RegisteredShape{
protected:
string info() { return "Circle"; }
};
int main(){
Logger l(cout);
array<RegisteredShape *, 2> shapes = {
new RegRectangle(),
new RegCircle()
};
for(auto *shape : shapes){
shape->logger(&l);
shape->draw();
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8b3N0cmVhbT4KI2luY2x1ZGUgPGFycmF5Pgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgTG9nZ2Vyewpwcml2YXRlOgoJb3N0cmVhbSAmbV9vc3M7CnB1YmxpYzoKCUxvZ2dlcihvc3RyZWFtICZvc3MpIDogbV9vc3Mob3NzKXt9Cgl2b2lkIGxvZyhjb25zdCBzdHJpbmcgJnN0cil7CgkJbV9vc3MgPDwgc3RyIDw8IGVuZGw7Cgl9Cn07CgpzdHJ1Y3QgSURyYXdhYmxlewoJdmlydHVhbCB2b2lkIGRyYXcoKSA9IDA7Cn07CgpzdHJ1Y3QgSUxvZ2FibGV7Cgl2aXJ0dWFsIExvZ2dlciAqbG9nZ2VyKCkgY29uc3QgPSAwOwoJdmlydHVhbCB2b2lkIGxvZ2dlcihMb2dnZXIgKikgPSAwOwp9OwoKY2xhc3MgU2hhcGUgOiBJRHJhd2FibGV7CnByb3RlY3RlZDoKCXZpcnR1YWwgc3RyaW5nIGluZm8oKSA9IDA7Cn07CgpjbGFzcyBSZWdpc3RlcmVkU2hhcGUgOiBwdWJsaWMgU2hhcGUsIElMb2dhYmxlewpwcm90ZWN0ZWQ6CglMb2dnZXIgKm1fbG9nZ2VyOwpwdWJsaWM6CglMb2dnZXIgKmxvZ2dlcigpIGNvbnN0eyByZXR1cm4gbV9sb2dnZXI7IH0KCXZvaWQgbG9nZ2VyKExvZ2dlciAqbCl7IG1fbG9nZ2VyID0gbDsgfQoJdm9pZCBkcmF3KCl7CgkJbV9sb2dnZXItPmxvZygiZHJhd2luZyAiICsgaW5mbygpKTsKCX0KfTsKCmNsYXNzIFJlZ1JlY3RhbmdsZSA6IHB1YmxpYyBSZWdpc3RlcmVkU2hhcGV7CnByb3RlY3RlZDoKCXN0cmluZyBpbmZvKCkgeyByZXR1cm4gIlJlY3RhbmdsZSI7IH0KfTsKCmNsYXNzIFJlZ0NpcmNsZSA6IHB1YmxpYyBSZWdpc3RlcmVkU2hhcGV7CnByb3RlY3RlZDoKCXN0cmluZyBpbmZvKCkgeyByZXR1cm4gIkNpcmNsZSI7IH0KfTsKCmludCBtYWluKCl7CglMb2dnZXIgbChjb3V0KTsKCWFycmF5PFJlZ2lzdGVyZWRTaGFwZSAqLCAyPiBzaGFwZXMgPSB7CgkJbmV3IFJlZ1JlY3RhbmdsZSgpLAoJCW5ldyBSZWdDaXJjbGUoKQoJfTsKCQoJZm9yKGF1dG8gKnNoYXBlIDogc2hhcGVzKXsKCQlzaGFwZS0+bG9nZ2VyKCZsKTsKCQlzaGFwZS0+ZHJhdygpOwoJfQoJCglyZXR1cm4gMDsKfQ==