ipaddress 1.2.0
Loading...
Searching...
No Matches
fixed-vector.hpp
Go to the documentation of this file.
1/**
2 * @file fixed-vector.hpp
3 * @brief Provides a fixed-size vector class template
4 * @author Vladimir Shaleev
5 * @copyright MIT License
6 *
7 * The fixed_vector template class is a lightweight container that encapsulates a fixed-size array.
8 * It provides a subset of the functionality of std::vector, optimized for scenarios where the size
9 * of the container is known at compile-time. This class is designed to work in constexpr contexts,
10 * enabling compile-time operations on fixed-size arrays. It ensures efficient memory usage and
11 * avoids dynamic memory allocation.
12 */
13
14 #ifndef IPADDRESS_FIXED_VECTOR_HPP
15 #define IPADDRESS_FIXED_VECTOR_HPP
16
17 #include "config.hpp"
18
19 namespace IPADDRESS_NAMESPACE {
20
21 namespace internal {
22
23 template <typename It>
24 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE typename std::iterator_traits<It>::difference_type get_distance(It first, It last, std::random_access_iterator_tag) IPADDRESS_NOEXCEPT {
25 return last - first;
26 }
27
28 template <typename It, typename Tag>
29 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE typename std::iterator_traits<It>::difference_type get_distance(It first, It last, Tag) IPADDRESS_NOEXCEPT {
30 typename std::iterator_traits<It>::difference_type count = 0;
31 for (auto it = first; it != last; ++it) {
32 ++count;
33 }
34 return count;
35 }
36
37 template<class It>
38 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE typename std::iterator_traits<It>::difference_type distance(It first, It last) IPADDRESS_NOEXCEPT {
39 return get_distance(first, last, typename std::iterator_traits<It>::iterator_category{});
40 }
41
42 } // namespace IPADDRESS_NAMESPACE::internal
43
44 /**
45 * A fixed-size vector iterator class template.
46 *
47 * The fixed_vector_iterator class template provides an iterator for the fixed_vector class template.
48 * It allows for iteration over the elements in the fixed_vector.
49 *
50 * @tparam T type of the elements in the vector.
51 */
52 IPADDRESS_EXPORT template <typename T>
54 public:
55 using iterator_category = std::random_access_iterator_tag; /**< The iterator category. */
56 using value_type = T; /**< The type of the elements. */
57 using difference_type = ptrdiff_t; /**< The type used for representing differences between iterators. */
58 using pointer = T*; /**< Pointer to the element type. */
59 using reference = T&; /**< Reference to the element type. */
60
61 /**
62 * Default constructor.
63 */
65
66 /**
67 * Constructs a fixed_vector_iterator from a pointer.
68 *
69 * @param[in] ptr The pointer to the element type.
70 */
71 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE explicit fixed_vector_iterator(pointer ptr) IPADDRESS_NOEXCEPT : _ptr(ptr) {
72 }
73
74 /**
75 * Constructs a const-compatible fixed_vector_iterator from a non-const fixed_vector_iterator.
76 *
77 * @param[in] it The iterator to convert.
78 */
79 template <typename U, typename = typename std::enable_if<std::is_convertible<U*, T*>::value>::type>
80 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_vector_iterator(const fixed_vector_iterator<U>& it) IPADDRESS_NOEXCEPT : _ptr(it.operator->()) {
81 }
82
83 /**
84 * Dereference operator.
85 *
86 * @return A reference to the element pointed to by the iterator.
87 */
89 return *_ptr;
90 }
91
92 /**
93 * Pointer access operator.
94 *
95 * @return A pointer to the element pointed to by the iterator.
96 */
98 return _ptr;
99 }
100
101 /**
102 * Access operator.
103 *
104 * @param[in] n The index of the element to access.
105 * @return A reference to the element at index n.
106 */
107 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference operator[](size_t n) const IPADDRESS_NOEXCEPT {
108 return *(_ptr + n);
109 }
110
111 /**
112 * Pre-increment operator.
113 *
114 * @return A reference to the iterator after incrementing.
115 */
117 ++_ptr;
118 return *this;
119 }
120
121 /**
122 * Post-increment operator.
123 *
124 * @return A copy of the iterator before incrementing.
125 */
127 auto tmp = *this;
128 ++_ptr;
129 return tmp;
130 }
131
132 /**
133 * Pre-decrement operator.
134 *
135 * @return A reference to the iterator after decrementing.
136 */
138 --_ptr;
139 return *this;
140 }
141
142 /**
143 * Post-decrement operator.
144 *
145 * @return A copy of the iterator before decrementing.
146 */
148 auto tmp = *this;
149 --_ptr;
150 return tmp;
151 }
152
153 /**
154 * Addition assignment operator.
155 *
156 * @param[in] n The number of elements to add.
157 * @return A reference to the iterator after addition.
158 */
160 _ptr += n;
161 return *this;
162 }
163
164 /**
165 * Subtraction assignment operator.
166 *
167 * @param[in] n The number of elements to subtract.
168 * @return A reference to the iterator after subtraction.
169 */
171 _ptr -= n;
172 return *this;
173 }
174
175 /**
176 * Addition operator.
177 *
178 * @param[in] n The number of elements to add.
179 * @return A new fixed_vector_iterator instance after addition.
180 */
182 return fixed_vector_iterator(_ptr + n);
183 }
184
185 /**
186 * Addition operator.
187 *
188 * @param[in] n The number of elements to add.
189 * @param[in] it The iterator to add to.
190 * @return A new fixed_vector_iterator instance after addition.
191 */
193 return it + n;
194 }
195
196 /**
197 * Subtraction operator.
198 *
199 * @param[in] n The number of elements to subtract.
200 * @return A new fixed_vector_iterator instance after subtraction.
201 */
203 return fixed_vector_iterator(_ptr - n);
204 }
205
206 /**
207 * Subtraction operator.
208 *
209 * @param[in] it The iterator to subtract from.
210 * @return The difference between the two iterators.
211 */
213 return _ptr - it._ptr;
214 }
215
216 /**
217 * Equality operator.
218 *
219 * @param[in] it The iterator to compare with.
220 * @return true if this iterator is equal to the other iterator, false otherwise.
221 */
223 return _ptr == it._ptr;
224 }
225
226 /**
227 * Inequality operator.
228 *
229 * @param[in] it The iterator to compare with.
230 * @return true if this iterator is not equal to the other iterator, false otherwise.
231 */
233 return !(*this == it);
234 }
235
236
237 #ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
238
239 /**
240 * Spaceship operator.
241 *
242 * @param[in] it The iterator to compare with.
243 * @return A strong_ordering value representing the comparison result.
244 */
246 return _ptr <=> it._ptr;
247 }
248
249 #else // !IPADDRESS_HAS_SPACESHIP_OPERATOR
250
251 /**
252 * Less than operator.
253 *
254 * @param[in] it The iterator to compare with.
255 * @return true if this iterator is less than the other iterator, false otherwise.
256 */
258 return _ptr < it._ptr;
259 }
260
261 /**
262 * Less than or equal to operator.
263 *
264 * @param[in] it The iterator to compare with.
265 * @return true if this iterator is less than or equal to the other iterator, false otherwise.
266 */
268 return !(it < *this);
269 }
270
271 /**
272 * Greater than operator.
273 *
274 * @param[in] it The iterator to compare with.
275 * @return true if this iterator is greater than the other iterator, false otherwise.
276 */
278 return it < *this;
279 }
280
281 /**
282 * Greater than or equal to operator.
283 *
284 * @param[in] it The iterator to compare with.
285 * @return true if this iterator is greater than or equal to the other iterator, false otherwise.
286 */
288 return !(*this < it);
289 }
290
291 #endif // !IPADDRESS_HAS_SPACESHIP_OPERATOR
292
293 private:
294 pointer _ptr{};
295 }; // fixed_vector_iterator;
296
297 /**
298 * A fixed-size vector class template.
299 *
300 * The fixed_vector class template provides a simple fixed-size array wrapper that allows for compile-time operations.
301 *
302 * @tparam T type of the elements in the vector.
303 * @tparam N capacity of the vector.
304 * @remark The fixed_vector class is a simple fixed-size array wrapper that provides a subset of the functionality of std::vector.
305 * This class is designed to work in constexpr contexts, allowing compile-time operations on fixed-size arrays.
306 */
307 IPADDRESS_EXPORT template <typename T, size_t N>
309 public:
310 using value_type = T; /**< type of the elements in the vector. */
311 using size_type = size_t; /**< type used for size representation. */
312 using difference_type = ptrdiff_t; /**< type used for representing differences between iterators. */
313 using pointer = value_type*; /**< type used for pointer to elements. */
314 using const_pointer = const value_type*; /**< type used for pointer to constant elements. */
315 using reference = value_type&; /**< type used for reference to elements. */
316 using const_reference = const value_type&; /**< type used for reference to constant elements. */
317 using iterator = fixed_vector_iterator<value_type>; /**< type used for iterator to elements. */
318 using const_iterator = fixed_vector_iterator<const value_type>; /**< type used for iterator to constant elements. */
319 using reverse_iterator = std::reverse_iterator<iterator>; /**< type used for reverse iterator. */
320 using const_reverse_iterator = std::reverse_iterator<const_iterator>; /**< type used for reverse iterator to constant elements. */
321
322 /**
323 * Default constructor.
324 */
326
327 /**
328 * Constructs a fixed_vector with the specified number of default-initialized elements.
329 *
330 * @param[in] n The number of elements to initialize.
331 * @remark The number of elements must not exceed the maximum size of the vector.
332 */
333 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE explicit fixed_vector(size_type n) IPADDRESS_NOEXCEPT {
334 assert(n <= max_size());
335 _size = n;
336 }
337
338 /**
339 * Constructs a fixed_vector with the specified number of elements initialized to the given value.
340 *
341 * @param[in] n The number of elements to initialize.
342 * @param[in] value The value to initialize the elements with.
343 * @remark The number of elements must not exceed the maximum size of the vector.
344 */
345 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_vector(size_type n, const_reference value) IPADDRESS_NOEXCEPT {
346 assign(n, value);
347 }
348
349 /**
350 * Constructs a fixed_vector from a range of elements.
351 *
352 * @tparam It The iterator type.
353 * @param[in] first The beginning iterator of the range.
354 * @param[in] last The ending iterator of the range.
355 * @remark The number of elements must not exceed the maximum size of the vector.
356 */
357 template <class It>
358 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_vector(It first, It last) IPADDRESS_NOEXCEPT {
359 assign(first, last);
360 }
361
362 /**
363 * Constructs a fixed_vector from an initializer list.
364 *
365 * @param[in] init_list The initializer list of elements.
366 * @remark The number of elements must not exceed the maximum size of the vector.
367 */
368 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_vector(std::initializer_list<value_type> init_list) IPADDRESS_NOEXCEPT : fixed_vector(init_list.begin(), init_list.end()) {
369 }
370
371 /**
372 * Replaces the contents with the specified number of copies of the given value.
373 *
374 * @param[in] n The number of elements to assign.
375 * @param[in] value The value to assign to the elements.
376 * @remark The number of elements must not exceed the maximum size of the vector.
377 */
378 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void assign(size_type n, const_reference value) IPADDRESS_NOEXCEPT {
379 assert(n <= max_size());
380 _size = n;
381 for (size_type i = 0; i < n; ++i) {
382 _data[i] = value;
383 }
384 }
385
386 /**
387 * Replaces the contents with the elements in the specified range.
388 *
389 * @tparam It The iterator type.
390 * @param[in] first The beginning iterator of the range.
391 * @param[in] last The ending iterator of the range.
392 * @remark The number of elements must not exceed the maximum size of the vector.
393 */
394 template <class It>
395 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void assign(It first, It last) IPADDRESS_NOEXCEPT {
396 _size = 0;
397 for (auto it = first; it != last; ++it) {
398 assert(_size < max_size());
399 _data[_size++] = *it;
400 }
401 }
402
403 /**
404 * Replaces the contents with the elements in the specified initializer list.
405 *
406 * @param[in] init_list The initializer list of elements.
407 * @remark The number of elements must not exceed the maximum size of the vector.
408 */
409 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void assign(std::initializer_list<value_type> init_list) IPADDRESS_NOEXCEPT {
410 assign(init_list.begin(), init_list.end());
411 }
412
413 /**
414 * Accesses an element by index.
415 *
416 * @param[in] n The index of the element.
417 * @return The element at the specified index.
418 * @remark n must be less than the size of the vector.
419 */
420 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference at(size_type n) IPADDRESS_NOEXCEPT {
421 assert(n < size());
422 return _data[n];
423 }
424
425 /**
426 * Accesses an element by index.
427 *
428 * @param[in] n The index of the element.
429 * @return The element at the specified index.
430 * @remark n must be less than the size of the vector.
431 */
432 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference at(size_type n) const IPADDRESS_NOEXCEPT {
433 assert(n < size());
434 return _data[n];
435 }
436
437 /**
438 * Accesses an element by index.
439 *
440 * @param[in] n The index of the element.
441 * @return The element at the specified index.
442 * @remark n must be less than the size of the vector.
443 */
444 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference operator[](size_type n) IPADDRESS_NOEXCEPT {
445 return at(n);
446 }
447
448 /**
449 * Accesses an element by index.
450 *
451 * @param[in] n The index of the element.
452 * @return The element at the specified index.
453 * @remark n must be less than the size of the vector.
454 */
455 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference operator[](size_type n) const IPADDRESS_NOEXCEPT {
456 return at(n);
457 }
458
459 /**
460 * Accesses the first element in the vector.
461 *
462 * @return A reference to the first element in the vector.
463 */
465 assert(!empty());
466 return _data[0];
467 }
468
469 /**
470 * Accesses the first element in the vector.
471 *
472 * @return A reference to the first element in the vector.
473 */
474 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference front() const IPADDRESS_NOEXCEPT {
475 assert(!empty());
476 return _data[0];
477 }
478
479 /**
480 * Accesses the last element in the vector.
481 *
482 * @return A reference to the last element in the vector.
483 */
485 assert(!empty());
486 return _data[_size - 1];
487 }
488
489 /**
490 * Accesses the last element in the vector.
491 *
492 * @return A reference to the last element in the vector.
493 */
494 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference back() const IPADDRESS_NOEXCEPT {
495 assert(!empty());
496 return _data[_size - 1];
497 }
498
499 /**
500 * Returns a pointer to the underlying array.
501 *
502 * @return A pointer to the underlying array of type value_type.
503 */
505 return _data;
506 }
507
508 /**
509 * Returns a const pointer to the underlying array (const version).
510 *
511 * @return A const pointer to the underlying array of type value_type.
512 */
513 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_pointer data() const IPADDRESS_NOEXCEPT {
514 return _data;
515 }
516
517 /**
518 * Return iterator to the first element.
519 *
520 * @return An iterator to the first element in the vector.
521 */
523 return iterator(_data);
524 }
525
526 /**
527 * Return const iterator to the first element
528 *
529 * @return A const iterator to the first element in the vector.
530 */
531 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator begin() const IPADDRESS_NOEXCEPT {
532 return const_iterator(_data);
533 }
534
535 /**
536 * Return const iterator to the first element.
537 *
538 * @return A const iterator to the first element in the vector.
539 */
540 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator cbegin() const IPADDRESS_NOEXCEPT {
541 return begin();
542 }
543
544 /**
545 * Returns an reverse iterator to the first element.
546 *
547 * @return A reverse iterator to the first element in the vector.
548 */
550 return reverse_iterator(end());
551 }
552
553 /**
554 * Returns a const iterator to the first element.
555 *
556 * @return A const reverse iterator to the first element in the vector.
557 */
558 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator rbegin() const IPADDRESS_NOEXCEPT {
559 return const_reverse_iterator(end());
560 }
561
562 /**
563 * Returns a const reverse iterator to the first element.
564 *
565 * @return A const reverse iterator to the first element in the vector.
566 */
567 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator crbegin() const IPADDRESS_NOEXCEPT {
568 return const_reverse_iterator(cend());
569 }
570
571 /**
572 * Returns an iterator to the element following the last element.
573 *
574 * @return An iterator to the element following the last element in the vector.
575 */
577 return iterator(_data + _size);
578 }
579
580 /**
581 * Returns a const iterator to the element following the last element.
582 *
583 * @return A const iterator to the element following the last element in the vector.
584 */
585 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator end() const IPADDRESS_NOEXCEPT {
586 return const_iterator(_data + _size);
587 }
588
589 /**
590 * Returns a const iterator to the element following the last element.
591 *
592 * @return A const iterator to the element following the last element in the vector.
593 */
594 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator cend() const IPADDRESS_NOEXCEPT {
595 return end();
596 }
597
598 /**
599 * Returns a reverse iterator to the element following the last element.
600 *
601 * @return A reverse iterator to the element following the last element in the vector.
602 */
603 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reverse_iterator rend() IPADDRESS_NOEXCEPT {
604 return reverse_iterator(begin());
605 }
606
607 /**
608 * Returns a const reverse iterator to the element following the last element.
609 *
610 * @return A const reverse iterator to the element following the last element in the vector.
611 */
612 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator rend() const IPADDRESS_NOEXCEPT {
613 return const_reverse_iterator(begin());
614 }
615
616 /**
617 * Returns a const reverse iterator to the element following the last element.
618 *
619 * @return A const reverse iterator to the element following the last element in the vector.
620 */
621 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator crend() const IPADDRESS_NOEXCEPT {
622 return const_reverse_iterator(cbegin());
623 }
624
625 /**
626 * Determines whether the container is empty.
627 *
628 * @return true if the container is empty; otherwise, false.
629 */
631 return _size == 0;
632 }
633
634 /**
635 * Returns the number of elements in the container.
636 *
637 * @return The number of elements in the container.
638 */
640 return _size;
641 }
642
643 /**
644 * Returns the maximum number of elements that the container can hold.
645 *
646 * @return The maximum number of elements that the container can hold.
647 */
649 return N;
650 }
651
652 /**
653 * Returns the maximum number of elements that the container can hold.
654 *
655 * @return The maximum number of elements that the container can hold.
656 */
658 return N;
659 }
660
661 /**
662 * Resizes the container to the specified size.
663 *
664 * If n is less than the current size, the container is truncated.
665 * If n is greater, default-inserted elements are added.
666 *
667 * @param[in] n The new size of the container.
668 * @remark n must not exceed the maximum size.
669 */
670 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void resize(size_type n) IPADDRESS_NOEXCEPT {
671 resize(n, value_type{});
672 }
673
674 /**
675 * Resizes the container to the specified size and initializes new elements with the given value.
676 *
677 * If n is less than the current size, the container is truncated.
678 * If n is greater, copies of value are appended.
679 *
680 * @param[in] n The new size of the container.
681 * @param[in] value The value to initialize new elements with.
682 * @remark n must not exceed the maximum size.
683 */
684 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void resize(size_type n, const_reference value) IPADDRESS_NOEXCEPT {
685 if (n < _size) {
686 _size = n;
687 } else {
688 assert(n < max_size());
689 for (size_type i = _size; i < n; ++i) {
690 _data[i] = value;
691 }
692 _size = n;
693 }
694 }
695
696 /**
697 * Reserves space for the specified number of elements.
698 *
699 * @param[in] n The number of elements to reserve space for.
700 * @note This function does not change the size of the container.
701 * It is a no-op for fixed_vector, as the size is fixed at compile time.
702 * The function is provided for compatibility with std::vector.
703 * @remark n must not exceed the maximum size.
704 */
705 static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void reserve(size_type n /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
706 assert(n < max_size());
707 }
708
709 /**
710 * Shrinks the container to fit its current size.
711 *
712 * @note This function does not change the size of the container.
713 * It is a no-op for fixed_vector, as the size is fixed at compile time.
714 * The function is provided for compatibility with std::vector.
715 */
716 static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void shrink_to_fit() IPADDRESS_NOEXCEPT {
717 }
718
719 /**
720 * Inserts copies of the given value at the specified position.
721 *
722 * @param[in] pos The position to insert the value at.
723 * @param[in] value The value to insert.
724 * @return An iterator to the inserted element.
725 * @remark The number of elements must not exceed the maximum size of the vector.
726 */
727 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert(const_iterator pos, const_reference value) IPADDRESS_NOEXCEPT {
728 return insert_n(pos, 1, value);
729 }
730
731 /**
732 * Moves the given value at the specified position.
733 *
734 * @param[in] pos The position to insert the value at.
735 * @param[in] value The value to insert.
736 * @return An iterator to the inserted element.
737 * @remark The number of elements must not exceed the maximum size of the vector.
738 */
739 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert(const_iterator pos, value_type&& value) IPADDRESS_NOEXCEPT {
740 return insert_n(pos, 1, std::move(value));
741 }
742
743 /**
744 * Inserts copies of the given value at the specified position.
745 *
746 * @param[in] pos The position to insert the value at.
747 * @param[in] n The number of copies to insert.
748 * @param[in] value The value to insert.
749 * @return An iterator pointing to the first inserted element.
750 * @remark The number of elements must not exceed the maximum size of the vector.
751 */
752 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert(const_iterator pos, size_type n, const_reference value) IPADDRESS_NOEXCEPT {
753 return insert_n(pos, n, value);
754 }
755
756 /**
757 * Inserts range of elements at the specified position.
758 *
759 * @tparam It The iterator type.
760 * @param[in] pos The position to insert the elements at.
761 * @param[in] first The beginning iterator of the range.
762 * @param[in] last The ending iterator of the range.
763 * @return An iterator pointing to the first inserted element.
764 * @remark The number of elements must not exceed the maximum size of the vector.
765 */
766 template <typename It>
767 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert(const_iterator pos, It first, It last) IPADDRESS_NOEXCEPT {
768 return insert_iterators(pos, first, last);
769 }
770
771 /**
772 * Inserts initializer list of elements at the specified position.
773 *
774 * @param[in] pos The position to insert the elements at.
775 * @param[in] init_list The initializer list of elements.
776 * @return An iterator pointing to the first inserted element.
777 * @remark The number of elements must not exceed the maximum size of the vector.
778 */
779 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert(const_iterator pos, std::initializer_list<value_type> init_list) IPADDRESS_NOEXCEPT {
780 return insert_iterators(pos, init_list.begin(), init_list.end());
781 }
782
783 /**
784 * Inserts a new element at the specified position, constructed in-place with the given arguments.
785 *
786 * @tparam Args The argument types for constructing the element.
787 * @param[in] pos The position to insert the element at.
788 * @param[in] args The arguments for constructing the element.
789 * @return An iterator pointing to the inserted element.
790 * @remark The number of elements must not exceed the maximum size of the vector.
791 */
792 template <typename... Args>
793 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator emplace(const_iterator pos, Args&&... args) IPADDRESS_NOEXCEPT {
794 return insert_n(pos, 1, value_type{std::forward<Args>(args)...});
795 }
796
797 /**
798 * Inserts a new element at the end of the vector, constructed in-place with the given arguments.
799 *
800 * @tparam Args The argument types for constructing the element.
801 * @param[in] args The arguments for constructing the element.
802 * @return A reference to the inserted element.
803 * @remark The number of elements must not exceed the maximum size of the vector.
804 */
805 template <typename... Args>
806 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference emplace_back(Args&&... args) IPADDRESS_NOEXCEPT {
807 assert(size() < max_size());
808 _data[_size++] = value_type{std::forward<Args>(args)...};
809 return _data[_size - 1];
810 }
811
812 /**
813 * Inserts a new element at the end of the vector, constructed in-place with the given arguments.
814 *
815 * @tparam Args The argument types for constructing the element.
816 * @param[in] args The arguments for constructing the element.
817 * @return A pointer to the inserted element, or nullptr if the insertion failed.
818 */
819 template <typename... Args>
820 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE pointer try_emplace_back(Args&&... args) IPADDRESS_NOEXCEPT {
821 if (size() < max_size()) {
822 _data[_size] = value_type{std::forward<Args>(args)...};
823 return &_data[_size++];
824 } else {
825 return nullptr;
826 }
827 }
828
829 /**
830 * Inserts a new element at the end of the vector, constructed in-place with the given arguments.
831 *
832 * @tparam Args The argument types for constructing the element.
833 * @param[in] args The arguments for constructing the element.
834 * @return A reference to the inserted element.
835 * @remark The condition size() < capacity() must hold true before calling this function. Otherwise, the behavior is undefined.
836 */
837 template <typename... Args>
838 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference unchecked_emplace_back(Args&&... args) IPADDRESS_NOEXCEPT {
839 _data[_size++] = value_type{std::forward<Args>(args)...};
840 return _data[_size - 1];
841 }
842
843 /**
844 * Adds a new element at the end of the vector.
845 *
846 * @param[in] value The value to add.
847 * @return A reference to the added element.
848 * @remark The number of elements must not exceed the maximum size of the vector.
849 */
850 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference push_back(const_reference value) IPADDRESS_NOEXCEPT {
851 assert(size() < max_size());
852 _data[_size++] = value;
853 return _data[_size - 1];
854 }
855
856 /**
857 * Adds a new element at the end of the vector.
858 *
859 * @param[in] value The value to add.
860 * @return A reference to the added element.
861 * @remark The number of elements must not exceed the maximum size of the vector.
862 */
863 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference push_back(value_type&& value) IPADDRESS_NOEXCEPT {
864 assert(size() < max_size());
865 _data[_size++] = std::move(value);
866 return _data[_size - 1];
867 }
868
869 /**
870 * Adds a new element at the end of the vector.
871 *
872 * @param[in] value The value to add.
873 * @return A pointer to the added element, or nullptr if the insertion failed.
874 */
875 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE pointer try_push_back(const_reference value) IPADDRESS_NOEXCEPT {
876 if (size() < max_size()) {
877 _data[_size] = value;
878 return &_data[_size++];
879 } else {
880 return nullptr;
881 }
882 }
883
884 /**
885 * Adds a new element at the end of the vector.
886 *
887 * @param[in] value The value to add.
888 * @return A pointer to the added element, or nullptr if the insertion failed.
889 */
890 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE pointer try_push_back(value_type&& value) IPADDRESS_NOEXCEPT {
891 if (size() < max_size()) {
892 _data[_size] = std::move(value);
893 return &_data[_size++];
894 } else {
895 return nullptr;
896 }
897 }
898
899 /**
900 * Adds a new element at the end of the vector without checking the size.
901 *
902 * @param[in] value The value to add.
903 * @return A reference to the added element.
904 * @remark The condition size() < capacity() must hold true before calling this function. Otherwise, the behavior is undefined.
905 */
906 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference unchecked_push_back(const_reference value) IPADDRESS_NOEXCEPT {
907 _data[_size++] = value;
908 return _data[_size - 1];
909 }
910
911 /**
912 * Adds a new element at the end of the vector without checking the size.
913 *
914 * @param[in] value The value to add.
915 * @return A reference to the added element.
916 * @remark The condition size() < capacity() must hold true before calling this function. Otherwise, the behavior is undefined.
917 */
918 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference unchecked_push_back(value_type&& value) IPADDRESS_NOEXCEPT {
919 _data[_size++] = std::move(value);
920 return _data[_size - 1];
921 }
922
923 /**
924 * Removes the last element from the vector.
925 *
926 * @remark The vector must not be empty before calling this function.
927 */
929 assert(!empty());
930 --_size;
931 }
932
933 /**
934 * Removes all elements from the vector.
935 *
936 * @remark The vector will be empty after calling this function.
937 */
939 _size = 0;
940 }
941
942 /**
943 * Removes the element at the specified position.
944 *
945 * @param[in] pos The position of the element to remove.
946 * @return An iterator to the next element after the removed element.
947 * @remark The vector must not be empty before calling this function.
948 */
949 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator erase(const_iterator pos) IPADDRESS_NOEXCEPT {
950 return erase(pos, pos + 1);
951 }
952
953 /**
954 * Remove range of elements from the vector.
955 *
956 * @param[in] first The position of the first element to remove.
957 * @param[in] last The position of the last element to remove.
958 * @return An iterator to the next element after the last removed element.
959 */
960 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator erase(const_iterator first, const_iterator last) IPADDRESS_NOEXCEPT {
961 assert(first >= begin() && last <= end() && first <= last);
962 const auto count = internal::distance(first, last);
963 const auto index = internal::distance(cbegin(), first);
964 for (size_type i = index; i < _size - count; ++i) {
965 _data[i] = std::move(_data[i + count]);
966 }
967 _size -= count;
968 return begin() + index;
969 }
970
971 /**
972 * Swaps the contents of this vector with another vector.
973 *
974 * @param[in] other The other vector to swap with.
975 */
977 const auto tmp_size = _size;
978 _size = other._size;
979 other._size = tmp_size;
980 auto size = _size < other._size ? other._size : _size;
981 for (size_type i = 0; i < size; ++i) {
982 const auto tmp_value = _data[i];
983 _data[i] = other._data[i];
984 other._data[i] = tmp_value;
985 }
986 }
987
988 private:
989 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert_n(const_iterator pos, size_type n, const_reference value) IPADDRESS_NOEXCEPT {
990 assert(pos >= begin() && pos <= end());
991 if (pos == end()) {
992 assert(_size + n <= max_size());
993 auto result = end();
994 for (size_type i = 0; i < n; ++i) {
995 _data[_size++] = value;
996 }
997 return result;
998 } else {
999 const auto index = internal::distance(cbegin(), pos);
1000 assert(_size + n <= max_size());
1001 for (auto i = difference_type(_size) - 1; i >= index; --i) {
1002 _data[i + difference_type(n)] = _data[i];
1003 }
1004 for (auto i = 0; i < difference_type(n); ++i) {
1005 _data[index + i] = value;
1006 }
1007 _size += n;
1008 return begin() + index;
1009 }
1010 }
1011
1012 template <typename It>
1013 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert_iterators(const_iterator pos, It first, It last) IPADDRESS_NOEXCEPT {
1014 assert(pos >= begin() && pos <= end() && first <= last);
1015 if (pos == end()) {
1016 auto result = end();
1017 for (auto it = first; it != last; ++it) {
1018 assert(_size < max_size());
1019 _data[_size++] = *it;
1020 }
1021 return result;
1022 } else {
1023 const auto count = internal::distance(first, last);
1024 const auto index = internal::distance(cbegin(), pos);
1025 assert(_size + count <= max_size());
1026 for (auto i = difference_type(_size) - 1; i >= index; --i) {
1027 _data[i + count] = _data[i];
1028 }
1029 for (auto i = 0; i < count; ++i) {
1030 _data[index + i] = *first++;
1031 }
1032 _size += count;
1033 return begin() + index;
1034 }
1035 }
1036
1037 value_type _data[N]{};
1038 size_type _size{};
1039 }; // fixed_vector
1040
1041 IPADDRESS_EXPORT template <typename T>
1042 class fixed_vector<T, 0> {
1043 public:
1044 using value_type = T;
1045 using size_type = size_t;
1046 using difference_type = ptrdiff_t;
1047 using pointer = value_type*;
1048 using const_pointer = const value_type*;
1049 using reference = value_type&;
1050 using const_reference = const value_type&;
1051 using iterator = fixed_vector_iterator<value_type>;
1052 using const_iterator = fixed_vector_iterator<const value_type>;
1053 using reverse_iterator = std::reverse_iterator<iterator>;
1054 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1055
1056 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_vector() IPADDRESS_NOEXCEPT = default;
1057
1058 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE explicit fixed_vector(size_type n /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
1059 assert(n == 0 && "fixed_vector<T, 0> cannot be constructed with a size.");
1060 }
1061
1062 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_vector(size_type n /* NOLINT(misc-unused-parameters) */, const_reference /*value*/) IPADDRESS_NOEXCEPT {
1063 assert(n == 0 && "fixed_vector<T, 0> cannot be constructed with a size and value.");
1064 }
1065
1066 template <class It>
1067 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_vector(It first /* NOLINT(misc-unused-parameters) */, It last /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
1068 assert(first == last && "fixed_vector<T, 0> cannot be constructed with a iterators.");
1069 }
1070
1071 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE fixed_vector(std::initializer_list<value_type> init_list /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
1072 assert(init_list.size() == 0 && "fixed_vector<T, 0> cannot be constructed with an initializer list.");
1073 }
1074
1075 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void assign(size_type n /* NOLINT(misc-unused-parameters) */, const_reference /*value*/) IPADDRESS_NOEXCEPT {
1076 assert(n == 0 && "fixed_vector<T, 0> cannot assign a size.");
1077 }
1078
1079 template <class It>
1080 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void assign(It first /* NOLINT(misc-unused-parameters) */, It last /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
1081 assert(first == last && "fixed_vector<T, 0> cannot assign from iterators.");
1082 }
1083
1084 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void assign(std::initializer_list<value_type> init_list /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
1085 assert(init_list.size() == 0 && "fixed_vector<T, 0> cannot assign from an initializer list.");
1086 }
1087
1088 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference at(size_type) IPADDRESS_NOEXCEPT {
1089 assert(!"fixed_vector<T, 0> cannot access elements.");
1090 return *data();
1091 }
1092
1093 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference at(size_type) const IPADDRESS_NOEXCEPT {
1094 assert(!"fixed_vector<T, 0> cannot access elements.");
1095 return *data();
1096 }
1097
1098 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference operator[](size_type) IPADDRESS_NOEXCEPT {
1099 assert(!"fixed_vector<T, 0> cannot access elements.");
1100 return *data();
1101 }
1102
1103 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference operator[](size_type) const IPADDRESS_NOEXCEPT {
1104 assert(!"fixed_vector<T, 0> cannot access elements.");
1105 return *data();
1106 }
1107
1108 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference front() IPADDRESS_NOEXCEPT {
1109 assert(!"fixed_vector<T, 0> cannot access elements.");
1110 return *data();
1111 }
1112
1113 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference front() const IPADDRESS_NOEXCEPT {
1114 assert(!"fixed_vector<T, 0> cannot access elements.");
1115 return *data();
1116 }
1117
1118 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference back() IPADDRESS_NOEXCEPT {
1119 assert(!"fixed_vector<T, 0> cannot access elements.");
1120 return *data();
1121 }
1122
1123 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reference back() const IPADDRESS_NOEXCEPT {
1124 assert(!"fixed_vector<T, 0> cannot access elements.");
1125 return *data();
1126 }
1127
1128 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE pointer data() IPADDRESS_NOEXCEPT {
1129 return nullptr;
1130 }
1131
1132 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_pointer data() const IPADDRESS_NOEXCEPT {
1133 return nullptr;
1134 }
1135
1136 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator begin() IPADDRESS_NOEXCEPT {
1137 return iterator(nullptr);
1138 }
1139
1140 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator begin() const IPADDRESS_NOEXCEPT {
1141 return const_iterator(nullptr);
1142 }
1143
1144 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator cbegin() const IPADDRESS_NOEXCEPT {
1145 return const_iterator(nullptr);
1146 }
1147
1148 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reverse_iterator rbegin() IPADDRESS_NOEXCEPT {
1149 return reverse_iterator(end());
1150 }
1151
1152 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator rbegin() const IPADDRESS_NOEXCEPT {
1153 return const_reverse_iterator(end());
1154 }
1155
1156 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator crbegin() const IPADDRESS_NOEXCEPT {
1157 return const_reverse_iterator(cend());
1158 }
1159
1160 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator end() IPADDRESS_NOEXCEPT {
1161 return iterator(nullptr);
1162 }
1163
1164 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator end() const IPADDRESS_NOEXCEPT {
1165 return const_iterator(nullptr);
1166 }
1167
1168 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator cend() const IPADDRESS_NOEXCEPT {
1169 return const_iterator(nullptr);
1170 }
1171
1172 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reverse_iterator rend() IPADDRESS_NOEXCEPT {
1173 return reverse_iterator(begin());
1174 }
1175
1176 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator rend() const IPADDRESS_NOEXCEPT {
1177 return const_reverse_iterator(begin());
1178 }
1179
1180 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator crend() const IPADDRESS_NOEXCEPT {
1181 return const_reverse_iterator(cbegin());
1182 }
1183
1184 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool empty() const IPADDRESS_NOEXCEPT {
1185 return true;
1186 }
1187
1188 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_type size() const IPADDRESS_NOEXCEPT {
1189 return 0;
1190 }
1191
1192 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_type max_size() IPADDRESS_NOEXCEPT {
1193 return 0;
1194 }
1195
1196 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_type capacity() IPADDRESS_NOEXCEPT {
1197 return 0;
1198 }
1199
1200 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void resize(size_type n /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
1201 assert(n == 0 && "fixed_vector<T, 0> cannot resize.");
1202 }
1203
1204 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void resize(size_type n /* NOLINT(misc-unused-parameters) */, const_reference /*value*/) IPADDRESS_NOEXCEPT {
1205 assert(n == 0 && "fixed_vector<T, 0> cannot resize.");
1206 }
1207
1208 static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void reserve(size_type n /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
1209 assert(n == 0 && "fixed_vector<T, 0> cannot reserve.");
1210 }
1211
1212 static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void shrink_to_fit() IPADDRESS_NOEXCEPT {
1213 }
1214
1215 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert(const_iterator, const_reference) IPADDRESS_NOEXCEPT {
1216 assert(!"fixed_vector<T, 0> cannot insert elements.");
1217 return iterator(nullptr);
1218 }
1219
1220 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert(const_iterator, value_type&&) IPADDRESS_NOEXCEPT {
1221 assert(!"fixed_vector<T, 0> cannot insert elements.");
1222 return iterator(nullptr);
1223 }
1224
1225 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert(const_iterator, size_type n /* NOLINT(misc-unused-parameters) */, const_reference) IPADDRESS_NOEXCEPT {
1226 assert(n == 0 && "fixed_vector<T, 0> cannot insert elements.");
1227 return iterator(nullptr);
1228 }
1229
1230 template <typename It>
1231 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert(const_iterator, It first /* NOLINT(misc-unused-parameters) */, It last /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
1232 assert(first == last && "fixed_vector<T, 0> cannot insert elements.");
1233 return iterator(nullptr);
1234 }
1235
1236 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator insert(const_iterator, std::initializer_list<value_type> init_list /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
1237 assert(init_list.size() == 0 && "fixed_vector<T, 0> cannot insert elements.");
1238 return iterator(nullptr);
1239 }
1240
1241 template <typename... Args>
1242 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator emplace(const_iterator, Args&&...) IPADDRESS_NOEXCEPT {
1243 assert(!"fixed_vector<T, 0> cannot emplace elements.");
1244 return iterator(nullptr);
1245 }
1246
1247 template <typename... Args>
1248 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference emplace_back(Args&&...) IPADDRESS_NOEXCEPT {
1249 assert(!"fixed_vector<T, 0> cannot emplace elements.");
1250 return *data();
1251 }
1252
1253 template <typename... Args>
1254 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE pointer try_emplace_back(Args&&...) IPADDRESS_NOEXCEPT {
1255 return nullptr;
1256 }
1257
1258 template <typename... Args>
1259 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference unchecked_emplace_back(Args&&...) IPADDRESS_NOEXCEPT {
1260 return *data();
1261 }
1262
1263 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference push_back(const_reference) IPADDRESS_NOEXCEPT {
1264 assert(!"fixed_vector<T, 0> cannot push back elements.");
1265 return *data();
1266 }
1267
1268 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference push_back(value_type&&) IPADDRESS_NOEXCEPT {
1269 assert(!"fixed_vector<T, 0> cannot push back elements.");
1270 return *data();
1271 }
1272
1273 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE pointer try_push_back(const_reference) IPADDRESS_NOEXCEPT {
1274 return nullptr;
1275 }
1276
1277 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE pointer try_push_back(value_type&&) IPADDRESS_NOEXCEPT {
1278 return nullptr;
1279 }
1280
1281 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference unchecked_push_back(const_reference) IPADDRESS_NOEXCEPT {
1282 return *data();
1283 }
1284
1285 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE reference unchecked_emplace_back(value_type&&) IPADDRESS_NOEXCEPT {
1286 return *data();
1287 }
1288
1289 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void pop_back() IPADDRESS_NOEXCEPT {
1290 assert(!"fixed_vector<T, 0> cannot pop back elements.");
1291 }
1292
1293 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void clear() IPADDRESS_NOEXCEPT {
1294 }
1295
1296 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator erase(const_iterator) IPADDRESS_NOEXCEPT {
1297 assert(!"fixed_vector<T, 0> cannot erase elements.");
1298 return iterator(nullptr);
1299 }
1300
1301 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator erase(const_iterator first /* NOLINT(misc-unused-parameters) */, const_iterator last /* NOLINT(misc-unused-parameters) */) IPADDRESS_NOEXCEPT {
1302 assert(first == last && "fixed_vector<T, 0> cannot erase elements.");
1303 return iterator(nullptr);
1304 }
1305
1306 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void swap(fixed_vector&) IPADDRESS_NOEXCEPT {
1307 }
1308 }; // fixed_vector<T, 0>
1309
1310 /**
1311 * Compares two fixed_vector objects for equality.
1312 *
1313 * Checks if the contents of \a lhs and \a rhs are equal, meaning they have the same
1314 * number of elements and each element in \a lhs compares equal with the element in \a rhs at the same position.
1315 *
1316 * @tparam T The type of the elements in the vector.
1317 * @tparam N1 The size of the first vector.
1318 * @tparam N2 The size of the second vector.
1319 * @param[in] lhs The first vector to compare.
1320 * @param[in] rhs The second vector to compare.
1321 * @return `true` if the vectors are equal; otherwise, `false`.
1322 */
1323 IPADDRESS_EXPORT template <typename T, size_t N1, size_t N2>
1324 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator==(const fixed_vector<T, N1>& lhs, const fixed_vector<T, N2>& rhs) IPADDRESS_NOEXCEPT {
1325 if (lhs.size() != rhs.size()) {
1326 return false;
1327 }
1328 for (size_t i = 0; i < lhs.size(); ++i) {
1329 if (lhs[i] != rhs[i]) {
1330 return false;
1331 }
1332 }
1333 return true;
1334 }
1335
1336 /**
1337 * Compares two fixed_vector objects for inequality.
1338 *
1339 * Checks if the contents of \a lhs and \a rhs are not equal, meaning they do not have the same
1340 * number of elements or there is at least one position at which the elements in \a lhs and \a rhs differ.
1341 *
1342 * @tparam T The type of the elements in the vector.
1343 * @tparam N1 The size of the first vector.
1344 * @tparam N2 The size of the second vector.
1345 * @param[in] lhs The first vector to compare.
1346 * @param[in] rhs The second vector to compare.
1347 * @return `true` if the vectors are not equal; otherwise, `false`.
1348 */
1349 IPADDRESS_EXPORT template <typename T, size_t N1, size_t N2>
1350 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator!=(const fixed_vector<T, N1>& lhs, const fixed_vector<T, N2>& rhs) IPADDRESS_NOEXCEPT {
1351 return !(lhs == rhs);
1352 }
1353
1354 #ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
1355
1356 /**
1357 * Compares the contents of two fixed vector lexicographically.
1358 *
1359 * Uses the three-way comparison operator (spaceship operator) to compare the contents of \a lhs and \a rhs.
1360 *
1361 * @tparam T The type of the elements in the vector.
1362 * @tparam N1 The size of the first vector.
1363 * @tparam N2 The size of the second vector.
1364 * @param[in] lhs The first vector to compare.
1365 * @param[in] rhs The second vector to compare.
1366 * @return A strong ordering result indicating the comparison result.
1367 */
1368 IPADDRESS_EXPORT template <typename T, size_t N1, size_t N2>
1369 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE std::strong_ordering operator<=>(const fixed_vector<T, N1>& lhs, const fixed_vector<T, N2>& rhs) IPADDRESS_NOEXCEPT {
1370 auto size = lhs.size() < rhs.size() ? lhs.size() : rhs.size();
1371 for (size_t i = 0; i < size; ++i) {
1372 if (auto cmp = lhs[i] <=> rhs[i]; cmp != std::strong_ordering::equivalent) {
1373 return cmp;
1374 }
1375 }
1376 return lhs.size() <=> rhs.size();
1377 }
1378
1379 #else // !IPADDRESS_HAS_SPACESHIP_OPERATOR
1380
1381 /**
1382 * Compares the contents of two fixed vector lexicographically.
1383 *
1384 * Checks if the contents of \a lhs are lexicographically less than the contents of \a rhs.
1385 *
1386 * @tparam T The type of the elements in the vector.
1387 * @tparam N1 The size of the first vector.
1388 * @tparam N2 The size of the second vector.
1389 * @param[in] lhs The first vector to compare.
1390 * @param[in] rhs The second vector to compare.
1391 * @return `true` if \a lhs is lexicographically less than \a rhs; otherwise, `false`.
1392 */
1393 IPADDRESS_EXPORT template <typename T, size_t N1, size_t N2>
1394 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator<(const fixed_vector<T, N1>& lhs, const fixed_vector<T, N2>& rhs) IPADDRESS_NOEXCEPT {
1395 auto size = lhs.size() < rhs.size() ? lhs.size() : rhs.size();
1396 for (size_t i = 0; i < size; ++i) {
1397 if (lhs[i] < rhs[i]) {
1398 return true;
1399 } else if (lhs[i] > rhs[i]) {
1400 return false;
1401 }
1402 }
1403 return lhs.size() < rhs.size();
1404 }
1405
1406 /**
1407 * Compares the contents of two fixed vector lexicographically.
1408 *
1409 * Checks if the contents of \a lhs are lexicographically greater than the contents of \a rhs.
1410 *
1411 * @tparam T The type of the elements in the vector.
1412 * @tparam N1 The size of the first vector.
1413 * @tparam N2 The size of the second vector.
1414 * @param[in] lhs The first vector to compare.
1415 * @param[in] rhs The second vector to compare.
1416 * @return `true` if \a lhs is lexicographically greater than \a rhs; otherwise, `false`.
1417 */
1418 IPADDRESS_EXPORT template <typename T, size_t N1, size_t N2>
1419 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator>(const fixed_vector<T, N1>& lhs, const fixed_vector<T, N2>& rhs) IPADDRESS_NOEXCEPT {
1420 return rhs < lhs;
1421 }
1422
1423 /**
1424 * Compares the contents of two fixed vector lexicographically.
1425 *
1426 * Checks if the contents of \a lhs are lexicographically less than or equal to the contents of \a rhs.
1427 *
1428 * @tparam T The type of the elements in the vector.
1429 * @tparam N1 The size of the first vector.
1430 * @tparam N2 The size of the second vector.
1431 * @param[in] lhs The first vector to compare.
1432 * @param[in] rhs The second vector to compare.
1433 * @return `true` if \a lhs is lexicographically less than or equal to \a rhs; otherwise, `false`.
1434 */
1435 IPADDRESS_EXPORT template <typename T, size_t N1, size_t N2>
1436 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator<=(const fixed_vector<T, N1>& lhs, const fixed_vector<T, N2>& rhs) IPADDRESS_NOEXCEPT {
1437 return !(rhs < lhs);
1438 }
1439
1440 /**
1441 * Compares the contents of two fixed vector lexicographically.
1442 *
1443 * Checks if the contents of \a lhs are lexicographically greater than or equal to the contents of \a rhs.
1444 *
1445 * @tparam T The type of the elements in the vector.
1446 * @tparam N1 The size of the first vector.
1447 * @tparam N2 The size of the second vector.
1448 * @param[in] lhs The first vector to compare.
1449 * @param[in] rhs The second vector to compare.
1450 * @return `true` if \a lhs is lexicographically greater than or equal to \a rhs; otherwise, `false`.
1451 */
1452 IPADDRESS_EXPORT template <typename T, size_t N1, size_t N2>
1453 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator>=(const fixed_vector<T, N1>& lhs, const fixed_vector<T, N2>& rhs) IPADDRESS_NOEXCEPT {
1454 return !(lhs < rhs);
1455 }
1456
1457 #endif // !IPADDRESS_HAS_SPACESHIP_OPERATOR
1458
1459 } // namespace IPADDRESS_NAMESPACE
1460
1461 #endif // IPADDRESS_FIXED_VECTOR_HPP
A fixed-size vector iterator class template.
Definition fixed-vector.hpp:53
constexpr inline bool operator<(const fixed_vector_iterator &it) const noexcept
Less than operator.
Definition fixed-vector.hpp:257
constexpr inline bool operator>(const fixed_vector_iterator &it) const noexcept
Greater than operator.
Definition fixed-vector.hpp:277
constexpr inline bool operator<=(const fixed_vector_iterator &it) const noexcept
Less than or equal to operator.
Definition fixed-vector.hpp:267
constexpr inline fixed_vector_iterator operator++(int) noexcept
Post-increment operator.
Definition fixed-vector.hpp:126
constexpr inline bool operator!=(const fixed_vector_iterator &it) const noexcept
Inequality operator.
Definition fixed-vector.hpp:232
constexpr inline fixed_vector_iterator & operator-=(difference_type n) noexcept
Subtraction assignment operator.
Definition fixed-vector.hpp:170
constexpr inline fixed_vector_iterator & operator--() noexcept
Pre-decrement operator.
Definition fixed-vector.hpp:137
constexpr inline fixed_vector_iterator operator--(int) noexcept
Post-decrement operator.
Definition fixed-vector.hpp:147
constexpr inline fixed_vector_iterator() noexcept=default
Default constructor.
constexpr inline fixed_vector_iterator & operator++() noexcept
Pre-increment operator.
Definition fixed-vector.hpp:116
constexpr inline bool operator>=(const fixed_vector_iterator &it) const noexcept
Greater than or equal to operator.
Definition fixed-vector.hpp:287
constexpr inline reference operator[](size_t n) const noexcept
Access operator.
Definition fixed-vector.hpp:107
friend constexpr inline fixed_vector_iterator operator+(difference_type n, const fixed_vector_iterator &it) noexcept
Addition operator.
Definition fixed-vector.hpp:192
constexpr inline fixed_vector_iterator(pointer ptr) noexcept
Constructs a fixed_vector_iterator from a pointer.
Definition fixed-vector.hpp:71
constexpr inline fixed_vector_iterator operator+(difference_type n) const noexcept
Addition operator.
Definition fixed-vector.hpp:181
constexpr inline bool operator==(const fixed_vector_iterator &it) const noexcept
Equality operator.
Definition fixed-vector.hpp:222
constexpr inline pointer operator->() const noexcept
Pointer access operator.
Definition fixed-vector.hpp:97
constexpr inline fixed_vector_iterator & operator+=(difference_type n) noexcept
Addition assignment operator.
Definition fixed-vector.hpp:159
constexpr inline fixed_vector_iterator operator-(difference_type n) const noexcept
Subtraction operator.
Definition fixed-vector.hpp:202
constexpr inline reference operator*() const noexcept
Dereference operator.
Definition fixed-vector.hpp:88
constexpr inline fixed_vector_iterator(const fixed_vector_iterator< U > &it) noexcept
Constructs a const-compatible fixed_vector_iterator from a non-const fixed_vector_iterator.
Definition fixed-vector.hpp:80
constexpr inline difference_type operator-(const fixed_vector_iterator &it) const noexcept
Subtraction operator.
Definition fixed-vector.hpp:212
A fixed-size vector class template.
Definition fixed-vector.hpp:308
constexpr inline reference push_back(value_type &&value) noexcept
Adds a new element at the end of the vector.
Definition fixed-vector.hpp:863
constexpr inline iterator end() noexcept
Returns an iterator to the element following the last element.
Definition fixed-vector.hpp:576
constexpr inline iterator insert(const_iterator pos, It first, It last) noexcept
Inserts range of elements at the specified position.
Definition fixed-vector.hpp:767
static constexpr inline size_type max_size() noexcept
Returns the maximum number of elements that the container can hold.
Definition fixed-vector.hpp:648
constexpr inline fixed_vector(It first, It last) noexcept
Constructs a fixed_vector from a range of elements.
Definition fixed-vector.hpp:358
constexpr inline iterator insert(const_iterator pos, size_type n, const_reference value) noexcept
Inserts copies of the given value at the specified position.
Definition fixed-vector.hpp:752
constexpr inline const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the first element.
Definition fixed-vector.hpp:567
constexpr inline const_reference at(size_type n) const noexcept
Accesses an element by index.
Definition fixed-vector.hpp:432
constexpr inline reference unchecked_push_back(value_type &&value) noexcept
Adds a new element at the end of the vector without checking the size.
Definition fixed-vector.hpp:918
constexpr inline reference operator[](size_type n) noexcept
Accesses an element by index.
Definition fixed-vector.hpp:444
constexpr inline pointer data() noexcept
Returns a pointer to the underlying array.
Definition fixed-vector.hpp:504
constexpr inline void clear() noexcept
Removes all elements from the vector.
Definition fixed-vector.hpp:938
constexpr inline reference front() noexcept
Accesses the first element in the vector.
Definition fixed-vector.hpp:464
constexpr inline void assign(std::initializer_list< value_type > init_list) noexcept
Replaces the contents with the elements in the specified initializer list.
Definition fixed-vector.hpp:409
constexpr inline const_iterator begin() const noexcept
Return const iterator to the first element.
Definition fixed-vector.hpp:531
constexpr inline reverse_iterator rbegin() noexcept
Returns an reverse iterator to the first element.
Definition fixed-vector.hpp:549
constexpr inline bool empty() const noexcept
Determines whether the container is empty.
Definition fixed-vector.hpp:630
constexpr inline const_reverse_iterator crend() const noexcept
Returns a const reverse iterator to the element following the last element.
Definition fixed-vector.hpp:621
constexpr inline iterator erase(const_iterator pos) noexcept
Removes the element at the specified position.
Definition fixed-vector.hpp:949
constexpr inline void swap(fixed_vector &other) noexcept
Swaps the contents of this vector with another vector.
Definition fixed-vector.hpp:976
constexpr inline const_reference front() const noexcept
Accesses the first element in the vector.
Definition fixed-vector.hpp:474
constexpr inline const_pointer data() const noexcept
Returns a const pointer to the underlying array (const version).
Definition fixed-vector.hpp:513
constexpr inline reference emplace_back(Args &&... args) noexcept
Inserts a new element at the end of the vector, constructed in-place with the given arguments.
Definition fixed-vector.hpp:806
constexpr inline iterator emplace(const_iterator pos, Args &&... args) noexcept
Inserts a new element at the specified position, constructed in-place with the given arguments.
Definition fixed-vector.hpp:793
constexpr inline size_type size() const noexcept
Returns the number of elements in the container.
Definition fixed-vector.hpp:639
constexpr inline pointer try_push_back(value_type &&value) noexcept
Adds a new element at the end of the vector.
Definition fixed-vector.hpp:890
constexpr inline void pop_back() noexcept
Removes the last element from the vector.
Definition fixed-vector.hpp:928
constexpr inline reference at(size_type n) noexcept
Accesses an element by index.
Definition fixed-vector.hpp:420
constexpr inline reference back() noexcept
Accesses the last element in the vector.
Definition fixed-vector.hpp:484
constexpr inline fixed_vector(size_type n) noexcept
Constructs a fixed_vector with the specified number of default-initialized elements.
Definition fixed-vector.hpp:333
constexpr inline const_reverse_iterator rend() const noexcept
Returns a const reverse iterator to the element following the last element.
Definition fixed-vector.hpp:612
constexpr inline const_iterator cend() const noexcept
Returns a const iterator to the element following the last element.
Definition fixed-vector.hpp:594
constexpr inline pointer try_emplace_back(Args &&... args) noexcept
Inserts a new element at the end of the vector, constructed in-place with the given arguments.
Definition fixed-vector.hpp:820
constexpr inline reference unchecked_emplace_back(Args &&... args) noexcept
Inserts a new element at the end of the vector, constructed in-place with the given arguments.
Definition fixed-vector.hpp:838
constexpr inline iterator insert(const_iterator pos, const_reference value) noexcept
Inserts copies of the given value at the specified position.
Definition fixed-vector.hpp:727
static constexpr inline void shrink_to_fit() noexcept
Shrinks the container to fit its current size.
Definition fixed-vector.hpp:716
constexpr inline reverse_iterator rend() noexcept
Returns a reverse iterator to the element following the last element.
Definition fixed-vector.hpp:603
constexpr inline const_iterator cbegin() const noexcept
Return const iterator to the first element.
Definition fixed-vector.hpp:540
constexpr inline void resize(size_type n) noexcept
Resizes the container to the specified size.
Definition fixed-vector.hpp:670
constexpr inline const_iterator end() const noexcept
Returns a const iterator to the element following the last element.
Definition fixed-vector.hpp:585
constexpr inline fixed_vector(size_type n, const_reference value) noexcept
Constructs a fixed_vector with the specified number of elements initialized to the given value.
Definition fixed-vector.hpp:345
constexpr inline pointer try_push_back(const_reference value) noexcept
Adds a new element at the end of the vector.
Definition fixed-vector.hpp:875
constexpr inline iterator begin() noexcept
Return iterator to the first element.
Definition fixed-vector.hpp:522
constexpr inline void assign(size_type n, const_reference value) noexcept
Replaces the contents with the specified number of copies of the given value.
Definition fixed-vector.hpp:378
constexpr inline const_reference operator[](size_type n) const noexcept
Accesses an element by index.
Definition fixed-vector.hpp:455
constexpr inline reference unchecked_push_back(const_reference value) noexcept
Adds a new element at the end of the vector without checking the size.
Definition fixed-vector.hpp:906
constexpr inline void resize(size_type n, const_reference value) noexcept
Resizes the container to the specified size and initializes new elements with the given value.
Definition fixed-vector.hpp:684
static constexpr inline size_type capacity() noexcept
Returns the maximum number of elements that the container can hold.
Definition fixed-vector.hpp:657
constexpr inline iterator insert(const_iterator pos, value_type &&value) noexcept
Moves the given value at the specified position.
Definition fixed-vector.hpp:739
constexpr inline void assign(It first, It last) noexcept
Replaces the contents with the elements in the specified range.
Definition fixed-vector.hpp:395
constexpr inline const_reverse_iterator rbegin() const noexcept
Returns a const iterator to the first element.
Definition fixed-vector.hpp:558
constexpr inline iterator erase(const_iterator first, const_iterator last) noexcept
Remove range of elements from the vector.
Definition fixed-vector.hpp:960
constexpr inline iterator insert(const_iterator pos, std::initializer_list< value_type > init_list) noexcept
Inserts initializer list of elements at the specified position.
Definition fixed-vector.hpp:779
constexpr inline fixed_vector() noexcept=default
Default constructor.
constexpr inline reference push_back(const_reference value) noexcept
Adds a new element at the end of the vector.
Definition fixed-vector.hpp:850
constexpr inline fixed_vector(std::initializer_list< value_type > init_list) noexcept
Constructs a fixed_vector from an initializer list.
Definition fixed-vector.hpp:368
static constexpr inline void reserve(size_type n) noexcept
Reserves space for the specified number of elements.
Definition fixed-vector.hpp:705
constexpr inline const_reference back() const noexcept
Accesses the last element in the vector.
Definition fixed-vector.hpp:494
#define IPADDRESS_EXPORT
Definition config.hpp:45
#define IPADDRESS_NODISCARD
Definition config.hpp:101
#define IPADDRESS_FORCE_INLINE
Definition config.hpp:115
#define IPADDRESS_NAMESPACE
Definition config.hpp:41
#define IPADDRESS_NOEXCEPT
Definition config.hpp:92
constexpr inline bool operator==(const fixed_vector< T, N1 > &lhs, const fixed_vector< T, N2 > &rhs) noexcept
Compares two fixed_vector objects for equality.
Definition fixed-vector.hpp:1324
constexpr inline bool operator!=(const fixed_vector< T, N1 > &lhs, const fixed_vector< T, N2 > &rhs) noexcept
Compares two fixed_vector objects for inequality.
Definition fixed-vector.hpp:1350
constexpr inline bool operator>(const fixed_vector< T, N1 > &lhs, const fixed_vector< T, N2 > &rhs) noexcept
Compares the contents of two fixed vector lexicographically.
Definition fixed-vector.hpp:1419
constexpr inline bool operator>=(const fixed_vector< T, N1 > &lhs, const fixed_vector< T, N2 > &rhs) noexcept
Compares the contents of two fixed vector lexicographically.
Definition fixed-vector.hpp:1453
constexpr inline bool operator<=(const fixed_vector< T, N1 > &lhs, const fixed_vector< T, N2 > &rhs) noexcept
Compares the contents of two fixed vector lexicographically.
Definition fixed-vector.hpp:1436
constexpr inline bool operator<(const fixed_vector< T, N1 > &lhs, const fixed_vector< T, N2 > &rhs) noexcept
Compares the contents of two fixed vector lexicographically.
Definition fixed-vector.hpp:1394