From 4dfc4ad2793084c4aeba5d2984bc200f43e13327 Mon Sep 17 00:00:00 2001 From: Fawn Date: Mon, 23 Mar 2026 11:10:09 -0600 Subject: [PATCH 1/3] Resolve all remaining C++20 TODOs With a single exception, which is already handled by #8321 --- include/ArrayVector.h | 13 +++---------- include/Flags.h | 3 +-- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/include/ArrayVector.h b/include/ArrayVector.h index 06e09226cf7..08671908186 100644 --- a/include/ArrayVector.h +++ b/include/ArrayVector.h @@ -306,8 +306,7 @@ class ArrayVector reference emplace_back(Args&&... args) { assert(!full()); - // TODO C++20: Use std::construct_at - const auto result = new(static_cast(end())) T(std::forward(args)...); + const auto result = std::construct_at(end(), std::forward(args)...); ++m_size; return *result; } @@ -362,21 +361,15 @@ class ArrayVector std::swap(a.m_size, b.m_size); } - // TODO C++20: Replace with operator<=> - friend bool operator<(const ArrayVector& l, const ArrayVector& r) + friend constexpr auto operator<=>(const ArrayVector& l, const ArrayVector& r) { - return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); + return std::lexicographical_compare_three_way(l.begin(), l.end(), r.begin(), r.end()); } - friend bool operator<=(const ArrayVector& l, const ArrayVector& r) { return !(r < l); } - friend bool operator>(const ArrayVector& l, const ArrayVector& r) { return r < l; } - friend bool operator>=(const ArrayVector& l, const ArrayVector& r) { return !(l < r); } friend bool operator==(const ArrayVector& l, const ArrayVector& r) { return std::equal(l.begin(), l.end(), r.begin(), r.end()); } - // TODO C++20: Remove - friend bool operator!=(const ArrayVector& l, const ArrayVector& r) { return !(l == r); } private: alignas(T) std::byte m_data[std::max(N * sizeof(T), std::size_t{1})]; // Intentionally a raw array diff --git a/include/Flags.h b/include/Flags.h index 62a5f8af8ba..37581afaa89 100644 --- a/include/Flags.h +++ b/include/Flags.h @@ -68,8 +68,7 @@ class Flags constexpr explicit operator UnderlyingType() const { return m_value; } // TODO C++23: explicit(std::is_scoped_enum) constexpr explicit operator bool() const { return m_value != 0; } - friend constexpr auto operator==(Flags l, Flags r) -> bool { return l.m_value == r.m_value; } // TODO C++20: = default - friend constexpr auto operator!=(Flags l, Flags r) -> bool { return l.m_value != r.m_value; } // TODO C++20: Remove + friend constexpr auto operator==(Flags l, Flags r) -> bool = default; private: UnderlyingType m_value = 0; From ea0203467d33e6f276803cc50ee04fd71162930b Mon Sep 17 00:00:00 2001 From: Fawn Date: Mon, 23 Mar 2026 14:37:14 -0600 Subject: [PATCH 2/3] Update iterator template constraints Co-authored-by: Dalton Messmer --- include/ArrayVector.h | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/include/ArrayVector.h b/include/ArrayVector.h index 08671908186..3c31bb5f5bc 100644 --- a/include/ArrayVector.h +++ b/include/ArrayVector.h @@ -37,17 +37,6 @@ namespace lmms { -namespace detail { - -template -constexpr bool is_input_iterator_v = false; - -template -constexpr bool is_input_iterator_v::iterator_category>> = - std::is_convertible_v::iterator_category, std::input_iterator_tag>; - -} // namespace detail - /** * A container that stores up to a maximum of `N` elements of type `T` directly * within itself, rather than separately on the heap. Useful when a dynamically @@ -100,7 +89,7 @@ class ArrayVector std::uninitialized_value_construct_n(begin(), count); } - template, int> = 0> + template ArrayVector(It first, It last) { // Can't check the size first as the iterator may not be multipass @@ -173,7 +162,7 @@ class ArrayVector m_size = count; } - template, int> = 0> + template void assign(It first, It last) { // Can't check the size first as the iterator may not be multipass @@ -262,7 +251,7 @@ class ArrayVector return mutPos; } - template, int> = 0> + template iterator insert(const_iterator pos, It first, It last) { // Can't check the size first as the iterator may not be multipass From 5894038cdbe5761214c675f5e973158e020ed4b4 Mon Sep 17 00:00:00 2001 From: Fawn Date: Mon, 23 Mar 2026 14:40:19 -0600 Subject: [PATCH 3/3] TODO C++26: Replace ArrayVector with std::inplace_vector Co-authored-by: Dalton Messmer --- include/ArrayVector.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/ArrayVector.h b/include/ArrayVector.h index 3c31bb5f5bc..7ea78d8e905 100644 --- a/include/ArrayVector.h +++ b/include/ArrayVector.h @@ -43,6 +43,8 @@ namespace lmms { * resizeable container is needed for use in real-time code. Can be thought of * as a hybrid between `std::array` and `std::vector`. The interface follows * that of `std::vector` - see standard C++ documentation. + * + * TODO C++26: Replace uses of this class with std::inplace_vector */ template class ArrayVector