fork(1) download
  1. #include <iostream>
  2. #include <sstream>
  3.  
  4. struct Statement;
  5. struct Logger;
  6. struct ComponentBase;
  7.  
  8. //------------------------------------------------------------------------------
  9.  
  10. struct ComponentBase {
  11. mutable ComponentBase *next;
  12. ComponentBase() : next(nullptr) { }
  13. virtual std::string toString() = 0;
  14. };
  15.  
  16. template <typename T>
  17. struct Component : ComponentBase {
  18. T value;
  19. Component(T value) : value(value) { }
  20. ~Component() { }
  21. virtual std::string toString() {
  22. std::stringstream ss;
  23. ss << value;
  24. return ss.str();
  25. }
  26. };
  27.  
  28. struct ComponentIterator {
  29. ComponentBase *ptr;
  30. ComponentIterator(ComponentBase *ptr) : ptr(ptr) { }
  31. ComponentBase &operator*() { return *ptr; }
  32. void operator++() { ptr = ptr->next; }
  33. bool operator!=(ComponentIterator &other) { return (ptr != other.ptr); }
  34. };
  35.  
  36. //------------------------------------------------------------------------------
  37.  
  38. struct Statement {
  39. Logger *logger;
  40. ComponentBase *front;
  41. ComponentBase *back;
  42. ComponentIterator begin() { return front; }
  43. ComponentIterator end() { return nullptr; }
  44.  
  45. template <typename T>
  46. Statement(Logger &logger, Component<T> &component)
  47. : logger(&logger), front(&component), back(&component) { }
  48. ~Statement();
  49.  
  50. template <typename T>
  51. Statement &operator<<(Component<T> &&component) {
  52. back->next = &component;
  53. back = &component;
  54. return *this;
  55. }
  56. };
  57.  
  58. //------------------------------------------------------------------------------
  59.  
  60. struct Logger {
  61. template <typename T>
  62. Statement operator<<(Component<T> &&component) {
  63. return {*this, component};
  64. }
  65.  
  66. virtual void log(Statement &statement) = 0;
  67. };
  68.  
  69. Statement::~Statement() {
  70. logger->log(*this);
  71. }
  72.  
  73. //------------------------------------------------------------------------------
  74.  
  75. template <typename T>
  76. Component<T const &> wrap(T const &value) {
  77. return value;
  78. }
  79. template <size_t N>
  80. Component<char const *> wrap(char const (&value)[N]) {
  81. return value;
  82. }
  83.  
  84. //------------------------------------------------------------------------------
  85.  
  86. struct MyLogger : public Logger {
  87. virtual void log(Statement &statement) override {
  88. for(auto &&component : statement) {
  89. std::cout << component.toString();
  90. }
  91. std::cout << std::endl;
  92. }
  93. };
  94.  
  95. int main() {
  96. std::string variable = "string";
  97. MyLogger logger;
  98. logger << wrap("Option ") << wrap(variable) << wrap(" is ") << wrap(42);
  99. }
  100.  
Success #stdin #stdout 0s 3464KB
stdin
Standard input is empty
stdout
Option string is 42