Skip to content

Instantly share code, notes, and snippets.

@oliverepper
Created February 26, 2022 08:35
Show Gist options
  • Save oliverepper/0d810ccc8e7499b7816af44107421e76 to your computer and use it in GitHub Desktop.
Save oliverepper/0d810ccc8e7499b7816af44107421e76 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <vector>
using namespace std;
template<typename T> void draw(const T& x, ostream& out, size_t position);
class object_t {
public:
template<typename T> object_t(T x) : self_(make_unique<model<T>>(move(x))) {}
object_t(const object_t& x) : self_(x.self_->copy_()) { cout << "copy" << endl; }
object_t(object_t&&) = default;
object_t& operator=(const object_t& x) {
return *this = object_t(x);
}
object_t& operator=(object_t&& x) noexcept = default;
friend void draw(const object_t& x, ostream& out, size_t position);
private:
struct concept_t {
virtual ~concept_t() = default;
[[nodiscard]] virtual unique_ptr<concept_t> copy_() const = 0;
virtual void draw_(ostream&, size_t) const = 0;
};
template<typename T> struct model final: concept_t {
explicit model(T x) : data_(move(x)) {}
void draw_(ostream& out, size_t position) const override {
draw(data_, out, position);
}
[[nodiscard]] unique_ptr<concept_t> copy_() const override {
return make_unique<model>(*this);
}
T data_;
};
unique_ptr<concept_t> self_;
};
using document_t = vector<object_t>;
template<typename T> void draw(const T& x, ostream& out, size_t position) {
out << string(position, ' ') << x << endl;
}
void draw(const object_t& x, ostream& out, size_t position) {
x.self_->draw_(out, position);
}
void draw(const document_t& x, ostream& out, size_t position) {
out << string(position, ' ') << "<document>" << endl;
for (const auto& e: x) draw(e, out, position + 2);
out << string(position, ' ') << "</document>" << endl;
}
int main() {
document_t document;
document.emplace_back(1);
document.emplace_back("Zwei");
document.emplace_back(document);
document.emplace_back(3);
draw(document, cout, 0);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment