blob: 9d67a7f138c813b75bfd4578e399b30095001a34 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#pragma once
#include <QMetaEnum>
namespace Utils {
namespace ranges {
template<typename ENUMTYPE>
struct MetaEnum
{
struct Iterator
{
using iterator_category = std::forward_iterator_tag;
using value_type = int;
using difference_type = std::ptrdiff_t;
using pointer = int *;
using reference = int &;
Iterator() = default;
Iterator(const QMetaEnum *e, int idx)
: m_enum(e)
, m_index(idx)
{}
int operator*() const { return m_enum->value(m_index); }
Iterator &operator++()
{
++m_index;
return *this;
}
Iterator operator++(int) // post-incrementable, returns prev value
{
Iterator temp = *this;
++*this;
return temp;
}
bool operator!=(const Iterator &other) const
{
return m_index != other.m_index && m_enum == other.m_enum;
}
bool operator==(const Iterator &other) const
{
return m_index == other.m_index && m_enum == other.m_enum;
}
const QMetaEnum *m_enum{nullptr};
int m_index{-1};
};
using value_type = int;
MetaEnum()
: m_enum(QMetaEnum::fromType<ENUMTYPE>())
{}
Iterator begin() const { return Iterator(&m_enum, 0); }
Iterator end() const { return Iterator(&m_enum, m_enum.keyCount()); }
size_t size() const { return m_enum.keyCount(); }
QMetaEnum m_enum;
};
} // namespace ranges
} // namespace Utils
#if defined(__cpp_lib_ranges) && __cpp_lib_ranges >= 201911L
#include <ranges>
namespace Utils {
namespace ranges {
using std::ranges::reverse_view;
}
namespace views {
using std::views::reverse;
}
} // namespace Utils
#else
#include <stdexcept>
namespace Utils {
namespace ranges {
template <typename Container>
class reverse_view
{
public:
using value_type = typename Container::value_type;
using size_type = typename Container::size_type;
using Type = value_type;
using pointer = Type *;
using const_pointer = const Type *;
using reference = Type &;
using const_reference = const Type &;
using reverse_iterator = typename Container::iterator;
using iterator = std::reverse_iterator<reverse_iterator>;
using const_reverse_iterator = typename Container::const_iterator;
using const_iterator = std::reverse_iterator<const_reverse_iterator>;
using Iterator = iterator;
using ConstIterator = const_iterator;
reverse_view(const Container &k) : d(&k) {}
const_reverse_iterator rbegin() const noexcept { return d->begin(); }
const_reverse_iterator rend() const noexcept { return d->end(); }
const_reverse_iterator crbegin() const noexcept { return d->begin(); }
const_reverse_iterator crend() const noexcept { return d->end(); }
const_iterator begin() const noexcept { return const_iterator(rend()); }
const_iterator end() const noexcept { return const_iterator(rbegin()); }
const_iterator cbegin() const noexcept { return const_iterator(rend()); }
const_iterator cend() const noexcept { return const_iterator(rbegin()); }
const_iterator constBegin() const noexcept { return const_iterator(rend()); }
const_iterator constEnd() const noexcept { return const_iterator(rbegin()); }
const_reference front() const noexcept { return *cbegin(); }
const_reference back() const noexcept { return *crbegin(); }
[[nodiscard]] size_type size() const noexcept { return d->size(); }
[[nodiscard]] bool empty() const noexcept { return d->size() == 0; }
explicit operator bool() const { return d->size(); }
const_reference operator[](size_type idx) const
{
if (idx < size())
return *(begin() + idx);
throw std::out_of_range("bad index in reverse side");
}
private:
const Container *d;
};
} // namespace ranges
namespace views {
constexpr struct {} reverse;
template <typename T>
inline ranges::reverse_view<T> operator|(const T &container, const decltype(reverse)&)
{
return ranges::reverse_view(container);
}
} // namsepace views
} // namespace Utils
#endif
|