Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2025 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 : #pragma once
23 :
24 : #include <algorithm>
25 : #include <stdexcept>
26 : #include <vector>
27 :
28 : namespace muse {
29 : template<typename T>
30 : struct VectorView
31 : {
32 : public:
33 3226 : VectorView(std::vector<T>& vec)
34 3226 : : m_begin(vec.begin()), m_end(vec.end()) {}
35 :
36 : using iterator = typename std::vector<T>::iterator;
37 : using reverse_iterator = typename std::vector<T>::reverse_iterator;
38 :
39 18 : iterator begin() { return m_begin; }
40 18 : iterator end() { return m_end; }
41 :
42 75 : reverse_iterator rbegin() { return reverse_iterator { m_end }; }
43 75 : reverse_iterator rend() { return reverse_iterator { m_begin }; }
44 :
45 11406 : bool empty() const { return m_begin == m_end; }
46 :
47 1 : T& front() const
48 : {
49 1 : if (empty()) {
50 0 : throw std::out_of_range("VectorView::front(): empty view");
51 : }
52 1 : return *m_begin;
53 : }
54 :
55 3589 : T& pop_front()
56 : {
57 3589 : if (empty()) {
58 0 : throw std::out_of_range("VectorView::pop_front(): empty view");
59 : }
60 3589 : T& v = *m_begin;
61 3589 : ++m_begin;
62 3589 : return v;
63 : }
64 :
65 1 : T& back() const
66 : {
67 1 : if (empty()) {
68 0 : throw std::out_of_range("VectorView::back(): empty view");
69 : }
70 1 : return *(m_end - 1);
71 : }
72 :
73 505 : T& pop_back()
74 : {
75 505 : if (empty()) {
76 0 : throw std::out_of_range("VectorView::pop_back(): empty view");
77 : }
78 505 : --m_end;
79 505 : return *m_end;
80 : }
81 :
82 2 : bool remove(const T& v)
83 : {
84 2 : auto originalEnd = m_end;
85 2 : m_end = std::remove(m_begin, m_end, v);
86 4 : return m_end != originalEnd;
87 : }
88 :
89 : template<typename Predicate>
90 511 : bool remove_if(Predicate&& pred)
91 : {
92 511 : auto originalEnd = m_end;
93 511 : m_end = std::remove_if(m_begin, m_end, std::forward<Predicate>(pred));
94 1022 : return m_end != originalEnd;
95 : }
96 :
97 2 : bool reverse_remove(const T& v)
98 : {
99 2 : auto originalBegin = m_begin;
100 2 : m_begin = std::remove(rbegin(), rend(), v).base();
101 4 : return m_begin != originalBegin;
102 : }
103 :
104 : template<typename Predicate>
105 73 : bool reverse_remove_if(Predicate&& pred)
106 : {
107 73 : auto originalBegin = m_begin;
108 73 : m_begin = std::remove_if(rbegin(), rend(), std::forward<Predicate>(pred)).base();
109 146 : return m_begin != originalBegin;
110 : }
111 :
112 : private:
113 : iterator m_begin;
114 : iterator m_end;
115 : };
116 : }
|