-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmatches.hh
160 lines (123 loc) · 3.36 KB
/
matches.hh
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) 2022 Mikael Simonsson <https://mikaelsimonsson.com>.
// SPDX-License-Identifier: BSL-1.0
// # Matches (`std::cmatch` wrapper)
#pragma once
#include "snn-core/optional.hh"
#include "snn-core/range/forward.hh"
#include "snn-core/regex/match_view.hh"
#include <regex>
namespace snn::regex
{
// ## Classes
// ### matches_iterator
class matches_iterator final
{
public:
match_view operator*() const noexcept
{
return match_view{cmatch_, index_};
}
matches_iterator& operator++() noexcept
{
++index_;
return *this;
}
bool operator==(const matches_iterator& other) const noexcept
{
return index_ == other.index_;
}
bool operator!=(const matches_iterator& other) const noexcept
{
return index_ != other.index_;
}
private:
const std::cmatch& cmatch_;
usize index_;
template <typename>
friend class matches_base;
explicit matches_iterator(const std::cmatch& matches, const usize index) noexcept
: cmatch_{matches},
index_{index}
{
}
};
// ## Classes
// ### matches_base
template <typename Derived>
class matches_base
{
public:
// Explicit conversion operators.
constexpr explicit operator bool() const noexcept
{
return !is_empty();
}
// Single element access.
[[nodiscard]] optional<match_view> at(const usize pos) const noexcept
{
if (pos < count())
{
return match_view{cmatch_(), pos};
}
return nullopt;
}
[[nodiscard]] match_view at(const usize pos, promise::within_bounds_t) const noexcept
{
snn_assert(pos < count());
return match_view{cmatch_(), pos};
}
// Iterators
[[nodiscard]] auto begin() const noexcept
{
return matches_iterator{cmatch_(), 0};
}
[[nodiscard]] auto end() const noexcept
{
return matches_iterator{cmatch_(), cmatch_().size()};
}
// Capacity
[[nodiscard]] usize count() const noexcept
{
return cmatch_().size();
}
[[nodiscard]] bool is_empty() const noexcept
{
return count() == 0;
}
// Range
[[nodiscard]] auto range() const noexcept
{
return snn::range::forward{meta::iterators, begin(), end()};
}
protected:
matches_base() = default;
private:
const std::cmatch& cmatch_() const noexcept
{
return static_cast<const Derived*>(this)->cmatch();
}
};
// ## Classes
// ### matches
class matches final : public matches_base<matches>
{
public:
explicit matches() = default;
explicit matches(std::cmatch cmatch)
: cmatch_{std::move(cmatch)}
{
}
private:
std::cmatch cmatch_{};
friend class matches_base<matches>;
friend class pattern;
std::cmatch& cmatch() noexcept
{
return cmatch_;
}
const std::cmatch& cmatch() const noexcept
{
return cmatch_;
}
};
}