P4C
The P4 Compiler
Loading...
Searching...
No Matches
indent.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef LIB_INDENT_H_
9#define LIB_INDENT_H_
10
11#include <iomanip>
12#include <iostream>
13#include <vector>
14
15namespace P4 {
16
17class indent_t {
18 int indent;
19
20 public:
21 static int tabsz;
22 indent_t() : indent(0) {}
23 explicit indent_t(int i) : indent(i) {}
24 indent_t &operator++() {
25 ++indent;
26 return *this;
27 }
28 indent_t &operator--() {
29 --indent;
30 return *this;
31 }
32 indent_t operator++(int) {
33 indent_t rv = *this;
34 ++indent;
35 return rv;
36 }
37 indent_t operator--(int) {
38 indent_t rv = *this;
39 --indent;
40 return rv;
41 }
42 friend std::ostream &operator<<(std::ostream &os, indent_t i);
43 indent_t operator+(int v) {
44 indent_t rv = *this;
45 rv.indent += v;
46 return rv;
47 }
48 indent_t operator-(int v) {
49 indent_t rv = *this;
50 rv.indent -= v;
51 return rv;
52 }
53 indent_t &operator+=(int v) {
54 indent += v;
55 return *this;
56 }
57 indent_t &operator-=(int v) {
58 indent -= v;
59 return *this;
60 }
61 static indent_t &getindent(std::ostream &);
62};
63
64inline std::ostream &operator<<(std::ostream &os, indent_t i) {
65 os << std::setw(i.indent * i.tabsz) << "";
66 return os;
67}
68
69namespace IndentCtl {
70inline std::ostream &endl(std::ostream &out) {
71 return out << std::endl << indent_t::getindent(out);
72}
73inline std::ostream &indent(std::ostream &out) {
74 ++indent_t::getindent(out);
75 return out;
76}
77inline std::ostream &unindent(std::ostream &out) {
78 --indent_t::getindent(out);
79 return out;
80}
81
82class TempIndent {
83 // an indent that can be added to any stream and unrolls when the object is destroyed
84 std::vector<std::ostream *> streams; // streams that have been indented
85
86 public:
87 TempIndent(const TempIndent &) = delete; // not copyable
88 TempIndent() = default;
89 friend std::ostream &operator<<(std::ostream &out, TempIndent &ti) {
90 ti.streams.push_back(&out);
91 return out << indent;
92 }
93 friend std::ostream &operator<<(std::ostream &out, TempIndent &&ti) {
94 ti.streams.push_back(&out);
95 return out << indent;
96 }
97 const char *pop_back() {
98 if (!streams.empty()) {
99 *streams.back() << unindent;
100 streams.pop_back();
101 }
102 return "";
103 }
104 const char *reset() {
105 for (auto *out : streams) *out << unindent;
106 streams.clear();
107 return "";
108 }
109 ~TempIndent() {
110 for (auto *out : streams) *out << unindent;
111 }
112};
113
114} // namespace IndentCtl
115} // namespace P4
116
117#endif /* LIB_INDENT_H_ */
Definition indent.h:17
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13