Skip to content

Instantly share code, notes, and snippets.

@acgetchell
Last active March 21, 2019 07:16
Show Gist options
  • Save acgetchell/7d396f78104d7dc6d81bbd2ec0847cdb to your computer and use it in GitHub Desktop.
Save acgetchell/7d396f78104d7dc6d81bbd2ec0847cdb to your computer and use it in GitHub Desktop.
Command Pattern
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <functional>
struct A {
explicit A() : sum{15} {}
std::vector<int> data{1,2,3,4,5};
void update_sum() {
auto new_sum = 0;
for (auto const& item : data) {
new_sum += item;
}
sum = new_sum;
}
int sum;
friend std::ostream& operator<<(std::ostream& os, A const& result);
};
std::ostream& operator<<(std::ostream& os, A const& result)
{
for (auto& item : result.data) {
os << item << " ";
}
os << " sums to " << result.sum;
return os;
}
template <typename ManifoldType,
typename FunctionType=std::function<ManifoldType(ManifoldType&)>>
class Command
{
public:
explicit Command(ManifoldType& manifold)
: manifold_{std::make_unique<ManifoldType>(manifold)}
{}
/// @return A reference to the manifold
ManifoldType const& get_manifold() const { return *manifold_; }
/// Push a move onto the move queue
void enqueue(FunctionType move) { moves_.emplace_back(move); }
/// Execute move
void execute()
{
auto move = moves_.back();
move(*manifold_);
}
/// The results
[[nodiscard]] auto& get_results() { return *manifold_; }
private:
std::unique_ptr<ManifoldType> manifold_;
std::vector<FunctionType> moves_;
};
A f(A& a){
for (auto& item : a.data) {
item *= 2;
}
return a;
}
A g(A& a){
for (auto& item : a.data) {
item *= 4;
}
return a;
}
int main()
{
A a;
Command<A> command{a};
auto func{f};
command.enqueue(func);
command.execute();
auto b = command.get_results();
std::cout << "The original is " << a << "\n";
b.update_sum();
std::cout << "The result is " << b << "\n";
A c;
Command<A> command2{c};
auto func2 = [](auto& a) -> A {
return g(a);
};
command2.enqueue(func2);
std::cout << "The original is " << command2.get_manifold() << "\n";
command2.execute();
c = command2.get_results();
// Don't update yet
std::cout << "The un-updated result is " << c << "\n";
c.update_sum();
std::cout << "After update: " << c << "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment