/src/tomlplusplus/include/toml++/impl/key.hpp
Line | Count | Source |
1 | | //# This file is a part of toml++ and is subject to the the terms of the MIT license. |
2 | | //# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au> |
3 | | //# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. |
4 | | // SPDX-License-Identifier: MIT |
5 | | #pragma once |
6 | | |
7 | | #include "source_region.hpp" |
8 | | #include "std_utility.hpp" |
9 | | #include "print_to_stream.hpp" |
10 | | #include "header_start.hpp" |
11 | | |
12 | | TOML_NAMESPACE_START |
13 | | { |
14 | | /// \brief A key parsed from a TOML document. |
15 | | /// |
16 | | /// \detail These are used as the internal keys for a toml::table: \cpp |
17 | | /// const toml::table tbl = R"( |
18 | | /// a = 1 |
19 | | /// b = 2 |
20 | | /// c = 3 |
21 | | /// )"_toml; |
22 | | /// |
23 | | /// for (auto&& [k, v] : tbl) |
24 | | /// std::cout << "key '"sv << k << "' defined at "sv << k.source() << "\n"; |
25 | | /// \ecpp |
26 | | /// \out |
27 | | /// key 'a' defined at line 2, column 5 |
28 | | /// key 'b' defined at line 3, column 7 |
29 | | /// key 'c' defined at line 4, column 9 |
30 | | /// \eout |
31 | | class key |
32 | | { |
33 | | private: |
34 | | std::string key_; |
35 | | source_region source_; |
36 | | |
37 | | public: |
38 | | /// \brief Default constructor. |
39 | | TOML_NODISCARD_CTOR |
40 | | key() noexcept = default; |
41 | | |
42 | | /// \brief Constructs a key from a string view and source region. |
43 | | TOML_NODISCARD_CTOR |
44 | | explicit key(std::string_view k, source_region&& src = {}) // |
45 | 874k | : key_{ k }, |
46 | 874k | source_{ std::move(src) } |
47 | 874k | {} |
48 | | |
49 | | /// \brief Constructs a key from a string view and source region. |
50 | | TOML_NODISCARD_CTOR |
51 | | explicit key(std::string_view k, const source_region& src) // |
52 | | : key_{ k }, |
53 | | source_{ src } |
54 | 0 | {} |
55 | | |
56 | | /// \brief Constructs a key from a string and source region. |
57 | | TOML_NODISCARD_CTOR |
58 | | explicit key(std::string&& k, source_region&& src = {}) noexcept // |
59 | | : key_{ std::move(k) }, |
60 | | source_{ std::move(src) } |
61 | 0 | {} |
62 | | |
63 | | /// \brief Constructs a key from a string and source region. |
64 | | TOML_NODISCARD_CTOR |
65 | | explicit key(std::string&& k, const source_region& src) noexcept // |
66 | | : key_{ std::move(k) }, |
67 | | source_{ src } |
68 | 0 | {} |
69 | | |
70 | | /// \brief Constructs a key from a c-string and source region. |
71 | | TOML_NODISCARD_CTOR |
72 | | explicit key(const char* k, source_region&& src = {}) // |
73 | | : key_{ k }, |
74 | | source_{ std::move(src) } |
75 | 0 | {} |
76 | | |
77 | | /// \brief Constructs a key from a c-string view and source region. |
78 | | TOML_NODISCARD_CTOR |
79 | | explicit key(const char* k, const source_region& src) // |
80 | | : key_{ k }, |
81 | | source_{ src } |
82 | 0 | {} |
83 | | |
84 | | #if TOML_ENABLE_WINDOWS_COMPAT |
85 | | |
86 | | /// \brief Constructs a key from a wide string view and source region. |
87 | | /// |
88 | | /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled. |
89 | | TOML_NODISCARD_CTOR |
90 | | explicit key(std::wstring_view k, source_region&& src = {}) // |
91 | | : key_{ impl::narrow(k) }, |
92 | | source_{ std::move(src) } |
93 | | {} |
94 | | |
95 | | /// \brief Constructs a key from a wide string and source region. |
96 | | /// |
97 | | /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled. |
98 | | TOML_NODISCARD_CTOR |
99 | | explicit key(std::wstring_view k, const source_region& src) // |
100 | | : key_{ impl::narrow(k) }, |
101 | | source_{ src } |
102 | | {} |
103 | | |
104 | | #endif |
105 | | |
106 | | /// \name String operations |
107 | | /// @{ |
108 | | |
109 | | /// \brief Returns a view of the key's underlying string. |
110 | | TOML_PURE_INLINE_GETTER |
111 | | std::string_view str() const noexcept |
112 | 0 | { |
113 | 0 | return std::string_view{ key_ }; |
114 | 0 | } |
115 | | |
116 | | /// \brief Returns a view of the key's underlying string. |
117 | | TOML_PURE_INLINE_GETTER |
118 | | /*implicit*/ operator std::string_view() const noexcept |
119 | 0 | { |
120 | 0 | return str(); |
121 | 0 | } |
122 | | |
123 | | /// \brief Returns true if the key's underlying string is empty. |
124 | | TOML_PURE_INLINE_GETTER |
125 | | bool empty() const noexcept |
126 | 0 | { |
127 | 0 | return key_.empty(); |
128 | 0 | } |
129 | | |
130 | | /// \brief Returns a pointer to the start of the key's underlying string. |
131 | | TOML_PURE_INLINE_GETTER |
132 | | const char* data() const noexcept |
133 | 0 | { |
134 | 0 | return key_.data(); |
135 | 0 | } |
136 | | |
137 | | /// \brief Returns the length of the key's underlying string. |
138 | | TOML_PURE_INLINE_GETTER |
139 | | size_t length() const noexcept |
140 | 0 | { |
141 | 0 | return key_.length(); |
142 | 0 | } |
143 | | |
144 | | /// @} |
145 | | |
146 | | /// \name Metadata |
147 | | /// @{ |
148 | | |
149 | | /// \brief Returns the source region responsible for specifying this key during parsing. |
150 | | TOML_PURE_INLINE_GETTER |
151 | | const source_region& source() const noexcept |
152 | 643k | { |
153 | 643k | return source_; |
154 | 643k | } |
155 | | |
156 | | /// @} |
157 | | |
158 | | /// \name Equality and Comparison |
159 | | /// \attention These operations only compare the underlying strings; source regions are ignored for the purposes of all comparison! |
160 | | /// @{ |
161 | | |
162 | | /// \brief Returns true if `lhs.str() == rhs.str()`. |
163 | | TOML_PURE_INLINE_GETTER |
164 | | friend bool operator==(const key& lhs, const key& rhs) noexcept |
165 | 0 | { |
166 | 0 | return lhs.key_ == rhs.key_; |
167 | 0 | } |
168 | | |
169 | | /// \brief Returns true if `lhs.str() != rhs.str()`. |
170 | | TOML_PURE_INLINE_GETTER |
171 | | friend bool operator!=(const key& lhs, const key& rhs) noexcept |
172 | 0 | { |
173 | 0 | return lhs.key_ != rhs.key_; |
174 | 0 | } |
175 | | |
176 | | /// \brief Returns true if `lhs.str() < rhs.str()`. |
177 | | TOML_PURE_INLINE_GETTER |
178 | | friend bool operator<(const key& lhs, const key& rhs) noexcept |
179 | 214k | { |
180 | 214k | return lhs.key_ < rhs.key_; |
181 | 214k | } |
182 | | |
183 | | /// \brief Returns true if `lhs.str() <= rhs.str()`. |
184 | | TOML_PURE_INLINE_GETTER |
185 | | friend bool operator<=(const key& lhs, const key& rhs) noexcept |
186 | 0 | { |
187 | 0 | return lhs.key_ <= rhs.key_; |
188 | 0 | } |
189 | | |
190 | | /// \brief Returns true if `lhs.str() > rhs.str()`. |
191 | | TOML_PURE_INLINE_GETTER |
192 | | friend bool operator>(const key& lhs, const key& rhs) noexcept |
193 | 0 | { |
194 | 0 | return lhs.key_ > rhs.key_; |
195 | 0 | } |
196 | | |
197 | | /// \brief Returns true if `lhs.str() >= rhs.str()`. |
198 | | TOML_PURE_INLINE_GETTER |
199 | | friend bool operator>=(const key& lhs, const key& rhs) noexcept |
200 | 0 | { |
201 | 0 | return lhs.key_ >= rhs.key_; |
202 | 0 | } |
203 | | |
204 | | /// \brief Returns true if `lhs.str() == rhs`. |
205 | | TOML_PURE_INLINE_GETTER |
206 | | friend bool operator==(const key& lhs, std::string_view rhs) noexcept |
207 | 409k | { |
208 | 409k | return lhs.key_ == rhs; |
209 | 409k | } |
210 | | |
211 | | /// \brief Returns true if `lhs.str() != rhs`. |
212 | | TOML_PURE_INLINE_GETTER |
213 | | friend bool operator!=(const key& lhs, std::string_view rhs) noexcept |
214 | 0 | { |
215 | 0 | return lhs.key_ != rhs; |
216 | 0 | } |
217 | | |
218 | | /// \brief Returns true if `lhs.str() < rhs`. |
219 | | TOML_PURE_INLINE_GETTER |
220 | | friend bool operator<(const key& lhs, std::string_view rhs) noexcept |
221 | 1.19M | { |
222 | 1.19M | return lhs.key_ < rhs; |
223 | 1.19M | } |
224 | | |
225 | | /// \brief Returns true if `lhs.str() <= rhs`. |
226 | | TOML_PURE_INLINE_GETTER |
227 | | friend bool operator<=(const key& lhs, std::string_view rhs) noexcept |
228 | 0 | { |
229 | 0 | return lhs.key_ <= rhs; |
230 | 0 | } |
231 | | |
232 | | /// \brief Returns true if `lhs.str() > rhs`. |
233 | | TOML_PURE_INLINE_GETTER |
234 | | friend bool operator>(const key& lhs, std::string_view rhs) noexcept |
235 | 0 | { |
236 | 0 | return lhs.key_ > rhs; |
237 | 0 | } |
238 | | |
239 | | /// \brief Returns true if `lhs.str() >= rhs`. |
240 | | TOML_PURE_INLINE_GETTER |
241 | | friend bool operator>=(const key& lhs, std::string_view rhs) noexcept |
242 | 0 | { |
243 | 0 | return lhs.key_ >= rhs; |
244 | 0 | } |
245 | | |
246 | | /// \brief Returns true if `lhs == rhs.str()`. |
247 | | TOML_PURE_INLINE_GETTER |
248 | | friend bool operator==(std::string_view lhs, const key& rhs) noexcept |
249 | 0 | { |
250 | 0 | return lhs == rhs.key_; |
251 | 0 | } |
252 | | |
253 | | /// \brief Returns true if `lhs != rhs.str()`. |
254 | | TOML_PURE_INLINE_GETTER |
255 | | friend bool operator!=(std::string_view lhs, const key& rhs) noexcept |
256 | 0 | { |
257 | 0 | return lhs != rhs.key_; |
258 | 0 | } |
259 | | |
260 | | /// \brief Returns true if `lhs < rhs.str()`. |
261 | | TOML_PURE_INLINE_GETTER |
262 | | friend bool operator<(std::string_view lhs, const key& rhs) noexcept |
263 | 0 | { |
264 | 0 | return lhs < rhs.key_; |
265 | 0 | } |
266 | | |
267 | | /// \brief Returns true if `lhs <= rhs.str()`. |
268 | | TOML_PURE_INLINE_GETTER |
269 | | friend bool operator<=(std::string_view lhs, const key& rhs) noexcept |
270 | 0 | { |
271 | 0 | return lhs <= rhs.key_; |
272 | 0 | } |
273 | | |
274 | | /// \brief Returns true if `lhs > rhs.str()`. |
275 | | TOML_PURE_INLINE_GETTER |
276 | | friend bool operator>(std::string_view lhs, const key& rhs) noexcept |
277 | 0 | { |
278 | 0 | return lhs > rhs.key_; |
279 | 0 | } |
280 | | |
281 | | /// \brief Returns true if `lhs >= rhs.str()`. |
282 | | TOML_PURE_INLINE_GETTER |
283 | | friend bool operator>=(std::string_view lhs, const key& rhs) noexcept |
284 | 0 | { |
285 | 0 | return lhs >= rhs.key_; |
286 | 0 | } |
287 | | |
288 | | /// @} |
289 | | |
290 | | /// \name Iteration |
291 | | /// @{ |
292 | | |
293 | | /// \brief A const iterator for iterating over the characters in the key. |
294 | | using const_iterator = const char*; |
295 | | |
296 | | /// \brief A const iterator for iterating over the characters in the key. |
297 | | using iterator = const_iterator; |
298 | | |
299 | | /// \brief Returns an iterator to the first character in the key's backing string. |
300 | | TOML_PURE_INLINE_GETTER |
301 | | const_iterator begin() const noexcept |
302 | 0 | { |
303 | 0 | return key_.data(); |
304 | 0 | } |
305 | | |
306 | | /// \brief Returns an iterator to one-past-the-last character in the key's backing string. |
307 | | TOML_PURE_INLINE_GETTER |
308 | | const_iterator end() const noexcept |
309 | 0 | { |
310 | 0 | return key_.data() + key_.length(); |
311 | 0 | } |
312 | | |
313 | | /// @} |
314 | | |
315 | | /// \brief Prints the key's underlying string out to the stream. |
316 | | friend std::ostream& operator<<(std::ostream& lhs, const key& rhs) |
317 | 0 | { |
318 | 0 | impl::print_to_stream(lhs, rhs.key_); |
319 | 0 | return lhs; |
320 | 0 | } |
321 | | }; |
322 | | |
323 | | /// \brief Metafunction for determining if a type is, or is a reference to, a toml::key. |
324 | | template <typename T> |
325 | | inline constexpr bool is_key = std::is_same_v<impl::remove_cvref<T>, toml::key>; |
326 | | |
327 | | /// \brief Metafunction for determining if a type is, or is a reference to, a toml::key, |
328 | | /// or is implicitly or explicitly convertible to one. |
329 | | template <typename T> |
330 | | inline constexpr bool is_key_or_convertible = is_key<T> // |
331 | | || impl::is_constructible_or_convertible<toml::key, T>; |
332 | | } |
333 | | TOML_NAMESPACE_END; |
334 | | |
335 | | #include "header_end.hpp" |