Created
July 7, 2016 12:51
-
-
Save mobius/cdde3bc6c8e902c99ca5e3f3b869602d to your computer and use it in GitHub Desktop.
value_semantics.cxx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include <iostream> | |
#include <memory> | |
#include <vector> | |
#include <string> | |
#include <algorithm> | |
#include <cassert> | |
#include <chrono> | |
#include <thread> | |
#include <future> | |
using namespace std; | |
template<typename T> | |
void draw(const T& x, ostream& out, size_t position) | |
{ | |
out << string(position, ' ') << x << endl; | |
} | |
class object_t | |
{ | |
public: | |
template<typename T> | |
object_t(T x) : self_(make_shared<model<T>>(move(x))) { /*cout << "ctor 0" << endl; */} | |
// object_t(const object_t& x) : self_(x.self_->copy_()) { /*cout << "ctor 1" << endl;*/ } | |
// object_t(object_t&& x) noexcept = default; | |
// | |
// object_t& operator=(object_t&& x) noexcept = default; | |
// object_t& operator=(const object_t& x) | |
// { | |
// object_t tmp(x); | |
// *this = move(tmp); | |
// return *this; | |
// } | |
friend void draw(const object_t& x, ostream& out, size_t position) | |
{ | |
x.self_->draw_(out, position); | |
} | |
private: | |
struct concept_t | |
{ | |
virtual ~concept_t() = default; | |
//virtual concept_t* copy_() const = 0; | |
virtual void draw_(ostream&, size_t) const = 0; | |
}; | |
template<typename T> | |
struct model : concept_t | |
{ | |
model(T x): data_(move(x)) {} | |
//concept_t* copy_() const { return new model(*this); } | |
void draw_(ostream& out, size_t position) const | |
{ | |
draw(data_, out, position); | |
} | |
T data_; | |
}; | |
shared_ptr<const concept_t> self_; | |
}; | |
struct some_t | |
{ | |
object_t member_; | |
}; | |
some_t func() { return{ 5 }; } | |
using document_t = vector<object_t>; | |
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; | |
} | |
class my_class_t {}; | |
void draw(const my_class_t&, ostream& out, size_t position) | |
{ | |
out << string(position, ' ') << "my_class_t" << endl; | |
} | |
using history_t = vector<document_t>; | |
void commit(history_t& x) { assert(x.size()); x.push_back(x.back()); } | |
void undo(history_t& x) { assert(x.size()); x.pop_back(); } | |
document_t& current(history_t& x) { assert(x.size()); return x.back(); } | |
int main(int argc, char** argv) | |
{ | |
#if 0 | |
document_t document; | |
document.reserve(5); | |
document.emplace_back(0); | |
document.emplace_back("hello world"); | |
document.emplace_back(document); | |
document.emplace_back(my_class_t()); | |
//reverse(document.begin(), document.end()); | |
draw(document, cout, 0); | |
#else | |
history_t h(1); | |
current(h).emplace_back(0); | |
current(h).emplace_back(string("hello")); | |
draw(current(h), cout, 0); | |
cout << "-------------------------------------------" << endl; | |
commit(h); | |
current(h)[0] = 42.5; | |
auto document = current(h); | |
auto saving = async([=]() | |
{ | |
this_thread::sleep_for(chrono::seconds(3)); | |
cout << "------------ 'save' --------------" << endl; | |
draw(document, cout, 0); | |
}); | |
current(h)[1] = string("world"); | |
current(h).emplace_back(current(h)); | |
current(h).emplace_back(my_class_t()); | |
draw(current(h), cout, 0); | |
cout << "-------------------------------------------" << endl; | |
undo(h); | |
draw(current(h), cout, 0); | |
#endif | |
getchar(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment