#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <optional>
#include <cassert>
#include <chrono>
struct WildCardParser
{
//? ΠΡΠ±ΠΎΠΉ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠΈΠΌΠ²ΠΎΠ»
//* ΠΠΎΠ»Ρ ΠΈΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ²
//# ΠΡΠ±Π°Ρ ΠΎΠ΄Π½ΠΎΠ·Π½Π°ΡΠ½Π°Ρ ΡΠΈΡΡΠ° (0-9)
//[charlist] ΠΡΠ±ΠΎΠΉ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠΈΠΌΠ²ΠΎΠ» Π² charlist
//[!charlist] ΠΡΠ±ΠΎΠΉ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠΈΠΌΠ²ΠΎΠ», ΠΎΡΡΡΡΡΡΠ²ΡΡΡΠΈΠΉ Π² charlist
//To match the special characters left bracket ([), question mark (?), number sign (#)
//and asterisk (*), enclose them in brackets. The right bracket (])
//can't be used within a group to match itself, but it can be used outside a group as an individual character.
constexpr static bool ShowDebugOutput = !true;
constexpr static std::wstring_view DebugPrefix = L" dbg: ";
constexpr static wchar_t WCHAR_exclamation{ L'!' };
constexpr static wchar_t WCHAR_openbrace{ L'[' };
constexpr static wchar_t WCHAR_closebrace{ L']' };
constexpr static wchar_t WCHAR_hyphen{ L'-' };
constexpr static wchar_t WCHAR_numbersign{ L'#' };
constexpr static wchar_t WCHAR_asterisk{ L'*' };
constexpr static wchar_t WCHAR_question{ L'?' };
constexpr static wchar_t WCHAR_zero{ L'0' };
constexpr static wchar_t WCHAR_nine{ L'9' };
//ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΠΏΡΠΎΠΏΠ°ΡΡΠ΅Π½Π½ΡΡ
ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΡΡ
ΡΠΊΠΎΠ±ΠΊΠ°Ρ
struct s_SquareBracketsInfo
{
private:
//#todo - Π΄Π»Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΡΡΡΠΎΠΊΡ ΠΌΠ°ΡΡΠΈΠ²ΠΎΠΌ, ΡΠΎΠ³Π΄Π° ΡΠ±Π΅ΡΡΡΡΡ ΡΠ°Π±ΠΎΡΠ° Ρ ΠΊΡΡΠ΅ΠΉ
std::wstring m_CharsList;//ΡΠΏΠΈΡΠΎΠΊ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ², ΡΠ°ΡΠΊΡΡΡΡΠΉ ΠΈΠ· ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΡΡ
ΡΠΊΠΎΠ±ΠΎΠΊ
size_t m_ClosingBracketPos{};//ΠΏΠΎΠ·ΠΈΡΠΈΡ Π·Π°ΠΊΡΡΠ²Π°ΡΡΠ΅ΠΉ ΡΠΊΠΎΠ±ΠΊΠΈ
bool m_Inverted{};//ΡΠ»Π°Π³ ΠΈΠ½Π²Π΅ΡΡΠΈΠΈ ΠΈΠ· Π½Π°ΡΠ°Π»Π° ΡΠΊΠΎΠ±ΠΎΠΊ
private:
//Π΄Π»Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ: ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΠΉ ΡΠ°ΡΠΏΠ°ΡΡΠ΅Π½Π½ΡΠΉ ΡΠ΅ΠΊΡΡ.
//ΠΡΠ»ΠΈ ΠΎΠ½ ΡΠ°ΠΊΠΎΠΉ ΠΆΠ΅, ΡΠΎ Π·Π°Π½ΠΎΠ²ΠΎ ΠΏΠ°ΡΡΠΈΡΡ Π½Π΅ Π½ΡΠΆΠ½ΠΎ, Π²ΡΡ ΡΠΆΠ΅ Π³ΠΎΡΠΎΠ²ΠΎ
std::optional<std::wstring_view> m_lastParsedText;
public:
bool IsSetEmpty()const noexcept
{
return m_CharsList.empty();
}
bool TestChar(const wchar_t c)const noexcept
{
const bool contains = (m_CharsList.find(c) != m_CharsList.npos);
if (m_Inverted)
{
return !contains;
}
else
{
return contains;
}
}
bool Parse(const std::wstring_view text)
{
if (m_lastParsedText)
{
if (m_lastParsedText->size() == text.size())
{
if (m_lastParsedText->data() == text.data())
{
if constexpr (ShowDebugOutput)std::wcout << DebugPrefix << L"m_lastParsedText reused\n";
return true;
}
}
}
const auto res = Parse__(text);
if (res)
{
//Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅ΠΌ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΠΏΠ°ΡΡΡΠ½Π½ΡΠΉ ΡΠ΅ΠΊΡΡ
m_lastParsedText = text;
//if constexpr(ShowDebugOutput)std::wcout<<DebugPrefix<<L"m_lastParsedText saved\n";
assert(m_lastParsedText);
assert(!m_lastParsedText->empty());
assert(m_lastParsedText->size() > m_ClosingBracketPos);
assert((*m_lastParsedText)[m_ClosingBracketPos] == WCHAR_closebrace);
}
else
{
//ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΌΠΎΠ³Π»ΠΎ ΠΌΠ΅Π½ΡΡΡΡΡ, Π·Π°Π±ΡΠ²Π°Π΅ΠΌ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΡΠ΅ΠΊΡΡ
m_lastParsedText.reset();
if constexpr (ShowDebugOutput)std::wcout << DebugPrefix << L"m_lastParsedText reset\n";
}
return res;
}
size_t PosOfClosingBracket()const noexcept
{
return m_ClosingBracketPos;
}
private:
//Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΡΠΏΠΈΡΠΊΠ° ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ² ΠΈΠ· ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΡΡ
ΡΠΊΠΎΠ±ΠΎΠΊ
//text - Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ Ρ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΡΠΈΠΌΠ²ΠΎΠ»Π° ΠΏΠΎΡΠ»Π΅ ΠΎΡΠΊΡΡΠ²Π°ΡΡΠ΅ΠΉ ΡΠΊΠΎΠ±ΠΊΠΈ
bool Parse__(std::wstring_view text)
{
//ΡΡΡ Π½Π΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΡΡ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ ΠΏΠΎΠ²ΡΠΎΡΠΎΠ² [ababa].
//ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ, ΡΡΠΎ ΡΠ·Π΅Ρ ΡΠ°ΠΌ ΡΠ΅Π±Π΅ Π½Π΅ Π²ΡΠ°Π³, Π° Π΅ΡΠ»ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π°Π»Π³ΠΎΡΠΈΡΠΌ
//ΡΠ΄Π°Π»Π΅Π½ΠΈΡ ΠΏΠΎΠ²ΡΠΎΡΠΎΠ² - ΡΡΠΎ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΡΡΠΎΡΠ½Π½Π°Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½Π°Ρ Π½Π°Π³ΡΡΠ·ΠΊΠ°
if (text.empty())return false;
m_CharsList.clear();
m_ClosingBracketPos = {};
m_Inverted = {};
//ΡΠΏΡΠ°Π²Π° ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΠ²Π°Π΅ΠΌΡΡ ΠΏΠΎ Π·Π°ΠΊΡΡΠ²Π°ΡΡΠ΅ΠΉ ΡΠΊΠΎΠ±ΠΊΠ΅
{
const auto pos = text.find_first_of(WCHAR_closebrace);
if (pos == text.npos)return false;
text = text.substr(0, pos);
m_ClosingBracketPos = pos;
}
//ΡΠ»Π°Π³ ΠΈΠ½Π²Π΅ΡΡΠΈΠΈ
if (!text.empty() && text.front() == WCHAR_exclamation)
{
//ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° ΠΎΠ΄ΠΈΠ½ΠΎΠΊΠΈΠΉ Π²ΠΎΡΠΊΠ»ΠΈΡΠ°ΡΠ΅Π»ΡΠ½ΡΠΉ Π·Π½Π°ΠΊ
if (text.size() == 1)
{
m_CharsList.push_back(WCHAR_exclamation);
return true;
}
m_Inverted = true;
text.remove_prefix(1);
}
//ΡΠ΅ΠΉΡΠ°Ρ text ΡΠ°ΠΊΠΎΠΉ:
//begin,front - ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠΈΠΌΠ²ΠΎΠ» ΠΏΠΎΡΠ»Π΅ ΠΎΡΠΊΡΡΠ²Π°ΡΡΠ΅ΠΉ ΡΠΊΠΎΠ±ΠΊΠΈ ΠΈΠ»ΠΈ ΠΈΠ½Π²Π΅ΡΡΠΈΡΡΡΡΠ΅Π³ΠΎ Π·Π½Π°ΠΊΠ°
//back - ΡΠΈΠΌΠ²ΠΎΠ» ΠΏΠ΅ΡΠ΅Π΄ Π·Π°ΠΊΡΡΠ²Π°ΡΡΠ΅ΠΉ ΡΠΊΠΎΠ±ΠΊΠΎΠΉ
//end - Π·Π°ΠΊΡΡΠ²Π°ΡΡΠ°Ρ ΡΠΊΠΎΠ±ΠΊΠ°
auto text_cur = text.cbegin();
auto const text_end = text.cend();
while (text_cur != text_end)
{
//text_cur - ΡΠ΅ΠΊΡΡΠΈΠΉ ΡΠΈΠΌΠ²ΠΎΠ»
//Π΅ΡΠ»ΠΈ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠΈΠΌΠ²ΠΎΠ» ΡΡΠΎ ΠΌΠΈΠ½ΡΡ,
if (const auto hyphen = text_cur + 1; hyphen != text_end && *hyphen == WCHAR_hyphen)
{
//ΡΠΎ ΠΏΠΎΡΠ»Π΅ ΠΌΠΈΠ½ΡΡΠ° ΡΠΎΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ ΡΠΈΠΌΠ²ΠΎΠ»
if (const auto second = hyphen + 1; second != text_end)
{
//ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° X-Z, ΡΠ΅ΠΉΡΠ°Ρ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌΡΡ Π½Π° X
auto c1 = *text_cur;
auto c2 = *second;
if (c1 > c2)std::swap(c1, c2);
for (auto c = c1; c <= c2; ++c)m_CharsList.push_back(c);
//ΠΈΠ΄ΡΠΌ Π΄Π°Π»ΡΡΠ΅
//ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌ ΡΠΈΡΡΠ°ΡΠΈΡ Ρ ΡΡΠ°ΠΌΠ²Π°Π΅ΠΌ a-b-c
//Π΅ΡΠ»ΠΈ ΠΏΠΎΡΠ»Π΅ second Π»Π΅ΠΆΠΈΡ ΠΌΠΈΠ½ΡΡ
const auto next_after_second = second + 1;
if (next_after_second != text_end && *next_after_second == WCHAR_hyphen)
{
text_cur = second;
}
else
{
text_cur = second + 1;
}
continue;
}
}
//ΠΎΠ΄ΠΈΠ½ ΡΠΈΠΌΠ²ΠΎΠ» ΠΊΠ»Π°Π΄ΡΠΌ Π² ΡΠΏΠΈΡΠΎΠΊ
m_CharsList.push_back(*text_cur);
text_cur++;
}
return true;
}
};
static bool Match(const std::wstring_view text, const std::wstring_view wc)
{
//ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΠΏΡΠΎΠΏΠ°ΡΡΠ΅Π½Π½ΡΡ
ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΡΡ
ΡΠΊΠΎΠ±ΠΊΠ°Ρ
s_SquareBracketsInfo SBInfo;
return Match_recursed(text, wc, SBInfo);
}
private:
static bool Match_recursed(const std::wstring_view text, const std::wstring_view wc, s_SquareBracketsInfo& SBInfo)
{
auto wc_cur = wc.cbegin();
auto const wc_end = wc.cend();
auto text_cur = text.cbegin();
auto const text_end = text.cend();
while (wc_cur != wc_end)
{
if (text_cur == text_end)
{
//Π·Π°Π²Π΅ΡΡΠ°ΡΡΠΈΠ΅ Π·Π²ΡΠ·Π΄ΠΎΡΠΊΠΈ ΠΈΠ³Π½ΠΎΡΠΈΡΡΠ΅ΠΌ
if (*wc_cur == WCHAR_asterisk)
{
++wc_cur;
continue;
}
//Π·Π°Π²Π΅ΡΡΠ°ΡΡΠΈΠ΅ ΠΏΡΡΡΡΠ΅ ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΡΠ΅ ΡΠΊΠΎΠ±ΠΊΠΈ ΠΈΠ³Π½ΠΎΡΠΈΡΡΠ΅ΠΌ
if (*wc_cur == WCHAR_openbrace && (wc_cur + 1) != wc_end && *(wc_cur + 1) == WCHAR_closebrace)
{
wc_cur += 2;
continue;
}
return false;
}
switch (*wc_cur)
{
default:
{
//Π»ΡΠ±ΠΎΠΉ Π΄ΡΡΠ³ΠΎΠΉ ΡΠΈΠΌΠ²ΠΎΠ» - Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ²ΠΏΠ°ΡΡΡ Ρ ΡΠ΅ΠΊΡΡΠΎΠ²ΡΠΌ
if (*wc_cur == *text_cur)
{
++wc_cur;
++text_cur;
}
else
{
return false;
}
}break;
case WCHAR_question:
{
++wc_cur;
++text_cur;
}break;
case WCHAR_numbersign:
{
if (WCHAR_zero <= *text_cur && *text_cur <= WCHAR_nine)
{
++wc_cur;
++text_cur;
}
else
{
return false;
}
}break;
case WCHAR_openbrace:
{
const auto wc_next = wc_cur + 1;
if (!SBInfo.Parse({ &*wc_next, size_t(wc_end - wc_next) }))
{
//ΠΎΡΠΈΠ±ΠΊΠ° ΠΏΠ°ΡΡΠΈΠ½Π³Π° ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΡΡ
ΡΠΊΠΎΠ±ΠΎΠΊ
return false;
}
if (SBInfo.IsSetEmpty())
{
//[]
wc_cur = wc_next + SBInfo.PosOfClosingBracket() + 1;
}
else if (SBInfo.TestChar(*text_cur))
{
//ΡΠΈΠΌΠ²ΠΎΠ» ΡΡΡΠΎΠΊΠΈ Π΅ΡΡΡ Π² ΡΠΏΠΈΡΠΊΠ΅
wc_cur = wc_next + SBInfo.PosOfClosingBracket() + 1;
++text_cur;
}
else
{
return false;
}
}break;
case WCHAR_asterisk:
{
const auto wc_next = wc_cur + 1;
if (wc_next == wc_end)
{
//ΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΡΠΈΠΌΠ²ΠΎΠ»Π° Π² ΠΌΠ°ΡΠΊΠ΅ Π½Π΅Ρ, ΠΏΠΎΡΡΠΎΠΌΡ Π²ΡΡ ΠΎΡΡΠ°Π»ΡΠ½ΠΎΠ΅ - ΠΌΠ°ΡΡΠΈΡΡΡ
return true;
}
//Π½ΡΠΆΠ½ΠΎ Π²ΡΡΡΠ½ΠΈΡΡ, ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ² Π²ΠΎΠ·ΡΠΌΡΡ Π·Π²ΡΠ·Π΄ΠΎΡΠΊΠ° ΠΈΠ· ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΡΡΡΠΎΠΊΠΈ.
//ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΡΠ΅ΠΊΡΡΡΠΈΡ
auto text_lef = text_end;
while (1)
{
//ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΠΌ, ΡΡΠΎ Π·Π²ΡΠ·Π΄ΠΎΡΠΊΠ° Π·Π°Π±ΠΈΡΠ°Π΅Ρ [text_lef...text_end).
//Π’ΠΎΠ³Π΄Π° ΡΡΠ° ΡΠ°ΡΡΡ ΡΡΡΠΎΠΊΠΈ Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠΌΠ°ΡΡΠΈΡΡΡ Ρ ΠΎΡΡΠ°Π²ΡΠ΅ΠΉΡΡ ΡΠ°ΡΡΡΡ ΠΌΠ°ΡΠΊΠΈ
if (Match_recursed({ &*text_lef, size_t(text_end - text_lef) }, { &*wc_next, size_t(wc_end - wc_next) }, SBInfo))
{
return true;
}
if (text_lef == text_cur)
{
return false;
}
text_lef--;
}
}break;
}
}
//ΡΡΡΠΎΠΊΠ° ΠΈ ΠΌΠ°ΡΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ Π΄ΠΎΡΠΈΡΠ°Π½Ρ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ
return wc_cur == wc_end && text_cur == text_end;
}
};
bool LikeVB(const wchar_t* s, const wchar_t* p)
{
const wchar_t* rs = 0, * rp = 0;
bool res = 0;//result [...]
while (1) {
if (*p == L'[') {
if (*(p + 1) == L']') { p += 2; continue; }// ""=="[]"
bool b = false, match = false;
const wchar_t* pt = p; //p_temp
if (*(++pt) == L'!' && *(pt + 1) != L']') { b = true; ++pt; }//[!...] not [!]
while (*pt != L']') {
if (*pt == L'\0') { throw 93; }//Π΅ΡΠ»ΠΈ Π·Π°Π±ΡΠ»ΠΈ Π·Π°ΠΊΡΡΠ²Π°ΡΡΡΡ ΡΠΊΠΎΠ±ΠΊΡ//' Throws Error 93 (invalid pattern string).
if (*(pt + 1) == L'-' && *(pt + 2) != L']')//Π΅ΡΠ»ΠΈ Π΅ΡΡΡ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ ... - ...
{
if (*s >= *pt && *s <= *(pt + 2))
{
if (b) {
res = false; break;
}//Π΅ΡΠ»ΠΈ ΡΠ°ΠΊΠΈΡ
ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ² Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ
else {
match = true;
}//Π΅ΡΠ»ΠΈ Π½Π°ΡΠ»ΠΈ
}
pt += 2; //for [1-4-9]
}
else { //Π΅ΡΠ»ΠΈ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠΈΠΌΠ²ΠΎΠ»
if (*s == *pt) {
if (b) {
res = false; break;
}//Π΅ΡΠ»ΠΈ ΡΠ°ΠΊΠΈΡ
ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ² Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ
else {
match = true;
}//Π΅ΡΠ»ΠΈ Π½Π°ΡΠ»ΠΈ
}
++pt;
}
}
if (b == match) {
res = false;
}
else {
res = true;
++s; p = ++pt;//Π·Π°ΠΊΡΡΠ²Π°ΡΡΠ°Ρ ΡΠΊΠΎΠ±ΠΊΠ°
}
}
if (res) {
res = false;
}
else if (*p == L'#' && *s <= L'9' && *s >= L'0') {
++s, ++p;
}
else if (*p == L'*') {
rs = s, rp = ++p;
}
else if (!*s) {
return !*p;
}
else if (*p == L'?' || *s == *p && *p != L'[' && *p != L'#') {
++s, ++p;
}
else if (rs) {
s = ++rs, p = rp;
}
else {
return false;
}
}
}
int main()
{
constexpr size_t passes= 5;
constexpr size_t testsRepeats= 200000;
using std::wcout,std::to_wstring;
using std::chrono::steady_clock,std::chrono::duration_cast,std::chrono::milliseconds;
using namespace std::string_literals;
const std::vector < std::vector<const wchar_t* >> testArr =
{
{L"XYXZZXYXYXZZXY", L"*X*X?*X*X?",L"True"},
{L"aBBBa", L"a*a",L"True"},
{L"F" , L"[A-Z]" ,L"True"},
{L"F" , L"[!A-Z]",NULL},
{L"a2a" , L"a#a", L"True"},
{L"aM5b" , L"a[L-P]#[!c-e]", L"True"},
{L"BAT123khg" , L"B?T*", L"True"},
{L"CAT123khg" , L"B?T*",NULL},
{L"ab" , L"a*b",L"True"},
{L"a*b" , L"a [*]b", NULL},
{L"axxxxxb" , L"a [*]b",NULL},
{L"a [xyz" , L"a [[]*", L"True"},
{L"aM5b" , L"a*?b", L"True"},
{L"aM5b" , L"a*[1-4-9][!c-e]", L"True"},
{L"aM55b" , L"a*[1-4-9][!c-e]", L"True"},
{L"aM55b" , L"a*[1-45-9][!c-e]", L"True"},
{L"aM5b" , L"*#[!c-e]", L"True"},
{L"5*", L"5[*]", L"True"},
{L"?n", L"[?]n", L"True"},
{L"a", L"[a-cdf]", L"True"},
{L"b", L"[a-cdf]", L"True"},
{L"c", L"[a-cdf]", L"True"},
{L"d", L"[a-cdf]", L"True"},
{L"f", L"[a-cdf]", L"True"},
{L"-", L"[-acdf]", L"True"},
{L"a", L"[-acdf]", L"True"},
{L"c", L"[-acdf]", L"True"},
{L"d", L"[-acdf]", L"True"},
{L"f", L"[-acdf]", L"True"},
{L"[", L"[ [ ]", L"True"},
{L"]", L"]", L"True"},
{L"abc_d", L"abc[_]d*", L"True"},
{L"abc_de", L"abc[_]d*", L"True"},
{L"abcd", L"abc[def]", L"True"},
{L"abce", L"abc[def]", L"True"},
{L"abcf", L"abc[def]", L"True"},
{L"abcdef", L"abc*[de]ef", L"True"},
{L"abcyef", L"abc[xz]ef", NULL},
{L"abcxef", L"abc[xz]ef", L"True"},
{L"abcyef", L"abc[!xz]ef", L"True"},
{L"abcxef", L"abc[!xz]ef", NULL},
{L"ac5c5b", L"a*[1-56-9][!c-e]", L"True"},
{L"", L"", L"True"},
{L"", L"*", L"True"},
{L"", L"[]", L"True"},
{L"", L"[!]", NULL},
{L"", L"[]*", L"True"},
{L"", L"[!]*", NULL},
{L"1", L"[!]*", NULL},
{L"1", L"[]*", L"True"},
{L"1", L"[!]*", NULL},
{L"1", L"[!]", NULL},
{L"1", L"*[!]", NULL},
{L"1", L"*[]", L"True"},
{L"1", L"#[]", L"True"},
{L"1", L"#[!]", NULL},
{L"12", L"#[!]", NULL},
{L"12", L"#[!]*", NULL},
{L"123", L"*[!]*", NULL},
{L"1!3", L"*[!]*", L"True"},
{L"!", L"*[!]*", L"True"},
{L"!", L"[!]", L"True"},
{L"!a", L"*[!a]*", L"True"},
{L"!a", L"[!a]*", L"True"},
{L"!a", L"*[!a]", NULL},
{L"!a", L"[!a]", NULL},
{L"a", L"[!a]", NULL},
{L"b", L"[!a]", L"True"},
{L"2", L"#[]", L"True"},
{L"*", L"[*]", L"True"},
{L"1", L"[*]", NULL},
{L"!", L"[!-!]", NULL},
{L"1", L"[!-!]", L"True"},
{L"!", L"[-!]", L"True"},
{L"!", L"[!-]", L"True"},
{L"-", L"[!-]", NULL},
{L"-", L"[-]", L"True"},
{L"***", L"*[*]*", L"True"},
{L"???", L"?[?]?", L"True"},
{L"###", L"#[#]#", NULL},
{L"[[[[[", L"[[]?*[[]", L"True"},
//{L"a [xyz" , L"a [*", NULL} //' Throws Error 93 (invalid pattern string).
};
try
{
wcout << L"LikeVB...\n";
for(size_t tes_pas=0; tes_pas<passes; tes_pas++)
{
const auto start = steady_clock::now();
size_t ok{},error{};
for(size_t tes_rep=0; tes_rep<testsRepeats; tes_rep++)
{
for(const auto& test:testArr){(LikeVB(test[0], test[1]) == !!test[2]) ? ok++ : error++;}
}
wcout << "ok="<<ok<<" error="<<error;
wcout << L" ms=" + to_wstring(duration_cast<milliseconds> (steady_clock::now() - start).count()) + L"\n";
}
wcout << '\n';
wcout << L"WildCardParser::Match...\n";
for(size_t tes_pas=0; tes_pas<passes; tes_pas++)
{
const auto start = steady_clock::now();
size_t ok{},error{};
for(size_t tes_rep=0; tes_rep<testsRepeats; tes_rep++)
{
for(const auto& test:testArr){(WildCardParser::Match(test[0], test[1]) == !!test[2]) ? ok++ : error++;}
}
wcout << "ok="<<ok<<" error="<<error;
wcout << L" ms=" + to_wstring(duration_cast<milliseconds> (steady_clock::now() - start).count()) + L"\n";
}
wcout << '\n';
//std::ignore=system("pause");
return 0;
}
catch (int& e) { std::ignore=system("pause"); return e; }
catch (...) { std::ignore=system("pause"); return -1; }
}