17 #include <initializer_list>
22 COMMS_GNU_WARNING_PUSH
24 #if COMMS_IS_GCC_12 && defined(NDEBUG)
28 COMMS_GNU_WARNING_DISABLE(
"-Warray-bounds")
41 class StaticVectorBase
45 using size_type = std::size_t;
47 using const_reference =
const T&;
49 using const_pointer =
const T*;
50 using iterator = pointer;
51 using const_iterator = const_pointer;
52 using reverse_iterator = std::reverse_iterator<iterator>;
53 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
56 typename std::aligned_storage<
58 std::alignment_of<T>::value
61 static_assert(
sizeof(CellType) ==
sizeof(T),
"Type T must be padded");
63 StaticVectorBase(CellType* dataPtr, std::size_t cap)
69 ~StaticVectorBase() noexcept
74 StaticVectorBase(
const StaticVectorBase&) =
delete;
75 StaticVectorBase& operator=(
const StaticVectorBase&) =
delete;
78 std::size_t size()
const
83 std::size_t capacity()
const
95 COMMS_MSVC_WARNING_SUPPRESS(4189)
96 auto& lastElem = back();
104 return elem(size() - 1);
107 const T& back()
const
110 return elem(size() - 1);
119 const T& front()
const
125 template <
typename TIter>
126 void assign(TIter from, TIter to)
129 for (
auto iter = from; iter != to; ++iter) {
130 if (capacity() <= size()) {
131 static constexpr
bool Not_all_elements_are_copied =
false;
132 static_cast<void>(Not_all_elements_are_copied);
137 new (cellPtr(size())) T(*(
reinterpret_cast<const T*
>(&*iter)));
142 void fill(std::size_t count,
const T& value)
146 for (
auto idx = 0U; idx < count; ++idx) {
147 new (cellPtr(idx)) T(value);
153 for (
auto idx = 0U; idx < size(); ++idx) {
169 const T* begin()
const
174 const T* cbegin()
const
185 return begin() + size();
193 const T* cend()
const
195 return cbegin() + size();
198 T& at(std::size_t pos)
204 const T& at(std::size_t pos)
const
210 T& operator[](std::size_t pos)
215 const T& operator[](std::size_t pos)
const
229 const T* data()
const
238 template <
typename U>
239 T* insert(
const T* pos, U&& value)
244 push_back(std::forward<U>(value));
249 push_back(std::move(back()));
250 auto* insertIter = begin() + std::distance(cbegin(), pos);
251 std::move_backward(insertIter, end() - 2, end() - 1);
252 *insertIter = std::forward<U>(value);
256 T* insert(
const T* pos, std::size_t count,
const T& value)
260 auto dist = std::distance(cbegin(), pos);
261 COMMS_ASSERT((0 <= dist) &&
static_cast<std::size_t
>(dist) < size());
262 auto* posIter = begin() + dist;
263 if (end() <= posIter) {
272 auto tailCount =
static_cast<std::size_t
>(std::distance(posIter, end()));
273 if (count <= tailCount) {
274 auto pushBegIter = end() - count;
275 auto pushEndIter = end();
276 for (
auto iter = pushBegIter; iter != pushEndIter; ++iter) {
277 push_back(std::move(*iter));
280 auto moveBegIter = posIter;
281 auto moveEndIter = moveBegIter + (tailCount - count);
284 COMMS_GNU_WARNING_PUSH
285 #if COMMS_IS_GCC_12 && defined(NDEBUG)
288 COMMS_GNU_WARNING_DISABLE(
"-Wstringop-overflow")
290 std::move_backward(moveBegIter, moveEndIter, pushEndIter);
291 COMMS_GNU_WARNING_POP
293 auto* assignBegIter = posIter;
294 auto* assignEndIter = assignBegIter + count;
295 for (
auto iter = assignBegIter; iter != assignEndIter; ++iter) {
301 auto pushValueCount = count - tailCount;
302 for (
auto idx = 0U; idx < pushValueCount; ++idx) {
306 auto* pushBegIter = posIter;
307 auto* pushEndIter = pushBegIter + tailCount;
308 for (
auto iter = pushBegIter; iter != pushEndIter; ++iter) {
309 push_back(std::move(*iter));
312 auto assignBegIter = posIter;
313 auto assignEndIter = assignBegIter + tailCount;
314 for (
auto iter = assignBegIter; iter != assignEndIter; ++iter) {
320 template <
typename TIter>
321 T* insert(
const T* pos, TIter from, TIter to)
323 using Tag =
typename std::iterator_traits<TIter>::iterator_category;
324 return insert_internal(pos, from, to, Tag());
327 template <
typename... TArgs>
328 T* emplace(
const T* iter, TArgs&&... args)
330 auto* insertIter = begin() + std::distance(cbegin(), iter);
331 if (iter == cend()) {
332 emplace_back(std::forward<TArgs>(args)...);
337 push_back(std::move(back()));
338 std::move_backward(insertIter, end() - 2, end() - 1);
340 new (insertIter) T(std::forward<TArgs>(args)...);
344 T* erase(
const T* from,
const T* to)
350 auto tailCount =
static_cast<std::size_t
>(std::distance(to, cend()));
351 auto eraseCount =
static_cast<std::size_t
>(std::distance(from, to));
353 auto* moveSrc = begin() + std::distance(cbegin(), to);
354 auto* moveDest = begin() + std::distance(cbegin(), from);
355 std::move(moveSrc, end(), moveDest);
357 auto* eraseFrom = moveDest + tailCount;
358 auto* eraseTo = end();
361 COMMS_ASSERT(
static_cast<std::size_t
>(std::distance(eraseFrom, eraseTo)) == eraseCount);
362 for (
auto iter = eraseFrom; iter != eraseTo; ++iter) {
369 template <
typename U>
370 void push_back(U&& value)
373 new (cellPtr(size())) T(std::forward<U>(value));
377 template <
typename... TArgs>
378 void emplace_back(TArgs&&... args)
381 new (cellPtr(size())) T(std::forward<TArgs>(args)...);
385 void resize(std::size_t count,
const T& value)
387 if (count < size()) {
388 erase(begin() + count, end());
393 while (size() < count) {
398 void swap(StaticVectorBase<T>& other)
400 auto swapSize = std::min(other.size(), size());
401 for (
auto idx = 0U; idx < swapSize; ++idx) {
402 std::swap(this->
operator[](idx), other[idx]);
405 auto otherSize = other.size();
406 auto thisSize = size();
408 if (otherSize == thisSize) {
412 if (otherSize < thisSize) {
413 auto limit = std::min(thisSize, other.capacity());
414 for (
auto idx = swapSize; idx < limit; ++idx) {
415 new (other.cellPtr(idx)) T(std::move(elem(idx)));
418 other.size_ = thisSize;
419 erase(begin() + otherSize, end());
423 auto limit = std::min(otherSize, capacity());
424 for (
auto idx = swapSize; idx < limit; ++idx) {
425 new (cellPtr(idx)) T(std::move(other.elem(idx)));
428 other.erase(other.begin() + thisSize, other.end());
432 CellType& cell(std::size_t idx)
438 const CellType& cell(std::size_t idx)
const
444 CellType* cellPtr(std::size_t idx)
450 T& elem(std::size_t idx)
452 return reinterpret_cast<T&
>(cell(idx));
455 const T& elem(std::size_t idx)
const
457 return reinterpret_cast<const T&
>(cell(idx));
460 template <
typename TIter>
461 T* insert_random_access(
const T* pos, TIter from, TIter to)
464 auto* posIter = begin() + std::distance(cbegin(), pos);
465 if (end() <= posIter) {
466 for (; from != to; ++from) {
473 auto count =
static_cast<std::size_t
>(std::distance(from, to));
475 auto tailCount =
static_cast<std::size_t
>(std::distance(posIter, end()));
476 if (count <= tailCount) {
477 auto pushBegIter = end() - count;
478 auto pushEndIter = end();
479 for (
auto iter = pushBegIter; iter != pushEndIter; ++iter) {
480 push_back(std::move(*iter));
483 auto moveBegIter = posIter;
484 auto moveEndIter = moveBegIter + (tailCount - count);
486 std::move_backward(moveBegIter, moveEndIter, pushEndIter);
488 auto* assignBegIter = posIter;
489 auto* assignEndIter = assignBegIter + count;
490 for (
auto iter = assignBegIter; iter != assignEndIter; ++iter) {
497 auto pushValueCount = count - tailCount;
498 auto pushInsertedBegIter = to - pushValueCount;
499 for (
auto idx = 0U; idx < pushValueCount; ++idx) {
500 push_back(*pushInsertedBegIter);
501 ++pushInsertedBegIter;
504 auto* pushBegIter = posIter;
505 auto* pushEndIter = pushBegIter + tailCount;
506 for (
auto iter = pushBegIter; iter != pushEndIter; ++iter) {
507 push_back(std::move(*iter));
510 auto assignBegIter = posIter;
511 auto assignEndIter = assignBegIter + tailCount;
512 for (
auto iter = assignBegIter; iter != assignEndIter; ++iter) {
520 template <
typename TIter>
521 T* insert_input(
const T* pos, TIter from, TIter to)
524 for (; from != to; ++from) {
525 if (ret ==
nullptr) {
526 ret = begin() + std::distance(cbegin(), pos);
534 template <
typename TIter>
535 T* insert_internal(
const T* pos, TIter from, TIter to, std::random_access_iterator_tag)
537 return insert_random_access(pos, from, to);
540 template <
typename TIter>
541 T* insert_internal(
const T* pos, TIter from, TIter to, std::input_iterator_tag)
543 return insert_input(pos, from, to);
547 CellType* data_ =
nullptr;
548 std::size_t capacity_ = 0;
549 std::size_t size_ = 0;
552 template <
typename T, std::
size_t TSize>
553 struct StaticVectorStorageBase
555 using ElementType =
typename std::aligned_storage<
557 std::alignment_of<T>::value
560 using StorageType = std::array<ElementType, TSize>;
564 template <
typename T, std::
size_t TSize>
565 class StaticVectorGeneric :
566 public StaticVectorStorageBase<T, TSize>,
567 public StaticVectorBase<T>
569 using StorageBase = StaticVectorStorageBase<T, TSize>;
570 using Base = StaticVectorBase<T>;
573 using value_type =
typename Base::value_type;
574 using size_type =
typename Base::size_type;
575 using difference_type =
typename StorageBase::StorageType::difference_type;
576 using reference =
typename Base::reference;
577 using const_reference =
typename Base::const_reference;
578 using pointer =
typename Base::pointer;
579 using const_pointer =
typename Base::const_pointer;
580 using iterator =
typename Base::iterator;
581 using const_iterator =
typename Base::const_iterator;
582 using reverse_iterator =
typename Base::reverse_iterator;
583 using const_reverse_iterator =
typename Base::const_reverse_iterator;
585 StaticVectorGeneric()
586 : Base(StorageBase::data_.data(), StorageBase::data_.size())
590 StaticVectorGeneric(size_type count,
const T& value)
591 : Base(StorageBase::data_.data(), StorageBase::data_.size())
596 explicit StaticVectorGeneric(size_type count)
597 : Base(StorageBase::data_.data(), StorageBase::data_.size())
601 Base::emplace_back();
606 template <
typename TIter>
607 StaticVectorGeneric(TIter from, TIter to)
608 : Base(StorageBase::data_.data(), StorageBase::data_.size())
613 template <std::
size_t TOtherSize>
614 StaticVectorGeneric(
const StaticVectorGeneric<T, TOtherSize>& other)
615 : Base(StorageBase::data_.data(), StorageBase::data_.size())
617 assign(other.begin(), other.end());
620 StaticVectorGeneric(
const StaticVectorGeneric& other)
621 : Base(StorageBase::data_.data(), StorageBase::data_.size())
623 assign(other.begin(), other.end());
626 StaticVectorGeneric(std::initializer_list<value_type> init)
627 : Base(StorageBase::data_.data(), StorageBase::data_.size())
629 assign(init.begin(), init.end());
632 ~StaticVectorGeneric() noexcept = default;
634 StaticVectorGeneric& operator=(const StaticVectorGeneric& other)
636 if (&other ==
this) {
640 assign(other.begin(), other.end());
644 template <std::
size_t TOtherSize>
645 StaticVectorGeneric& operator=(
const StaticVectorGeneric<T, TOtherSize>& other)
647 assign(other.cbegin(), other.cend());
651 StaticVectorGeneric& operator=(std::initializer_list<value_type> init)
657 void assign(size_type count,
const T& value)
660 Base::fill(count, value);
663 template <
typename TIter>
664 void assign(TIter from, TIter to)
669 void assign(std::initializer_list<value_type> init)
671 assign(init.begin(), init.end());
674 void reserve(size_type new_cap)
676 static_cast<void>(new_cap);
681 template <
typename TOrig,
typename TCast, std::
size_t TSize>
682 class StaticVectorCasted :
public StaticVectorGeneric<TCast, TSize>
684 using Base = StaticVectorGeneric<TCast, TSize>;
685 static_assert(
sizeof(TOrig) ==
sizeof(TCast),
"The sizes are not equal");
688 using value_type = TOrig;
689 using size_type =
typename Base::size_type;
690 using difference_type =
typename Base::difference_type;
691 using reference = value_type&;
692 using const_reference =
const value_type&;
693 using pointer = value_type*;
694 using const_pointer =
const value_type*;
695 using iterator = pointer;
696 using const_iterator = const_pointer;
698 StaticVectorCasted() =
default;
700 StaticVectorCasted(size_type count, const_reference& value)
701 : Base(count, *(reinterpret_cast<typename Base::const_pointer>(&value)))
705 explicit StaticVectorCasted(size_type count)
710 template <
typename TIter>
711 StaticVectorCasted(TIter from, TIter to)
716 template <std::
size_t TOtherSize>
717 StaticVectorCasted(
const StaticVectorCasted<TOrig, TCast, TOtherSize>& other)
722 StaticVectorCasted(
const StaticVectorCasted& other)
727 StaticVectorCasted(std::initializer_list<value_type> init)
728 : Base(init.begin(), init.end())
732 ~StaticVectorCasted() noexcept = default;
734 StaticVectorCasted& operator=(const StaticVectorCasted&) = default;
736 template <std::
size_t TOtherSize>
737 StaticVectorCasted& operator=(const StaticVectorCasted<TOrig, TCast, TOtherSize>& other)
739 Base::operator=(other);
743 StaticVectorCasted& operator=(std::initializer_list<value_type> init)
745 Base::operator=(init);
749 void assign(size_type count, const_reference& value)
754 template <
typename TIter>
755 void assign(TIter from, TIter to)
760 void assign(std::initializer_list<value_type> init)
762 assign(init.begin(), init.end());
765 reference at(size_type pos)
767 return *(
reinterpret_cast<pointer
>(&(Base::at(pos))));
770 const_reference at(size_type pos)
const
772 return *(
reinterpret_cast<const_pointer
>(&(Base::at(pos))));
775 reference operator[](size_type pos)
777 return *(
reinterpret_cast<pointer
>(&(Base::operator[](pos))));
780 const_reference operator[](size_type pos)
const
782 return *(
reinterpret_cast<const_pointer
>(&(Base::operator[](pos))));
787 return *(
reinterpret_cast<pointer
>(&(Base::front())));
790 const_reference front()
const
792 return *(
reinterpret_cast<const_pointer
>(&(Base::front())));
797 return *(
reinterpret_cast<pointer
>(&(Base::back())));
800 const_reference back()
const
802 return *(
reinterpret_cast<const_pointer
>(&(Base::back())));
807 return reinterpret_cast<pointer
>(Base::data());
810 const_pointer data()
const
812 return reinterpret_cast<const_pointer
>(Base::data());
817 return reinterpret_cast<iterator
>(Base::begin());
820 const_iterator begin()
const
825 const_iterator cbegin()
const
827 return reinterpret_cast<const_iterator
>(Base::cbegin());
832 return reinterpret_cast<iterator
>(Base::end());
835 const_iterator end()
const
840 const_iterator cend()
const
842 return reinterpret_cast<const_iterator
>(Base::cend());
845 iterator insert(const_iterator iter, const_reference value)
848 reinterpret_cast<iterator
>(
850 reinterpret_cast<typename Base::const_iterator
>(iter),
851 *(
reinterpret_cast<typename Base::const_pointer
>(&value))));
854 iterator insert(const_iterator iter, TCast&& value)
857 reinterpret_cast<iterator
>(
859 reinterpret_cast<typename Base::const_iterator
>(iter),
860 std::move(*(
reinterpret_cast<typename Base::pointer
>(&value)))));
863 iterator insert(const_iterator iter, size_type count, const_reference value)
866 reinterpret_cast<iterator
>(
868 reinterpret_cast<typename Base::const_iterator
>(iter),
870 *(
reinterpret_cast<typename Base::const_pointer
>(&value))));
873 template <
typename TIter>
874 iterator insert(const_iterator iter, TIter from, TIter to)
877 reinterpret_cast<iterator
>(
879 reinterpret_cast<typename Base::const_iterator
>(iter),
884 iterator insert(const_iterator iter, std::initializer_list<value_type> init)
887 reinterpret_cast<iterator
>(
889 reinterpret_cast<typename Base::const_iterator
>(iter),
894 template <
typename... TArgs>
895 iterator emplace(const_iterator iter, TArgs&&... args)
898 reinterpret_cast<iterator
>(
900 reinterpret_cast<typename Base::const_iterator
>(iter),
901 std::forward<TArgs>(args)...));
904 iterator erase(const_iterator iter)
906 return erase(iter, iter + 1);
911 iterator erase(const_iterator from, const_iterator to)
914 reinterpret_cast<iterator
>(
916 reinterpret_cast<typename Base::const_iterator
>(from),
917 reinterpret_cast<typename Base::const_iterator
>(to)));
920 void push_back(const_reference value)
922 Base::push_back(*(
reinterpret_cast<typename Base::const_pointer
>(&value)));
925 void push_back(TCast&& value)
927 Base::push_back(std::move(*(
reinterpret_cast<TCast*
>(&value))));
931 template <
bool TSignedIntegral>
932 struct StaticVectorBaseSignedIntegral;
935 struct StaticVectorBaseSignedIntegral<true>
937 template <
typename T, std::
size_t TSize>
938 using Type = StaticVectorCasted<T, typename std::make_unsigned<T>::type, TSize>;
942 struct StaticVectorBaseSignedIntegral<false>
944 template <
typename T, std::
size_t TSize>
945 using Type = StaticVectorGeneric<T, TSize>;
948 template <
typename T, std::
size_t TSize>
949 using ChooseStaticVectorBase =
950 typename StaticVectorBaseSignedIntegral<std::is_integral<T>::value && std::is_signed<T>::value>::template Type<T, TSize>;
963 template <
typename T, std::
size_t TSize>
966 using Base = details::ChooseStaticVectorBase<T, TSize>;
967 using ElementType =
typename Base::ElementType;
969 static_assert(
sizeof(T) ==
sizeof(ElementType),
970 "Sizes are not equal as expected.");
972 template <
typename U, std::
size_t TOtherSize>
1015 : Base(count, value)
1028 template <
typename TIter>
1036 template <std::
size_t TOtherSize>
1065 template <std::
size_t TOtherSize>
1068 Base::operator=(other);
1076 Base::operator=(init);
1089 template <
typename TIter>
1097 void assign(std::initializer_list<value_type> init)
1099 assign(init.begin(), init.end());
1110 return Base::at(pos);
1120 return Base::at(pos);
1127 return Base::operator[](pos);
1134 return Base::operator[](pos);
1142 return Base::front();
1150 return Base::front();
1158 return Base::back();
1166 return Base::back();
1173 return Base::data();
1180 return Base::data();
1187 return Base::begin();
1201 return Base::cbegin();
1222 return Base::cend();
1271 return Base::empty();
1278 return Base::size();
1295 return Base::reserve(new_cap);
1304 return Base::capacity();
1325 return Base::insert(iter, value);
1332 return Base::insert(iter, std::move(value));
1339 return Base::insert(iter, count, value);
1344 template <
typename TIter>
1347 return Base::insert(iter, from, to);
1354 return Base::insert(iter, init.begin(), init.end());
1359 template <
typename... TArgs>
1362 return Base::emplace(iter, std::forward<TArgs>(args)...);
1369 return erase(iter, iter + 1);
1376 return Base::erase(from, to);
1384 Base::push_back(value);
1392 Base::push_back(std::move(value));
1398 template <
typename... TArgs>
1401 Base::emplace_back(std::forward<TArgs>(args)...);
1425 Base::resize(count, value);
1431 template <std::
size_t TOtherSize>
1439 template <
typename T>
1440 class StaticVector<T, 0U>
1442 using StorageType = std::array<T, 0U>;
1444 template <
typename U, std::
size_t TOtherSize>
1445 friend class StaticVector;
1448 using value_type =
typename StorageType::value_type;
1449 using size_type =
typename StorageType::size_type;
1450 using difference_type =
typename StorageType::difference_type;
1451 using reference =
typename StorageType::reference;
1452 using const_reference =
typename StorageType::const_reference;
1453 using pointer =
typename StorageType::pointer;
1454 using const_pointer =
typename StorageType::const_pointer;
1455 using iterator =
typename StorageType::iterator;
1456 using const_iterator =
typename StorageType::const_iterator;
1457 using reverse_iterator =
typename StorageType::reverse_iterator;
1458 using const_reverse_iterator =
typename StorageType::const_reverse_iterator;
1460 StaticVector() =
default;
1462 StaticVector(size_type count,
const T& value)
1464 static_cast<void>(value);
1469 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1470 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1471 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1474 explicit StaticVector(size_type count)
1480 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1481 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1482 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1485 template <
typename TIter>
1486 StaticVector(TIter from, TIter to)
1492 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1493 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1494 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1497 template <std::
size_t TOtherSize>
1498 StaticVector(
const StaticVector<T, TOtherSize>& other)
1500 static_cast<void>(other);
1501 if (TOtherSize == 0U) {
1505 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1506 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1507 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1510 StaticVector(
const StaticVector& other)
1512 static_cast<void>(other);
1515 StaticVector(std::initializer_list<value_type> init)
1517 if (std::begin(init) == std::end(init)) {
1521 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1522 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1523 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1526 ~StaticVector() noexcept = default;
1528 StaticVector& operator=(const StaticVector&) = default;
1530 template <std::
size_t TOtherSize>
1531 StaticVector& operator=(const StaticVector<T, TOtherSize>& other)
1533 static_cast<void>(other);
1534 if (TOtherSize == 0U) {
1538 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1539 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1540 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1544 StaticVector& operator=(std::initializer_list<value_type> init)
1546 if (std::begin(init) == std::end(init)) {
1550 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1551 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1552 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1556 void assign(size_type count,
const T& value)
1558 static_cast<void>(value);
1563 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1564 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1565 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1568 template <
typename TIter>
1569 void assign(TIter from, TIter to)
1575 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1576 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1577 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1580 void assign(std::initializer_list<value_type> init)
1582 if (std::begin(init) == std::end(init)) {
1586 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1587 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1588 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1591 reference at(size_type pos)
1593 static_cast<void>(pos);
1594 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1595 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1596 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1600 const_reference at(size_type pos)
const
1602 static_cast<void>(pos);
1603 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1604 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1605 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1609 reference operator[](size_type pos)
1611 static_cast<void>(pos);
1612 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1613 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1614 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1618 const_reference operator[](size_type pos)
const
1620 static_cast<void>(pos);
1621 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1622 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1623 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1629 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1630 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1631 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1632 return m_data.front();
1635 const_reference front()
const
1637 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1638 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1639 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1640 return m_data.front();
1645 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1646 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1647 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1648 return m_data.back();
1651 const_reference back()
const
1653 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1654 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1655 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1656 return m_data.back();
1661 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1662 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1663 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1664 return m_data.data();
1667 const_pointer data()
const
1669 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1670 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1671 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1672 return m_data.data();
1677 return m_data.begin();
1680 const_iterator begin()
const
1682 return m_data.begin();
1685 const_iterator cbegin()
const
1687 return m_data.cbegin();
1692 return m_data.end();
1695 const_iterator end()
const
1697 return m_data.end();
1700 const_iterator cend()
const
1702 return m_data.cend();
1705 reverse_iterator rbegin()
1707 return m_data.rbegin();
1710 const_reverse_iterator rbegin()
const
1712 return m_data.rbegin();
1715 const_reverse_iterator crbegin()
const
1717 return m_data.crbegin();
1720 reverse_iterator rend()
1722 return m_data.rend();
1725 const_reverse_iterator rend()
const
1727 return m_data.rend();
1730 const_reverse_iterator crend()
const
1732 return m_data.crend();
1737 return m_data.empty();
1740 size_type size()
const
1742 return m_data.size();
1745 size_type max_size()
const
1747 return m_data.max_size();
1750 void reserve(size_type new_cap)
1752 static_cast<void>(new_cap);
1753 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1754 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1755 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1758 size_type capacity()
const
1763 void shrink_to_fit()
1771 iterator insert(const_iterator iter,
const T& value)
1773 static_cast<void>(iter);
1774 static_cast<void>(value);
1775 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1776 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1777 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1778 return m_data.end();
1781 iterator insert(const_iterator iter, T&& value)
1783 static_cast<void>(iter);
1784 static_cast<void>(value);
1785 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1786 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1787 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1788 return m_data.end();
1791 iterator insert(const_iterator iter, size_type count,
const T& value)
1793 static_cast<void>(iter);
1794 static_cast<void>(count);
1795 static_cast<void>(value);
1796 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1797 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1798 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1799 return m_data.end();
1802 template <
typename TIter>
1803 iterator insert(const_iterator iter, TIter from, TIter to)
1805 static_cast<void>(iter);
1806 static_cast<void>(from);
1807 static_cast<void>(to);
1808 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1809 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1810 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1811 return m_data.end();
1814 iterator insert(const_iterator iter, std::initializer_list<value_type> init)
1816 static_cast<void>(iter);
1817 static_cast<void>(init);
1818 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1819 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1820 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1821 return m_data.end();
1824 template <
typename... TArgs>
1825 iterator emplace(const_iterator iter, TArgs&&...)
1827 static_cast<void>(iter);
1828 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1829 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1830 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1831 return m_data.end();
1834 iterator erase(const_iterator iter)
1836 static_cast<void>(iter);
1837 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1838 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1839 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1840 return m_data.end();
1843 iterator erase(const_iterator from, const_iterator to)
1846 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1847 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1848 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1850 return m_data.end();
1853 void push_back(
const T& value)
1855 static_cast<void>(value);
1856 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1857 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1858 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1861 void push_back(T&& value)
1863 static_cast<void>(value);
1864 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1865 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1866 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1869 template <
typename... TArgs>
1870 void emplace_back(TArgs&&...)
1872 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1873 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1874 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1879 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1880 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1881 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1884 void resize(size_type count)
1890 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1891 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1892 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1895 void resize(size_type count,
const value_type& value)
1897 static_cast<void>(value);
1902 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1903 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1904 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1907 template <std::
size_t TOtherSize>
1908 void swap(StaticVector<T, TOtherSize>& other)
1910 static_cast<void>(other);
1911 if (TOtherSize != 0U) {
1912 static constexpr
bool Must_not_be_called_for_zero_sized_vector =
false;
1913 static_cast<void>(Must_not_be_called_for_zero_sized_vector);
1914 COMMS_ASSERT(Must_not_be_called_for_zero_sized_vector);
1925 template <
typename T, std::
size_t TSize1, std::
size_t TSize2>
1928 return std::lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end());
1934 template <
typename T, std::
size_t TSize1, std::
size_t TSize2>
1943 template <
typename T, std::
size_t TSize1, std::
size_t TSize2>
1952 template <
typename T, std::
size_t TSize1, std::
size_t TSize2>
1961 template <
typename T, std::
size_t TSize1, std::
size_t TSize2>
1964 return (v1.size() == v2.size()) &&
1972 template <
typename T, std::
size_t TSize1, std::
size_t TSize2>
1982 template <
typename T>
1983 struct IsStaticVector
1985 static const bool Value =
false;
1988 template <
typename T, std::
size_t TSize>
1991 static const bool Value =
true;
1999 template <
typename T>
2002 return details::IsStaticVector<T>::Value;
2015 template <
typename T, std::
size_t TSize1, std::
size_t TSize2>
2023 COMMS_GNU_WARNING_POP
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition: Assert.h:170
Contains various compiler related definitions.
Replacement to std::vector when no dynamic memory allocation is allowed.
Definition: StaticVector.h:965
const_iterator cend() const
Returns an iterator to the end.
Definition: StaticVector.h:1220
void assign(std::initializer_list< value_type > init)
Assigns values to the container.
Definition: StaticVector.h:1097
reference at(size_type pos)
Access specified element with bounds checking.
Definition: StaticVector.h:1108
size_type max_size() const
Returns the maximum possible number of elements.
Definition: StaticVector.h:1285
typename Base::const_reference const_reference
Const reference to single element.
Definition: StaticVector.h:989
void assign(size_type count, const T &value)
Assigns values to the container.
Definition: StaticVector.h:1082
void resize(size_type count)
Changes the number of elements stored.
Definition: StaticVector.h:1415
const_reverse_iterator rbegin() const
Returns a reverse iterator to the beginning.
Definition: StaticVector.h:1234
iterator begin()
Returns an iterator to the beginning.
Definition: StaticVector.h:1185
static constexpr bool isStaticVector()
Compile time check whether the provided type is a variant of comms::util::StaticVector.
Definition: StaticVector.h:2000
void swap(StaticVector< T, TOtherSize > &other)
Swaps the contents.
Definition: StaticVector.h:1432
const_iterator begin() const
Returns an iterator to the beginning.
Definition: StaticVector.h:1192
const_reference at(size_type pos) const
Access specified element with bounds checking.
Definition: StaticVector.h:1118
StaticVector(TIter from, TIter to)
Constructor.
Definition: StaticVector.h:1029
typename Base::reference reference
Reference to single element.
Definition: StaticVector.h:986
StaticVector(const StaticVector< T, TOtherSize > &other)
Copy constructor.
Definition: StaticVector.h:1037
bool operator!=(const StaticVector< T, TSize1 > &v1, const StaticVector< T, TSize2 > &v2)
Lexicographically compares the values in the vector.
Definition: StaticVector.h:1973
StaticVector(size_type count)
Constructor.
Definition: StaticVector.h:1021
StaticVector(const StaticVector &other)
Copy constructor.
Definition: StaticVector.h:1044
iterator insert(const_iterator iter, std::initializer_list< value_type > init)
Inserts elements.
Definition: StaticVector.h:1352
const_reference operator[](size_type pos) const
Access specified element without bounds checking.
Definition: StaticVector.h:1132
size_type capacity() const
Returns the number of elements that can be held in currently allocated storage.
Definition: StaticVector.h:1302
void assign(TIter from, TIter to)
Assigns values to the container.
Definition: StaticVector.h:1090
reference front()
Access the first element.
Definition: StaticVector.h:1140
const_reference back() const
Access the last element.
Definition: StaticVector.h:1164
void clear()
Clears the contents.
Definition: StaticVector.h:1316
reference back()
Access the last element.
Definition: StaticVector.h:1156
const_reference front() const
Access the first element.
Definition: StaticVector.h:1148
bool operator<(const StaticVector< T, TSize1 > &v1, const StaticVector< T, TSize2 > &v2)
Lexicographically compares the values in the vector.
Definition: StaticVector.h:1926
bool operator<=(const StaticVector< T, TSize1 > &v1, const StaticVector< T, TSize2 > &v2)
Lexicographically compares the values in the vector.
Definition: StaticVector.h:1935
iterator insert(const_iterator iter, T &&value)
Inserts elements.
Definition: StaticVector.h:1330
const_iterator end() const
Returns an iterator to the end.
Definition: StaticVector.h:1213
typename Base::size_type size_type
Type used for size information.
Definition: StaticVector.h:980
StaticVector(std::initializer_list< value_type > init)
Constructor.
Definition: StaticVector.h:1051
StaticVector()=default
Default constructor.
StaticVector & operator=(std::initializer_list< value_type > init)
Copy assignement.
Definition: StaticVector.h:1074
StaticVector(size_type count, const T &value)
Constructor.
Definition: StaticVector.h:1014
const_reverse_iterator rend() const
Returns a reverse iterator to the end.
Definition: StaticVector.h:1255
void pop_back()
Removes the last element.
Definition: StaticVector.h:1407
void resize(size_type count, const value_type &value)
Changes the number of elements stored.
Definition: StaticVector.h:1423
void shrink_to_fit()
Reduces memory usage by freeing unused memory.
Definition: StaticVector.h:1310
typename Base::iterator iterator
Type of the iterator.
Definition: StaticVector.h:998
iterator insert(const_iterator iter, TIter from, TIter to)
Inserts elements.
Definition: StaticVector.h:1345
const_reverse_iterator crbegin() const
Returns a reverse iterator to the beginning.
Definition: StaticVector.h:1241
iterator insert(const_iterator iter, const T &value)
Inserts elements.
Definition: StaticVector.h:1323
reverse_iterator rend()
Returns a reverse iterator to the end.
Definition: StaticVector.h:1248
reverse_iterator rbegin()
Returns a reverse iterator to the beginning.
Definition: StaticVector.h:1227
typename Base::StorageType::difference_type difference_type
Type used in pointer arithmetics.
Definition: StaticVector.h:983
iterator end()
Returns an iterator to the end.
Definition: StaticVector.h:1206
bool operator>(const StaticVector< T, TSize1 > &v1, const StaticVector< T, TSize2 > &v2)
Lexicographically compares the values in the vector.
Definition: StaticVector.h:1944
void push_back(const T &value)
Adds an element to the end.
Definition: StaticVector.h:1382
typename Base::value_type value_type
Type of single element.
Definition: StaticVector.h:977
iterator erase(const_iterator from, const_iterator to)
Erases elements.
Definition: StaticVector.h:1374
void swap(comms::util::StaticVector< T, TSize1 > &v1, comms::util::StaticVector< T, TSize2 > &v2)
Specializes the std::swap algorithm.
Definition: StaticVector.h:2016
void reserve(size_type new_cap)
Reserves storage.
Definition: StaticVector.h:1293
iterator insert(const_iterator iter, size_type count, const T &value)
Inserts elements.
Definition: StaticVector.h:1337
size_type size() const
Returns the number of elements.
Definition: StaticVector.h:1276
typename Base::const_reverse_iterator const_reverse_iterator
Type of the const reverse iterator.
Definition: StaticVector.h:1007
bool operator==(const StaticVector< T, TSize1 > &v1, const StaticVector< T, TSize2 > &v2)
Lexicographically compares the values in the vector.
Definition: StaticVector.h:1962
void push_back(T &&value)
Adds an element to the end.
Definition: StaticVector.h:1390
typename Base::const_pointer const_pointer
Const pointer to single element.
Definition: StaticVector.h:995
bool operator>=(const StaticVector< T, TSize1 > &v1, const StaticVector< T, TSize2 > &v2)
Lexicographically compares the values in the vector.
Definition: StaticVector.h:1953
iterator emplace(const_iterator iter, TArgs &&... args)
Constructs elements in place.
Definition: StaticVector.h:1360
void emplace_back(TArgs &&... args)
Constructs an element in place at the end.
Definition: StaticVector.h:1399
typename Base::const_iterator const_iterator
Type of the const iterator.
Definition: StaticVector.h:1001
~StaticVector() noexcept=default
Destructor.
iterator erase(const_iterator iter)
Erases elements.
Definition: StaticVector.h:1367
bool empty() const
Checks whether the container is empty.
Definition: StaticVector.h:1269
const_pointer data() const
Direct access to the underlying array.
Definition: StaticVector.h:1178
pointer data()
Direct access to the underlying array.
Definition: StaticVector.h:1171
typename Base::reverse_iterator reverse_iterator
Type of the reverse iterator.
Definition: StaticVector.h:1004
typename Base::pointer pointer
Pointer to single element.
Definition: StaticVector.h:992
const_reverse_iterator crend() const
Returns a reverse iterator to the end.
Definition: StaticVector.h:1262
reference operator[](size_type pos)
Access specified element without bounds checking.
Definition: StaticVector.h:1125
const_iterator cbegin() const
Returns an iterator to the beginning.
Definition: StaticVector.h:1199
void assign(T &obj, TIter from, TIter to)
Assigns a new value to provided object.
Definition: assign.h:39
Main namespace for all classes / functions of COMMS library.