JS8Call-Improved master
Loading...
Searching...
No Matches
Maidenhead.h
Go to the documentation of this file.
1
10#ifndef MAIDENHEAD_HPP__
11#define MAIDENHEAD_HPP__
12
13#include <QString>
14#include <QStringView>
15#include <QValidator>
16
24namespace Maidenhead {
25
35constexpr char16_t normalize(char16_t const u) noexcept {
36 return (u >= u'a' && u <= u'z') ? u - (u'a' - u'A') : u;
37}
38
39static_assert(normalize(u'0') == u'0');
40static_assert(normalize(u'A') == u'A');
41static_assert(normalize(u'Z') == u'Z');
42static_assert(normalize(u'a') == u'A');
43static_assert(normalize(u'z') == u'Z');
44
66constexpr auto invalidIndex(QStringView const view) noexcept {
67 auto const size = view.size();
68
69 for (qsizetype i = 0; i < size; ++i) {
70 auto const u = normalize(view[i].unicode());
71
72 switch (i) {
73 case 0:
74 case 1:
75 if (u >= u'A' && u <= u'R')
76 continue;
77 break;
78 case 2:
79 case 3:
80 case 6:
81 case 7:
82 case 10:
83 case 11:
84 if (u >= u'0' && u <= u'9')
85 continue;
86 break;
87 case 4:
88 case 5:
89 case 8:
90 case 9:
91 if (u >= u'A' && u <= u'X')
92 continue;
93 break;
94 }
95 return i;
96 }
97
98 return size;
99}
100
101static_assert(invalidIndex(u"") == 0);
102static_assert(invalidIndex(u"S") == 0);
103static_assert(invalidIndex(u"AZ") == 1);
104static_assert(invalidIndex(u"AAA") == 2);
105static_assert(invalidIndex(u"AA00AA00AA00A") == 12);
106
118template <qsizetype Min = 2, qsizetype Max = 6>
119constexpr auto valid(QStringView const view) noexcept {
120 static_assert(Min >= 1 && Max >= 1 && Max <= 6 && Min <= Max);
121
122 if (auto const size = view.size();
123 !(size & 1) && (size >= 2 * Min) && (size <= 2 * Max)) {
124 return invalidIndex(view) == size;
125 }
126
127 return false;
128}
129
130static_assert(valid(u"AA00"));
131static_assert(valid(u"AA00AA"));
132static_assert(valid(u"AA00AA00"));
133static_assert(valid(u"BP51AD95RF"));
134static_assert(valid(u"BP51AD95RF00"));
135static_assert(valid(u"aa00"));
136static_assert(valid(u"AA00aa"));
137static_assert(valid(u"RR00XX"));
138
139static_assert(!valid(u""));
140static_assert(!valid(u"A"));
141static_assert(!valid(u"0"));
142static_assert(!valid(u"AA00 "));
143static_assert(!valid(u"AA00 "));
144static_assert(!valid(u"AA00 "));
145static_assert(!valid(u" AA00"));
146static_assert(!valid(u" AA00"));
147static_assert(!valid(u"00"));
148static_assert(!valid(u"aa00a"));
149static_assert(!valid(u"AA00ZZA"));
150static_assert(!valid(u"!@#$%^"));
151static_assert(!valid(u"123456"));
152static_assert(!valid(u"AA00ZZ"));
153static_assert(!valid(u"ss00XX"));
154static_assert(!valid(u"rr00yy"));
155static_assert(!valid(u"AAA1aa"));
156static_assert(!valid(u"BP51AD95RF00A"));
157static_assert(!valid(u"BP51AD95RF0000"));
158
169template <qsizetype Min, qsizetype Max>
170class Validator final : public QValidator {
171 static_assert(Min >= 1 && Max >= 1 && Max <= 6 && Min <= Max);
172
173 using QValidator::QValidator;
174
185 State validate(QString &input, int &pos) const override {
186 // Ensure the input is upper case and get the size.
187
188 input = input.toUpper();
189 auto const size = input.size();
190
191 // If nothing's been entered, we need more from them; if over
192 // the maximum, less.
193
194 if (size == 0)
195 return Intermediate;
196 if (size > Max * 2)
197 return Invalid;
198
199 // If anything up to the cursor is invalid, then we're invalid.
200 // Anything after the cursor, we're willing to be hopeful about.
201
202 if (auto const index = invalidIndex(input); index != size) {
203 return index < pos ? Invalid : Intermediate;
204 }
205
206 // Entire input was valid. If the count is odd, or we haven't yet
207 // hit the minimum, we need more from them, otherwise, we're good.
208
209 return ((size & 1) || (size < Min * 2)) ? Intermediate : Acceptable;
210 }
211};
212
220
228
229} // namespace Maidenhead
230
231#endif
Custom Qt validator for stateful UI evaluation of Maidenhead strings.
Definition Maidenhead.h:170
Namespace containing utilities for managing Maidenhead grid locators.
constexpr auto invalidIndex(QStringView const view) noexcept
Locates the first invalid character index in a locator string view.
Definition Maidenhead.h:66
constexpr char16_t normalize(char16_t const u) noexcept
Converts a lowercase character code point to uppercase if applicable.
Definition Maidenhead.h:35
Validator< 2, 6 > ExtendedValidator
Convenience validator permitting high fidelity sub-allocations up to Hyper Extended format.
Definition Maidenhead.h:227
Validator< 2, 3 > StandardValidator
Convenience validator requiring Field and Square, allowing Subsquare.
Definition Maidenhead.h:219
constexpr auto valid(QStringView const view) noexcept
Assesses whether a complete string view matches acceptable grid lengths and constraints.
Definition Maidenhead.h:119