#include #include #include #include #include using namespace std; // Pure Element class Element { public: virtual string write() const = 0; virtual ~Element(); }; Element::~Element() {} // Text Element class TextElement : public Element { string text; public: TextElement(const string&); string write() const; operator shared_ptr() const; }; TextElement::TextElement(const string& text) : text(text) {} string TextElement::write() const { return text; } TextElement::operator shared_ptr() const { return make_shared(*this); } // Attribute List class AttributeList : public Element, public unordered_map { public: using unordered_map::unordered_map; string write() const; }; string AttributeList::write() const { string buf; for(const auto& it : *this) { buf += " " + it.first + "=\"" + it.second + "\""; } return buf; } // Html class Html : public Element, public list> { public: using list::list; string write() const; }; string Html::write() const { string buf; for(const auto& it : *this) { buf += it->write(); } return buf; } // Tag class Tag : public Element { public: string tag; AttributeList attr; Html body; Tag(const string&, const Html&); Tag(const string&, const AttributeList&, const Html&); string write() const; operator shared_ptr() const; }; Tag::Tag(const string& tag, const Html& body) : tag(tag), body(body) {} Tag::Tag(const string& tag, const AttributeList& attr, const Html& body) : tag(tag), attr(attr), body(body) {} string Tag::write() const { return string("<") + tag + attr.write() + ">" + body.write() + ""; } Tag::operator shared_ptr() const { return make_shared(*this); } // Tests void speed_test(const Html& html) { for(int i = 0; i < 1000000; i++) { html.write(); } } int main() { Html html {Tag("html", { Tag("head", {Tag("title", {TextElement("Hello, world!")})}), Tag("body", {{"style", "background-color: salmon"}}, { Tag("p", {{"style", "font-family: serif"}}, { TextElement("Hello, "), Tag("i", {TextElement("world")}), TextElement("!")})})})}; speed_test(html); }