ipaddress 1.1.0
Loading...
Searching...
No Matches
fixed-string.hpp
Go to the documentation of this file.
1/**
2 * @file fixed-string.hpp
3 * @brief Provides a template for a fixed-length string suitable for use in non-type template parameters
4 * @author Vladimir Shaleev
5 * @copyright MIT License
6 *
7 * This header defines fixed_string, a template class designed to store a string of fixed size.
8 * It is particularly useful in contexts where a constant string is required at compile-time,
9 * such as in template metaprogramming or when specifying non-type template parameters.
10 */
11
12#ifndef IPADDRESS_FIXED_STRING_HPP
13#define IPADDRESS_FIXED_STRING_HPP
14
15#include "config.hpp"
16#include "unicode.hpp"
17
18namespace IPADDRESS_NAMESPACE {
19
20/**
21 * Fixed size string class.
22 *
23 * fixed_string is a template class that encapsulates a string of a fixed number of characters.
24 * It is designed to be used where strings are needed as non-type template parameters.
25 *
26 * @tparam N The maximum number of characters the fixed_string can hold.
27 */
28IPADDRESS_EXPORT template <size_t N>
30 using value_type = char; /**< Type of character in a string. */
31 using const_pointer = const char*; /**< Type of constant pointer to the string data. */
32 using const_reference = const char&; /**< Type of constant reference to a character in the string. */
33 using const_iterator = const_pointer; /**< Type of constant iterator for traversing the string. */
34 using const_reverse_iterator = std::reverse_iterator<const_iterator>; /**< Type of constant reverse iterator for traversing the string in reverse. */
35
36 static constexpr size_t max_length = N;
37
38 size_t length = 0;
39
40 char _data[N] = {};
41
42 /**
43 * Default constructor.
44 *
45 * Constructs a fixed_string with default values, initializing the string with null characters.
46 */
48
49 /**
50 * Constructs a fixed_string from a character array.
51 *
52 * This constructor template initializes a fixed_string with the contents of a given character array.
53 *
54 * @tparam T The character type of the input array.
55 * @param[in] data The character array to initialize the fixed_string with.
56 * @throw parse_error Thrown if contains unexpected characters for addresses
57 */
58 template <typename T>
59 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string(const T (&data)[N + 1]) IPADDRESS_NOEXCEPT(noexcept(internal::char_reader<T>::has_throw())) {
60 const auto begin = &data[0];
61 const auto end = &data[N];
62 auto it = begin;
63 for (size_t i = 0; i < N; ++i) {
64 _data[i] = internal::next_char(it, begin, end);
65 if (_data[i] == '\0') {
66 break;
67 }
68 ++length;
69 }
70 }
71
72 /**
73 * Constructs a fixed_string from a character array.
74 *
75 * This constructor template initializes a fixed_string with the contents of a given character array.
76 *
77 * @tparam T The character type of the input array.
78 * @param[in] data The character array to initialize the fixed_string with.
79 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
80 */
81 template <typename T>
82 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string(const T (&data)[N + 1], error_code& code) IPADDRESS_NOEXCEPT {
83 const auto begin = &data[0];
84 const auto end = &data[N];
85 auto it = begin;
86 uint32_t error_symbol = 0;
87 for (size_t i = 0; i < N; ++i) {
88 _data[i] = internal::next_char_or_error(it, end, code, error_symbol);
89 if (_data[i] == '\0' || code != error_code::no_error) {
90 break;
91 }
92 ++length;
93 }
94 }
95
96 /**
97 * Retrieves the begin iterator of the fixed_string.
98 *
99 * Returns an iterator pointing to the first character of the fixed_string.
100 * If the fixed_string is empty, the returned iterator will be equal to the one returned by end().
101 *
102 * @return A constant iterator to the beginning of the fixed_string.
103 * @sa end()
104 */
105 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator begin() const IPADDRESS_NOEXCEPT {
106 return const_iterator(_data);
107 }
108
109 /**
110 * Retrieves the end iterator of the fixed_string.
111 *
112 * Returns an iterator pointing to the past-the-end character of the fixed_string.
113 * This iterator acts as a placeholder and should not be dereferenced.
114 *
115 * @return A constant iterator to the element following the last character.
116 * @sa begin()
117 */
118 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator end() const IPADDRESS_NOEXCEPT {
119 return const_iterator(_data) + length;
120 }
121
122 /**
123 * Retrieves the reverse begin iterator of the fixed_string.
124 *
125 * Returns a reverse iterator pointing to the last character of the fixed_string.
126 * If the fixed_string is empty, the returned iterator will be equal to rend().
127 *
128 * @return A constant reverse iterator to the beginning of the reversed fixed_string.
129 * @sa rend()
130 */
131 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR_17 IPADDRESS_FORCE_INLINE const_reverse_iterator rbegin() const IPADDRESS_NOEXCEPT {
132 return const_reverse_iterator(end());
133 }
134
135 /**
136 * Retrieves the reverse end iterator of the fixed_string.
137 *
138 * Returns a reverse iterator pointing to the position preceding the first character of the fixed_string.
139 * This iterator acts as a placeholder and should not be dereferenced.
140 *
141 * @return A constant reverse iterator to the end of the reversed fixed_string.
142 * @sa rbegin()
143 */
144 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR_17 IPADDRESS_FORCE_INLINE const_reverse_iterator rend() const IPADDRESS_NOEXCEPT {
145 return const_reverse_iterator(begin());
146 }
147
148 /**
149 * Retrieves the constant begin iterator of the fixed_string.
150 *
151 * Returns a constant iterator pointing to the first character of the fixed_string.
152 * If the fixed_string is empty, the returned iterator will be equal to cend().
153 *
154 * @return A constant iterator to the beginning of the fixed_string.
155 * @sa cend()
156 */
157 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator cbegin() const IPADDRESS_NOEXCEPT {
158 return begin();
159 }
160
161 /**
162 * Retrieves the constant end iterator of the fixed_string.
163 *
164 * Returns a constant iterator pointing to the past-the-end character of the fixed_string.
165 * This iterator acts as a placeholder and should not be dereferenced.
166 *
167 * @return A constant iterator to the end of the fixed_string.
168 * @sa cbegin()
169 */
170 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator cend() const IPADDRESS_NOEXCEPT {
171 return end();
172 }
173
174 /**
175 * Retrieves the constant reverse begin iterator of the fixed_string.
176 *
177 * Returns a constant reverse iterator pointing to the last character of the fixed_string.
178 * If the fixed_string is empty, the returned iterator will be equal to crend().
179 *
180 * @return A constant reverse iterator to the beginning of the reversed fixed_string.
181 * @sa crend()
182 */
183 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR_17 IPADDRESS_FORCE_INLINE const_reverse_iterator crbegin() const IPADDRESS_NOEXCEPT {
184 return const_reverse_iterator(cend());
185 }
186
187 /**
188 * Retrieves the constant reverse end iterator of the fixed_string.
189 *
190 * Returns a reverse iterator pointing to the position preceding the first character of the fixed_string when reversed.
191 * This iterator acts as a placeholder and should not be dereferenced.
192 *
193 * @return A constant reverse iterator to the end of the reversed fixed_string.
194 * @sa crbegin()
195 */
196 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR_17 IPADDRESS_FORCE_INLINE const_reverse_iterator crend() const IPADDRESS_NOEXCEPT {
197 return const_reverse_iterator(cbegin());
198 }
199
200 /**
201 * Checks if the fixed_string is empty.
202 *
203 * Evaluates whether the fixed_string contains no characters.
204 *
205 * @return `true` if the fixed_string is empty, `false` otherwise.
206 */
208 return size() == 0;
209 }
210
211 /**
212 * Retrieves the size of the fixed_string.
213 *
214 * Returns the number of characters currently stored in the fixed_string.
215 *
216 * @return The number of characters in the fixed_string.
217 * @sa capacity()
218 */
220 return length;
221 }
222
223 /**
224 * Retrieves the capacity of the fixed_string.
225 *
226 * Returns the total number of characters that the fixed_string can hold.
227 *
228 * @return The capacity of the fixed_string.
229 * @sa size()
230 */
232 return max_length;
233 }
234
235 /**
236 * Accesses the character at the specified location with bounds checking.
237 *
238 * Returns a reference to the character at the specified location \a n. If \a n is out of bounds,
239 * an exception of type `std::out_of_range` will be thrown.
240 *
241 * @param[in] n The position of the character to return.
242 * @return A reference to the character at the specified location.
243 * @throw std::out_of_range When going beyond the bounds of the character array.
244 * @sa at(size_t) const
245 */
246 IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference operator[](size_t n) const IPADDRESS_NOEXCEPT {
247 return at(n);
248 }
249
250 /**
251 * Accesses the character at the specified location with bounds checking.
252 *
253 * Returns a reference to the character at the specified location \a n. If \a n is out of bounds,
254 * an exception of type `std::out_of_range` will be thrown.
255 *
256 * @param[in] n The position of the character to return.
257 * @return A reference to the character at the specified location.
258 * @throw std::out_of_range When going beyond the bounds of the character array.
259 * @sa operator[](size_t) const
260 */
261 IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference at(size_t n) const IPADDRESS_NOEXCEPT {
262 return _data[n];
263 }
264
265 /**
266 * Accesses the first element.
267 *
268 * Provides a reference to the first element in the string.
269 * Undefined behavior occurs if this function is called on an empty string.
270 *
271 * @return Reference to the first element.
272 * @sa back()
273 */
274 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference front() const IPADDRESS_NOEXCEPT {
275 return _data[0];
276 }
277
278 /**
279 * Accesses the last element.
280 *
281 * Provides a reference to the last element in the string.
282 * Undefined behavior occurs if this function is called on an empty string.
283 *
284 * @return Reference to the last element.
285 * @sa front()
286 */
287 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference back() const IPADDRESS_NOEXCEPT {
288 return _data[N - 1];
289 }
290
291 /**
292 * Provides a pointer to the underlying data.
293 *
294 * Returns a pointer to the underlying array serving as the string's storage.
295 * The range [data(), data() + size()) is valid even if the string is empty,
296 * but the data is not dereferenceable in that case.
297 *
298 * @return Pointer to the underlying data storage.
299 */
300 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_pointer data() const IPADDRESS_NOEXCEPT {
301 return _data;
302 }
303
304 /**
305 * Compares the string with another fixed_string.
306 *
307 * Compares the string with another fixed_string lexicographically.
308 *
309 * @tparam N2 The size of the other fixed_string.
310 * @param[in] rhs The other fixed_string to compare with.
311 * @return Negative value if less, zero if equal, positive value if greater.
312 */
313 template <size_t N2>
315 size_t i = 0;
316 for (; i < size() && i < rhs.size(); ++i) {
317 const auto c1 = at(i);
318 const auto c2 = rhs.at(i);
319 if (c1 != c2) {
320 return int(c1) - int(c2);
321 }
322 }
323
324 if (i == size() && i == rhs.size()) {
325 return 0;
326 } else if (i == size() && i < rhs.size()) {
327 return -1;
328 } else {
329 return 1;
330 }
331 }
332
333 /**
334 * Calculates the hash of the string.
335 *
336 * Computes a hash value for the string using a FNV-1a hash function.
337 *
338 * @return The hash value of the string.
339 */
341 size_t value{};
342 size_t prime{};
343
344 if (sizeof(size_t) == 8) {
345 value = size_t(14695981039346656037ULL);
346 prime = size_t(1099511628211ULL);
347 } else {
348 value = size_t(2166136261U);
349 prime = size_t(16777619U);
350 }
351
352 for (size_t i = 0; i < size(); ++i) {
353 value ^= static_cast<size_t>(_data[i]);
354 value *= prime;
355 }
356 return value;
357 }
358
359 /**
360 * Swaps the contents with another fixed_string.
361 *
362 * Exchanges the contents of the string with those of another fixed_string.
363 *
364 * @param[in,out] other The other fixed_string to swap with.
365 */
367 auto count = size() < other.size() ? other.size() : size();
368 for (size_t i = 0; i < count; ++i) {
369 auto tmp = _data[i];
370 _data[i] = other._data[i];
371 other._data[i] = tmp;
372 }
373 auto tmp = length;
374 length = other.length;
375 other.length = tmp;
376 }
377}; // fixed_string<N>
378
379IPADDRESS_EXPORT template <>
380struct fixed_string<0> {
381 using value_type = char;
382 using const_pointer = const char*;
383 using const_reference = const char&;
384 using const_iterator = const_pointer;
385 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
386
387 static constexpr size_t max_length = 0;
388
389 static constexpr size_t length = 0;
390
391 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string() IPADDRESS_NOEXCEPT = default;
392
393 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string(const char*) IPADDRESS_NOEXCEPT {
394 }
395
396 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string(const wchar_t*) IPADDRESS_NOEXCEPT {
397 }
398
399 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string(const char16_t*) IPADDRESS_NOEXCEPT {
400 }
401
402 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string(const char32_t*) IPADDRESS_NOEXCEPT {
403 }
404
405 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string(const char*, error_code& code) IPADDRESS_NOEXCEPT {
407 }
408
409 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string(const wchar_t*, error_code& code) IPADDRESS_NOEXCEPT {
411 }
412
413 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string(const char16_t*, error_code& code) IPADDRESS_NOEXCEPT {
415 }
416
417 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_string(const char32_t*, error_code& code) IPADDRESS_NOEXCEPT {
419 }
420
421#if __cpp_char8_t >= 201811L
423 }
424
427 }
428#endif // __cpp_char8_t
429
430 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator begin() const IPADDRESS_NOEXCEPT {
431 return const_iterator(nullptr);
432 }
433
434 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator end() const IPADDRESS_NOEXCEPT {
435 return const_iterator(nullptr) + length;
436 }
437
438 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR_17 IPADDRESS_FORCE_INLINE const_reverse_iterator rbegin() const IPADDRESS_NOEXCEPT {
439 return const_reverse_iterator(end());
440 }
441
442 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR_17 IPADDRESS_FORCE_INLINE const_reverse_iterator rend() const IPADDRESS_NOEXCEPT {
443 return const_reverse_iterator(begin());
444 }
445
446 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator cbegin() const IPADDRESS_NOEXCEPT {
447 return begin();
448 }
449
450 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator cend() const IPADDRESS_NOEXCEPT {
451 return end();
452 }
453
454 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR_17 IPADDRESS_FORCE_INLINE const_reverse_iterator crbegin() const IPADDRESS_NOEXCEPT {
455 return const_reverse_iterator(cend());
456 }
457
458 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR_17 IPADDRESS_FORCE_INLINE const_reverse_iterator crend() const IPADDRESS_NOEXCEPT {
459 return const_reverse_iterator(cbegin());
460 }
461
462 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool empty() const IPADDRESS_NOEXCEPT {
463 return true;
464 }
465
466 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t size() const IPADDRESS_NOEXCEPT {
467 return 0;
468 }
469
470 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t capacity() const IPADDRESS_NOEXCEPT {
471 return 0;
472 }
473
474 IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference operator[](size_t n) const IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
475 return at(n);
476 }
477
478 IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference at(size_t /*n*/) const IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
479 return front();
480 }
481
482 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference front() const IPADDRESS_NOEXCEPT {
483 return *cbegin();
484 }
485
486 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference back() const IPADDRESS_NOEXCEPT {
487 return *cbegin();
488 }
489
490 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_pointer data() const IPADDRESS_NOEXCEPT {
491 return nullptr;
492 }
493
494 template <size_t N2>
495 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE int compare(const fixed_string<N2>& rhs) const IPADDRESS_NOEXCEPT {
496 return rhs.empty() ? 0 : -1;
497 }
498
499 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t hash() const IPADDRESS_NOEXCEPT {
500 return 0;
501 }
502
503 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void swap(fixed_string& other) IPADDRESS_NOEXCEPT {
504 }
505}; // fixed_string<0>
506
507/**
508 * Compares the contents of two fixed strings for equality.
509 *
510 * Checks if the contents of \a lhs and \a rhs are equal, meaning they have the same
511 * number of elements and each element in \a lhs compares equal with the element in \a rhs at the same position.
512 *
513 * @tparam N1 The maximum number of characters of \a lhs.
514 * @tparam N2 The maximum number of characters of \a rhs.
515 * @param[in] lhs The fixed string whose contents to compare.
516 * @param[in] rhs The fixed string whose contents to compare.
517 * @return `true` if the contents of the strings are equal, `false` otherwise.
518 */
519IPADDRESS_EXPORT template <size_t N1, size_t N2>
520IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator==(const fixed_string<N1>& lhs, const fixed_string<N2>& rhs) IPADDRESS_NOEXCEPT {
521 return lhs.compare(rhs) == 0;
522}
523
524/**
525 * Compares the contents of two fixed strings for inequality.
526 *
527 * Checks if the contents of \a lhs and \a rhs are not equal, meaning they do not have the same
528 * number of elements or there is at least one position at which the elements in \a lhs and \a rhs differ.
529 *
530 * @tparam N1 The maximum number of characters of \a lhs.
531 * @tparam N2 The maximum number of characters of \a rhs.
532 * @param[in] lhs The fixed string whose contents to compare.
533 * @param[in] rhs The fixed string whose contents to compare.
534 * @return `true` if the contents of the strings are not equal, `false` otherwise.
535 */
536IPADDRESS_EXPORT template <size_t N1, size_t N2>
537IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator!=(const fixed_string<N1>& lhs, const fixed_string<N2>& rhs) IPADDRESS_NOEXCEPT {
538 return !(lhs == rhs);
539}
540
541#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
542
543 /**
544 * Compares the contents of two fixed strings lexicographically.
545 *
546 * Uses the three-way comparison operator (spaceship operator) to compare the contents of \a lhs and \a rhs.
547 *
548 * @tparam N1 The maximum number of characters of \a lhs.
549 * @tparam N2 The maximum number of characters of \a rhs.
550 * @param[in] lhs The fixed string whose contents to compare.
551 * @param[in] rhs The fixed string whose contents to compare.
552 * @return The relative order of the first pair of non-equivalent elements in \a lhs and \a rhs if there are such elements.
553 */
554 IPADDRESS_EXPORT template <size_t N1, size_t N2>
555 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE std::strong_ordering operator<=>(const fixed_string<N1>& lhs, const fixed_string<N2>& rhs) IPADDRESS_NOEXCEPT {
556 if (const auto result = lhs.compare(rhs); result == 0) {
557 return std::strong_ordering::equivalent;
558 } else if (result < 0) {
559 return std::strong_ordering::less;
560 } else {
561 return std::strong_ordering::greater;
562 }
563 }
564
565#else // !IPADDRESS_HAS_SPACESHIP_OPERATOR
566
567 /**
568 * Compares the contents of two fixed strings lexicographically.
569 *
570 * Checks if the contents of \a lhs are lexicographically less than the contents of \a rhs.
571 *
572 * @tparam N1 The maximum number of characters of \a lhs.
573 * @tparam N2 The maximum number of characters of \a rhs.
574 * @param[in] lhs The fixed string whose contents to compare.
575 * @param[in] rhs The fixed string whose contents to compare.
576 * @return `true` if the contents of \a lhs are lexicographically less than the contents of \a rhs, `false` otherwise.
577 */
578 IPADDRESS_EXPORT template <size_t N1, size_t N2>
579 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator<(const fixed_string<N1>& lhs, const fixed_string<N2>& rhs) IPADDRESS_NOEXCEPT {
580 return lhs.compare(rhs) < 0;
581 }
582
583 /**
584 * Compares the contents of two fixed strings for greater than relation.
585 *
586 * Determines if the contents of \a lhs are lexicographically greater than the contents of \a rhs.
587 *
588 * @tparam N1 The maximum number of characters of \a lhs.
589 * @tparam N2 The maximum number of characters of \a rhs.
590 * @param[in] lhs The fixed string whose contents to compare.
591 * @param[in] rhs The fixed string whose contents to compare.
592 * @return `true` if \a lhs is lexicographically greater than \a rhs, `false` otherwise.
593 */
594 IPADDRESS_EXPORT template <size_t N1, size_t N2>
595 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator>(const fixed_string<N1>& lhs, const fixed_string<N2>& rhs) IPADDRESS_NOEXCEPT {
596 return rhs < lhs;
597 }
598
599 /**
600 * Compares the contents of two fixed strings for less than or equal relation.
601 *
602 * Determines if the contents of \a lhs are lexicographically less than or equal to the contents of \a rhs.
603 *
604 * @tparam N1 The maximum number of characters of \a lhs.
605 * @tparam N2 The maximum number of characters of \a rhs.
606 * @param[in] lhs The fixed string whose contents to compare.
607 * @param[in] rhs The fixed string whose contents to compare.
608 * @return `true` if \a lhs is lexicographically less than or equal to \a rhs, `false` otherwise.
609 */
610 IPADDRESS_EXPORT template <size_t N1, size_t N2>
611 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator<=(const fixed_string<N1>& lhs, const fixed_string<N2>& rhs) IPADDRESS_NOEXCEPT {
612 return !(rhs < lhs);
613 }
614
615 /**
616 * Compares the contents of two fixed strings for greater than or equal relation.
617 *
618 * Determines if the contents of \a lhs are lexicographically greater than or equal to the contents of \a rhs.
619 *
620 * @tparam N1 The maximum number of characters of \a lhs.
621 * @tparam N2 The maximum number of characters of \a rhs.
622 * @param[in] lhs The fixed string whose contents to compare.
623 * @param[in] rhs The fixed string whose contents to compare.
624 * @return `true` if \a lhs is lexicographically greater than or equal to \a rhs, `false` otherwise.
625 */
626 IPADDRESS_EXPORT template <size_t N1, size_t N2>
627 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator>=(const fixed_string<N1>& lhs, const fixed_string<N2>& rhs) IPADDRESS_NOEXCEPT {
628 return !(lhs < rhs);
629 }
630
631#endif // !IPADDRESS_HAS_SPACESHIP_OPERATOR
632
633/**
634 * Creates a fixed-length string from a character array.
635 *
636 * Constructs a fixed_string object from a character array, deducing the size automatically.
637 *
638 * @tparam T The character type of the input array.
639 * @tparam N The size of the character array plus one for the null terminator.
640 * @param[in] data The character array to initialize the fixed_string with.
641 * @return A fixed_string object of size N-1.
642 */
643IPADDRESS_EXPORT template <typename T, size_t N>
645 return fixed_string<N - 1>(data);
646}
647
648/**
649 * Creates a fixed-length string from a character array.
650 *
651 * Constructs a fixed_string object from a character array, deducing the size automatically.
652 *
653 * @tparam T The character type of the input array.
654 * @tparam N The size of the character array plus one for the null terminator.
655 * @param[in] data The character array to initialize the fixed_string with.
656 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
657 * @return A fixed_string object of size N-1.
658 */
659IPADDRESS_EXPORT template <typename T, size_t N>
661 return fixed_string<N - 1>(data, code);
662}
663
664#if IPADDRESS_CPP_VERSION >= 17
665
666#if __cpp_char8_t >= 201811L
667 IPADDRESS_EXPORT template <size_t N> fixed_string(const char8_t(&)[N]) -> fixed_string<N - 1>;
668#endif // __cpp_char8_t
669 IPADDRESS_EXPORT template <size_t N> fixed_string(fixed_string<N>) -> fixed_string<N>;
670 IPADDRESS_EXPORT template <size_t N> fixed_string(const char(&)[N]) -> fixed_string<N - 1>;
671 IPADDRESS_EXPORT template <size_t N> fixed_string(const wchar_t(&)[N]) -> fixed_string<N - 1>;
672 IPADDRESS_EXPORT template <size_t N> fixed_string(const char16_t(&)[N]) -> fixed_string<N - 1>;
673 IPADDRESS_EXPORT template <size_t N> fixed_string(const char32_t(&)[N]) -> fixed_string<N - 1>;
674 IPADDRESS_EXPORT fixed_string() -> fixed_string<0>;
675
676#endif
677
678} // namespace IPADDRESS_NAMESPACE
679
680#endif // IPADDRESS_FIXED_STRING_HPP
#define IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS
Definition config.hpp:93
#define IPADDRESS_EXPORT
Definition config.hpp:42
#define IPADDRESS_NODISCARD
Definition config.hpp:98
#define IPADDRESS_FORCE_INLINE
Definition config.hpp:112
#define IPADDRESS_NAMESPACE
Definition config.hpp:38
#define IPADDRESS_NOEXCEPT
Definition config.hpp:89
#define IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS
Definition config.hpp:102
constexpr inline bool operator>=(const fixed_string< N1 > &lhs, const fixed_string< N2 > &rhs) noexcept
Compares the contents of two fixed strings for greater than or equal relation.
Definition fixed-string.hpp:627
constexpr inline bool operator>(const fixed_string< N1 > &lhs, const fixed_string< N2 > &rhs) noexcept
Compares the contents of two fixed strings for greater than relation.
Definition fixed-string.hpp:595
error_code
Enumeration of error codes for IP address parsing and validation.
Definition errors.hpp:52
@ no_error
Indicates the absence of any errors.
constexpr inline bool operator<(const fixed_string< N1 > &lhs, const fixed_string< N2 > &rhs) noexcept
Compares the contents of two fixed strings lexicographically.
Definition fixed-string.hpp:579
constexpr inline fixed_string< N - 1 > make_fixed_string(const T(&data)[N], error_code &code) noexcept
Creates a fixed-length string from a character array.
Definition fixed-string.hpp:660
constexpr inline bool operator<=(const fixed_string< N1 > &lhs, const fixed_string< N2 > &rhs) noexcept
Compares the contents of two fixed strings for less than or equal relation.
Definition fixed-string.hpp:611
constexpr inline fixed_string< N - 1 > make_fixed_string(const T(&data)[N]) noexcept(noexcept(fixed_string< N - 1 >(data)))
Creates a fixed-length string from a character array.
Definition fixed-string.hpp:644
constexpr inline bool operator==(const fixed_string< N1 > &lhs, const fixed_string< N2 > &rhs) noexcept
Compares the contents of two fixed strings for equality.
Definition fixed-string.hpp:520
constexpr inline bool operator!=(const fixed_string< N1 > &lhs, const fixed_string< N2 > &rhs) noexcept
Compares the contents of two fixed strings for inequality.
Definition fixed-string.hpp:537
Fixed size string class.
Definition fixed-string.hpp:29
constexpr inline fixed_string() noexcept=default
Default constructor.
constexpr inline const_reverse_iterator crbegin() const noexcept
Retrieves the constant reverse begin iterator of the fixed_string.
Definition fixed-string.hpp:183
constexpr inline size_t capacity() const noexcept
Retrieves the capacity of the fixed_string.
Definition fixed-string.hpp:231
constexpr inline const_iterator begin() const noexcept
Retrieves the begin iterator of the fixed_string.
Definition fixed-string.hpp:105
constexpr inline bool empty() const noexcept
Checks if the fixed_string is empty.
Definition fixed-string.hpp:207
constexpr inline const_reverse_iterator crend() const noexcept
Retrieves the constant reverse end iterator of the fixed_string.
Definition fixed-string.hpp:196
constexpr inline const_reference front() const noexcept
Accesses the first element.
Definition fixed-string.hpp:274
constexpr inline const_pointer data() const noexcept
Provides a pointer to the underlying data.
Definition fixed-string.hpp:300
constexpr inline const_reference at(size_t n) const noexcept
Accesses the character at the specified location with bounds checking.
Definition fixed-string.hpp:261
constexpr inline const_reverse_iterator rend() const noexcept
Retrieves the reverse end iterator of the fixed_string.
Definition fixed-string.hpp:144
constexpr inline const_iterator cend() const noexcept
Retrieves the constant end iterator of the fixed_string.
Definition fixed-string.hpp:170
constexpr inline int compare(const fixed_string< N2 > &rhs) const noexcept
Compares the string with another fixed_string.
Definition fixed-string.hpp:314
constexpr inline fixed_string(const T(&data)[N+1]) noexcept(noexcept(internal::char_reader< T >::has_throw()))
Constructs a fixed_string from a character array.
Definition fixed-string.hpp:59
constexpr inline const_reference operator[](size_t n) const noexcept
Accesses the character at the specified location with bounds checking.
Definition fixed-string.hpp:246
constexpr inline size_t hash() const noexcept
Calculates the hash of the string.
Definition fixed-string.hpp:340
constexpr inline const_iterator cbegin() const noexcept
Retrieves the constant begin iterator of the fixed_string.
Definition fixed-string.hpp:157
constexpr inline const_iterator end() const noexcept
Retrieves the end iterator of the fixed_string.
Definition fixed-string.hpp:118
constexpr inline fixed_string(const T(&data)[N+1], error_code &code) noexcept
Constructs a fixed_string from a character array.
Definition fixed-string.hpp:82
constexpr inline size_t size() const noexcept
Retrieves the size of the fixed_string.
Definition fixed-string.hpp:219
constexpr inline const_reverse_iterator rbegin() const noexcept
Retrieves the reverse begin iterator of the fixed_string.
Definition fixed-string.hpp:131
constexpr inline void swap(fixed_string &other) noexcept
Swaps the contents with another fixed_string.
Definition fixed-string.hpp:366
constexpr inline const_reference back() const noexcept
Accesses the last element.
Definition fixed-string.hpp:287