Skip to content

Commit 1483843

Browse files
committed
mpq: optimize: use lookup table for filename normalization
1 parent 02acb5b commit 1483843

1 file changed

Lines changed: 51 additions & 14 deletions

File tree

src/noggit/MPQ.cpp

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -336,26 +336,63 @@ namespace noggit
336336
{
337337
namespace mpq
338338
{
339+
namespace
340+
{
341+
// \todo(c++20): std::iota
342+
template<typename T, typename It>
343+
constexpr void constexprIota(It begin, It end, T value)
344+
{
345+
for (; begin != end; ++begin, ++value)
346+
{
347+
*begin = value;
348+
}
349+
}
350+
351+
constexpr auto build_to_lower_backslash_lookup_table()
352+
{
353+
std::array<unsigned char, std::numeric_limits<unsigned char>::max() + 1> r = {};
354+
constexprIota(r.begin(), r.end(), static_cast<unsigned char>(0));
355+
for (unsigned char upper = 'A', lower = 'a'; upper <= 'Z'; ++upper, ++lower)
356+
{
357+
r[upper] = lower;
358+
}
359+
r['\\'] = '/';
360+
return r;
361+
}
362+
constexpr auto build_to_upper_slash_lookup_table()
363+
{
364+
std::array<unsigned char, std::numeric_limits<unsigned char>::max() + 1> r = {};
365+
constexprIota(r.begin(), r.end(), static_cast<unsigned char>(0));
366+
for (unsigned char upper = 'A', lower = 'a'; upper <= 'Z'; ++upper, ++lower)
367+
{
368+
r[lower] = upper;
369+
}
370+
r['/'] = '\\';
371+
return r;
372+
}
373+
374+
constexpr auto const to_lower_backslash_lookup_table = build_to_lower_backslash_lookup_table();
375+
constexpr auto const to_upper_slash_lookup_table = build_to_upper_slash_lookup_table();
376+
377+
constexpr char to_lower_backslash(char c)
378+
{
379+
return to_lower_backslash_lookup_table[static_cast<unsigned char>(c)];
380+
}
381+
constexpr char to_upper_slash(char c)
382+
{
383+
return to_upper_slash_lookup_table[static_cast<unsigned char>(c)];
384+
}
385+
}
386+
387+
339388
std::string normalized_filename (std::string filename)
340389
{
341-
std::transform (filename.begin(), filename.end(), filename.begin(), [](unsigned char c) { return std::tolower(c); });
342-
std::transform ( filename.begin(), filename.end(), filename.begin()
343-
, [] (char c)
344-
{
345-
return c == '\\' ? '/' : c;
346-
}
347-
);
390+
std::transform (filename.begin(), filename.end(), filename.begin(), to_lower_backslash);
348391
return filename;
349392
}
350393
std::string normalized_filename_insane (std::string filename)
351394
{
352-
std::transform (filename.begin(), filename.end(), filename.begin(), [](unsigned char c) { return std::toupper(c); });
353-
std::transform ( filename.begin(), filename.end(), filename.begin()
354-
, [] (char c)
355-
{
356-
return c == '/' ? '\\' : c;
357-
}
358-
);
395+
std::transform (filename.begin(), filename.end(), filename.begin(), to_upper_slash);
359396
return filename;
360397
}
361398
}

0 commit comments

Comments
 (0)