File indexing completed on 2024-05-12 16:21:17

0001 // SPDX-FileCopyrightText: 2021 Jonah BrĂ¼chert <jbb@kaidan.im>
0002 //
0003 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 
0005 #pragma once
0006 
0007 #include <variant>
0008 #include <tuple>
0009 #include <span>
0010 #include <QtGlobal>
0011 
0012 template <typename Tuple, typename Func, std::size_t i>
0013 inline constexpr void iterate_impl(Tuple &tup, Func fun)
0014 {
0015     if constexpr(i >= std::tuple_size_v<std::decay_t<decltype(tup)>>) {
0016         return;
0017     } else {
0018         fun(std::get<i>(tup));
0019         return iterate_impl<Tuple, Func, i + 1>(tup, fun);
0020     }
0021 }
0022 
0023 template <typename Tuple, typename Func>
0024 inline constexpr void iterate_tuple(Tuple &tup, Func fun)
0025 {
0026     iterate_impl<Tuple, Func, 0>(tup, fun);
0027 }
0028 
0029 /// MultiIterableView is a view over multiple contigous memory arrays, like std::vector or std::array.
0030 /// The elements of the arrays do not need to be of the same type.
0031 template <typename... Arguments>
0032 class MultiIterableView {
0033 public:
0034     explicit MultiIterableView(std::span<Arguments>... lists)
0035         : m_vectors(std::forward_as_tuple(lists...))
0036     {
0037     }
0038 
0039     explicit MultiIterableView(std::vector<Arguments> &...lists)
0040         : MultiIterableView(std::span{lists}...)
0041     {
0042     }
0043 
0044     [[nodiscard]] constexpr size_t size() const {
0045         size_t s = 0;
0046         iterate_tuple(m_vectors, [&](auto &vec) {
0047             s += vec.size();
0048         });
0049         return s;
0050     }
0051 
0052     [[nodiscard]] constexpr std::variant<Arguments...> operator[](size_t i) const {
0053         size_t s = 0;
0054         std::variant<Arguments...> out;
0055         iterate_tuple(m_vectors, [&](auto &vec) {
0056             if (i >= s && i < s + vec.size()) {
0057                 out = vec[i - s];
0058             }
0059             s += vec.size();
0060         });
0061         return out;
0062     }
0063 
0064     [[nodiscard]] constexpr bool empty() const {
0065         bool empty = true;
0066         iterate_tuple(m_vectors, [&](auto &elem) {
0067             empty &= elem.empty();
0068         });
0069         return empty;
0070     }
0071 private:
0072     std::tuple<std::span<Arguments>...> m_vectors;
0073 };