Spicy
code-formatter.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <functional>
6 #include <optional>
7 #include <string>
8 #include <utility>
9 
10 #include <hilti/base/util.h>
11 
12 namespace hilti {
13 
23 public:
25  explicit CodeFormatter(std::string comment = "//") : _comment(std::move(comment)) {}
26  ~CodeFormatter() = default;
27 
29  bool output(std::ostream& out) { return util::copyStream(_out, out); }
30 
32  auto str() const { return _out.str(); }
33 
35  void next();
36 
38  void separator();
39 
41  void eol();
42 
44  void eos();
45 
47  void quoted(const std::string& s);
48 
50  void comment(const std::string& s);
51 
53  void indent() { _indent += 1; }
54 
56  void dedent() { _indent -= 1; }
57 
59  auto& stream() { return _out; }
60 
62  CodeFormatter& printString(const std::string& s);
63 
64  CodeFormatter(const CodeFormatter&) = delete;
65  CodeFormatter(CodeFormatter&&) = delete;
66  CodeFormatter& operator=(const CodeFormatter& f) = delete;
67  CodeFormatter& operator=(CodeFormatter&& f) = delete;
68 
69 private:
70  std::stringstream _out;
71  std::string _comment;
72 
73  int _indent = 0;
74  bool _did_sep = true;
75  bool _at_bol = true;
76  bool _in_comment = false;
77 };
78 
79 namespace code_formatter {
80 class isManipulator {};
81 } // namespace code_formatter
82 
83 #define __DEFINE_MANIPULATOR0(x) \
84  template<typename Formatter> \
85  class x : isManipulator { \
86  public: \
87  Formatter& operator()(Formatter& f) const { \
88  f.x(); \
89  return f; \
90  } \
91  };
92 
93 #define __DEFINE_MANIPULATOR1(x, t) \
94  template<typename Formatter> \
95  class x : isManipulator { \
96  t _t; \
97  \
98  public: \
99  x(t _t) : _t(std::move(_t)) {} \
100  Formatter& operator()(Formatter& f) const { \
101  f.x(_t); \
102  return f; \
103  } \
104  };
105 
106 namespace code_formatter {
107 __DEFINE_MANIPULATOR0(dedent)
108 __DEFINE_MANIPULATOR0(eol)
109 __DEFINE_MANIPULATOR0(eos)
110 __DEFINE_MANIPULATOR0(indent)
111 __DEFINE_MANIPULATOR0(separator)
112 __DEFINE_MANIPULATOR1(quoted, std::string)
113 __DEFINE_MANIPULATOR1(comment, std::string)
114 } // namespace code_formatter
115 
116 } // namespace hilti
void quoted(const std::string &s)
Definition: code-formatter.cc:40
void comment(const std::string &s)
Definition: code-formatter.cc:45
Definition: optional.h:79
Definition: code-formatter.h:80
void eol()
Definition: code-formatter.cc:27
bool copyStream(std::istream &in, std::ostream &out)
Definition: util.h:582
void dedent()
Definition: code-formatter.h:56
auto & stream()
Definition: code-formatter.h:59
bool output(std::ostream &out)
Definition: code-formatter.h:29
CodeFormatter(std::string comment="//")
Definition: code-formatter.h:25
Definition: code-formatter.h:22
void indent()
Definition: code-formatter.h:53
auto str() const
Definition: code-formatter.h:32
CodeFormatter & printString(const std::string &s)
Definition: code-formatter.cc:55
void next()
Definition: code-formatter.cc:9
void separator()
Definition: code-formatter.cc:17