Skip to content

Commit ff69e8f

Browse files
authored
Implement 'even', 'odd', 'lower' and 'upper' testers
* Begin implementing testers * Test for 'gt', 'ge', 'lt' and 'le' testers * Implement 'defined' and 'undefined' testers * Fix build * Implement 'iterable', 'mapping', 'number', 'sequence' and 'string' testers * Implement 'in' tester * Implement 'even', 'odd', 'lower' and 'upper' testers * Fix gcc/clang build * Fix build
1 parent 3dd4609 commit ff69e8f

File tree

4 files changed

+192
-162
lines changed

4 files changed

+192
-162
lines changed

src/string_converter_filter.cpp

Lines changed: 7 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -143,46 +143,6 @@ struct UrlStringEncoder : public StringEncoder<UrlStringEncoder>
143143
}
144144
};
145145

146-
template<typename Fn>
147-
struct StringConverterImpl : public visitors::BaseVisitor<>
148-
{
149-
using BaseVisitor::operator ();
150-
151-
StringConverterImpl(const Fn& fn) : m_fn(fn) {}
152-
153-
template<typename CharT>
154-
InternalValue operator()(const std::basic_string<CharT>& str) const
155-
{
156-
return m_fn(str);
157-
}
158-
159-
const Fn& m_fn;
160-
};
161-
162-
template<typename CharT>
163-
struct SameStringGetter : public visitors::BaseVisitor<std::basic_string<CharT>>
164-
{
165-
using ResultString = std::basic_string<CharT>;
166-
using visitors::BaseVisitor<ResultString>::operator ();
167-
168-
ResultString operator()(const ResultString& str) const
169-
{
170-
return str;
171-
}
172-
};
173-
174-
template<template<typename> class Cvt = StringConverterImpl, typename Fn>
175-
auto ApplyConverter(const InternalValue& str, Fn&& fn)
176-
{
177-
return Apply<Cvt<Fn>>(str, std::forward<Fn>(fn));
178-
}
179-
180-
template<typename CharT>
181-
auto GetAsSameString(const std::basic_string<CharT>& s, const InternalValue& val)
182-
{
183-
return Apply<SameStringGetter<CharT>>(val);
184-
}
185-
186146
StringConverter::StringConverter(FilterParams params, StringConverter::Mode mode)
187147
: m_mode(mode)
188148
{
@@ -207,13 +167,13 @@ InternalValue StringConverter::Filter(const InternalValue& baseVal, RenderContex
207167
switch (m_mode)
208168
{
209169
case TrimMode:
210-
result = ApplyConverter(baseVal, [](auto str) {
170+
result = ApplyStringConverter(baseVal, [](auto str) -> InternalValue {
211171
ba::trim_all(str);
212172
return str;
213173
});
214174
break;
215175
case TitleMode:
216-
result = ApplyConverter<GenericStringEncoder>(baseVal, [isDelim = true, &isAlpha, &isAlNum](auto ch, auto&& fn) mutable {
176+
result = ApplyStringConverter<GenericStringEncoder>(baseVal, [isDelim = true, &isAlpha, &isAlNum](auto ch, auto&& fn) mutable {
217177
if (isDelim && isAlpha(ch))
218178
{
219179
isDelim = false;
@@ -228,7 +188,7 @@ InternalValue StringConverter::Filter(const InternalValue& baseVal, RenderContex
228188
case WordCountMode:
229189
{
230190
int64_t wc = 0;
231-
ApplyConverter<GenericStringEncoder>(baseVal, [isDelim = true, &wc, &isAlpha, &isAlNum](auto ch, auto&& fn) mutable {
191+
ApplyStringConverter<GenericStringEncoder>(baseVal, [isDelim = true, &wc, &isAlpha, &isAlNum](auto ch, auto&& fn) mutable {
232192
if (isDelim && isAlNum(ch))
233193
{
234194
isDelim = false;
@@ -241,23 +201,23 @@ InternalValue StringConverter::Filter(const InternalValue& baseVal, RenderContex
241201
break;
242202
}
243203
case UpperMode:
244-
result = ApplyConverter<GenericStringEncoder>(baseVal, [&isAlpha](auto ch, auto&& fn) mutable {
204+
result = ApplyStringConverter<GenericStringEncoder>(baseVal, [&isAlpha](auto ch, auto&& fn) mutable {
245205
if (isAlpha(ch))
246206
fn(std::toupper(ch, std::locale()));
247207
else
248208
fn(ch);
249209
});
250210
break;
251211
case LowerMode:
252-
result = ApplyConverter<GenericStringEncoder>(baseVal, [&isAlpha](auto ch, auto&& fn) mutable {
212+
result = ApplyStringConverter<GenericStringEncoder>(baseVal, [&isAlpha](auto ch, auto&& fn) mutable {
253213
if (isAlpha(ch))
254214
fn(std::tolower(ch, std::locale()));
255215
else
256216
fn(ch);
257217
});
258218
break;
259219
case ReplaceMode:
260-
result = ApplyConverter(baseVal, [this, &context](auto str) {
220+
result = ApplyStringConverter(baseVal, [this, &context](auto str) -> InternalValue {
261221
auto oldStr = GetAsSameString(str, this->GetArgumentValue("old", context));
262222
auto newStr = GetAsSameString(str, this->GetArgumentValue("new", context));
263223
auto count = ConvertToInt(this->GetArgumentValue("count", context));
@@ -272,7 +232,7 @@ InternalValue StringConverter::Filter(const InternalValue& baseVal, RenderContex
272232
});
273233
break;
274234
case TruncateMode:
275-
result = ApplyConverter(baseVal, [this, &context, &isAlNum](auto str) {
235+
result = ApplyStringConverter(baseVal, [this, &context, &isAlNum](auto str) -> InternalValue {
276236
auto length = ConvertToInt(this->GetArgumentValue("length", context));
277237
auto killWords = ConvertToBool(this->GetArgumentValue("killwords", context));
278238
auto end = GetAsSameString(str, this->GetArgumentValue("end", context));

src/testers.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,30 @@ bool ValueTester::Test(const InternalValue& baseVal, RenderContext& context)
188188
{
189189
bool result = false;
190190
auto valKind = Apply<ValueKindGetter>(baseVal);
191+
enum
192+
{
193+
EvenTest,
194+
OddTest
195+
};
196+
197+
int testMode = EvenTest;
198+
auto evenOddTest = [&testMode, valKind](const InternalValue& val) -> bool
199+
{
200+
bool result = false;
201+
if (valKind == ValueKind::Integer)
202+
{
203+
auto intVal = ConvertToInt(val);
204+
result = testMode == (intVal & 1) == (EvenTest ? 0 : 1);
205+
}
206+
else if (valKind == ValueKind::Double)
207+
{
208+
auto dblVal = ConvertToDouble(val);
209+
int64_t intVal = dblVal;
210+
if (dblVal == intVal)
211+
result = testMode == (intVal & 1) == (EvenTest ? 0 : 1);
212+
}
213+
return result;
214+
};
191215

192216
switch (m_mode)
193217
{
@@ -235,12 +259,58 @@ bool ValueTester::Test(const InternalValue& baseVal, RenderContext& context)
235259
break;
236260
}
237261
case IsEvenMode:
262+
{
263+
testMode = EvenTest;
264+
result = evenOddTest(baseVal);
238265
break;
266+
}
239267
case IsOddMode:
268+
{
269+
testMode = OddTest;
270+
result = evenOddTest(baseVal);
240271
break;
272+
}
241273
case IsLowerMode:
274+
if (valKind != ValueKind::String)
275+
{
276+
result = false;
277+
}
278+
else
279+
{
280+
result = ApplyStringConverter(baseVal, [](const auto& str) {
281+
bool result = true;
282+
for (auto& ch : str)
283+
{
284+
if (std::isalpha(ch, std::locale()) && std::isupper(ch, std::locale()))
285+
{
286+
result = false;
287+
break;
288+
}
289+
}
290+
return result;
291+
});
292+
}
242293
break;
243294
case IsUpperMode:
295+
if (valKind != ValueKind::String)
296+
{
297+
result = false;
298+
}
299+
else
300+
{
301+
result = ApplyStringConverter(baseVal, [](const auto& str) {
302+
bool result = true;
303+
for (auto& ch : str)
304+
{
305+
if (std::isalpha(ch, std::locale()) && std::islower(ch, std::locale()))
306+
{
307+
result = false;
308+
break;
309+
}
310+
}
311+
return result;
312+
});
313+
}
244314
break;
245315

246316
}

0 commit comments

Comments
 (0)