Skip to content

Instantly share code, notes, and snippets.

@mobius
Created July 7, 2016 12:51
Show Gist options
  • Save mobius/cdde3bc6c8e902c99ca5e3f3b869602d to your computer and use it in GitHub Desktop.
Save mobius/cdde3bc6c8e902c99ca5e3f3b869602d to your computer and use it in GitHub Desktop.
value_semantics.cxx
#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