Sequoia
Loading...
Searching...
No Matches
Indent.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2020. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
14#include <algorithm>
15#include <string>
16#include <utility>
17
18namespace sequoia
19{
22 {
23 public:
24 using size_type = std::string::size_type;
25
26 indentation() = default;
27
28 explicit indentation(std::string s)
29 : m_Data{std::move(s)}
30 {}
31
32 [[nodiscard]]
33 operator std::string_view() const noexcept
34 {
35 return m_Data;
36 }
37
38 indentation& append(size_type count, char c)
39 {
40 m_Data.append(count, c);
41 return *this;
42 }
43
44 indentation& append(const std::string& s)
45 {
46 m_Data.append(s);
47 return *this;
48 }
49
50 indentation& trim(size_type count)
51 {
52 const auto pos{m_Data.size() - std::ranges::min(count, m_Data.size())};
53 m_Data.erase(pos);
54 return *this;
55 }
56
57 [[nodiscard]]
58 friend indentation operator+(const indentation& lhs, const indentation& rhs)
59 {
60 return indentation{lhs.m_Data + rhs.m_Data};
61 }
62
63 [[nodiscard]]
64 friend bool operator==(const indentation&, const indentation&) noexcept = default;
65 private:
66 std::string m_Data;
67 };
68
69 const indentation tab{"\t"};
70 const indentation no_indent{""};
71
73 [[nodiscard]]
74 std::string indent(std::string_view sv, indentation ind);
75
87 std::string& append_indented(std::string& s1, std::string_view s2, indentation ind);
88
89 [[nodiscard]]
90 std::string append_indented(std::string_view sv1, std::string_view sv2, indentation ind);
91
92 namespace impl
93 {
94 template<class... Ts, std::size_t... I>
95 std::string& append_indented(std::string& s, std::tuple<Ts...> strs, std::index_sequence<I...>)
96 {
97 (append_indented(s, std::get<I>(strs), std::get<sizeof...(Ts) - 1>(strs)), ...);
98 return s;
99 }
100
101 template<class... Ts>
102 std::string& append_indented(std::string& s, const std::tuple<Ts...>& strs)
103 {
104 return append_indented(s, strs, std::make_index_sequence<sizeof...(Ts) - 1>{});
105 }
106
107 template<class... Ts>
108 [[nodiscard]]
109 std::string indent(std::string_view sv, const std::tuple<Ts...>& strs)
110 {
111 auto s{indent(sv, std::get<sizeof...(Ts) - 1>(strs))};
112 return append_indented(s, strs);
113 }
114 }
115
116 template<class... Ts>
117 requires (sizeof...(Ts) > 2)
118 std::string& append_indented(std::string& s, Ts... strs)
119 {
120 return sequoia::impl::append_indented(s, std::tuple<Ts...>{strs...});
121 }
122
123 template<class... Ts>
124 requires (sizeof...(Ts) > 2)
125 [[nodiscard]]
126 std::string append_indented(std::string_view sv, Ts... strs)
127 {
128 std::string str{sv};
129 return append_indented(str, std::forward<Ts>(strs)...);
130 }
131
132 template<class... Ts>
133 requires (sizeof...(Ts) > 1)
134 [[nodiscard]]
135 std::string indent(std::string_view sv, Ts&&... strs)
136 {
137 return sequoia::impl::indent(sv, std::tuple<Ts...>{std::forward<Ts>(strs)...});
138 }
139
140 template<class... Ts>
141 requires (sizeof...(Ts) > 0)
142 std::string& append_lines(std::string& s, Ts&&... strs)
143 {
144 return append_indented(s, std::forward<Ts>(strs)..., no_indent);
145 }
146
147 template<class... Ts>
148 requires (sizeof...(Ts) > 0)
149 [[nodiscard]]
150 std::string append_lines(std::string_view sv, Ts&&... strs)
151 {
152 std::string str{sv};
153 return append_lines(str, std::forward<Ts>(strs)...);
154 }
155
156 std::string& tabs_to_spacing(std::string& text, std::string_view spacing);
157}
std::string indent(std::string_view sv, indentation ind)
For a non-empty string_view prepends with an indentation; otherwise returns an empty string.
Definition: Indent.cpp:16
std::string & append_indented(std::string &s1, std::string_view s2, indentation ind)
Definition: Indent.cpp:44
Type-safe mechanism for indentations.
Definition: Indent.hpp:22