enum class OutputFormat{
  markdown, html
};
struct ListStrategy{
  virtual void start(ostringstream& oss) {}
  virtual void add_list_item(ostringstream& oss, const string& item) {}
  virtual void end(ostringstream& oss) {}
};
struct TextProcessor{
  void append_list(const vector<string> items){
    list_strategy->start(oss);
    for(auto& item: items) list_strategy->add_list_item(oss, item);
    list_strtegy->end(oss);
  }
private:
  ostringstream oss;
  unique_ptr<ListStrategy> list_strategy;
};
struct HtmlListStrategy: ListStrategy{
  void start(ostringstream& oss) override {
    oss<<"<ul>\n";
  }
  
  void end(ostringstream& oss) override {
    oss<<"</ul>\n";
  }
  
  void add_list_item(ostringstream& oss, const string& item) override {
    oss<<"<li>"<<item<<"</li>\n";
  }
};
struct MarkdownListStrategy: ListStrategy{
  void add_list_item(ostringstream& oss, const string& item) override {
    oss<<" * "<<item<<endl;
  }
};
void TextProcessor::set_output_format(const OutputFormat format){
  switch(format){
  case OutputFormat::markdown:
    list_strategy=make_unique<MarkdownListStrategy>();
    break;
  case OutputFormat::html:
    list_strategy=make_unique<HtmlListStrategy>();
  break;
  }
}
TextProcessor tp;
tp.set_output_format(OutputFormat::markdown);
tp.append_list({"foo", "bar", "baz"});
cout<<tp.str()<<endl;
tp.clear();
tp.set_output_format(OutputFormat::Html);
tp.append_list({"foo", "bar", "baz"});
cout<<tp.str()<<endl;