Skip to content

Commit ea7b1e8

Browse files
author
me
committed
try map
1 parent 71e17da commit ea7b1e8

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

src/http.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <cctype>
55
#include <algorithm>
66
#include <filesystem>
7+
#include <unordered_map>
78
#include <boost/asio/version.hpp>
89
#include "http.h"
910

@@ -428,30 +429,59 @@ namespace http
428429

429430
//----------------------------------------------------------------------------------------------------------------
430431

431-
constexpr char fast_ascii_tolower(const char c)
432+
constexpr char fast_ascii_tolower(const char c) noexcept
432433
{
433434
// The following is a tad faster than std::tolower(c)
434435
return (c >= 'A' && c <= 'Z') ? (c | 0x20) : c;
435436
}
436437

437-
constexpr bool case_insenstive_equals(std::string_view a, std::string_view b)
438+
constexpr bool case_insenstive_equals(std::string_view a, std::string_view b) noexcept
438439
{
439440
return a.size() == b.size() && std::equal(begin(a), end(a), begin(b), [](char ac, char bc) {
440441
return fast_ascii_tolower(ac) == fast_ascii_tolower(bc);
441442
});
442443
}
443444

445+
struct ci_hash
446+
{
447+
constexpr size_t operator()(std::string_view sv) const noexcept
448+
{
449+
constexpr std::size_t fnv_offset_basis = 14695981039346656037ull;
450+
constexpr std::size_t fnv_prime = 1099511628211ull;
451+
std::size_t hash = fnv_offset_basis;
452+
453+
for (char c : sv) {
454+
hash ^= static_cast<std::size_t>(fast_ascii_tolower(c));
455+
hash *= fnv_prime;
456+
}
457+
458+
return hash;
459+
}
460+
};
461+
462+
struct ci_compare { constexpr bool operator()(std::string_view lhs, std::string_view rhs) const noexcept { return case_insenstive_equals(lhs, rhs); } };
463+
464+
const auto FIELD_MAP = []
465+
{
466+
std::unordered_map<std::string_view, field, ci_hash, ci_compare> m;
467+
for (size_t i = 0 ; i < std::size(FIELDS) ; ++i)
468+
m[FIELDS[i]] = (field)i;
469+
return m;
470+
}();
471+
444472
std::string_view field_label(field f)
445473
{
446474
return FIELDS[f];
447475
}
448476

449477
field field_enum(std::string_view f)
450478
{
451-
for (unsigned int i = 0 ; i < std::size(FIELDS) ; ++i)
452-
if (case_insenstive_equals(FIELDS[i], f))
453-
return (field)i;
454-
return unknown_field;
479+
const auto it = FIELD_MAP.find(f);
480+
return it != end(FIELD_MAP) ? it->second : unknown_field;
481+
// for (unsigned int i = 0 ; i < std::size(FIELDS) ; ++i)
482+
// if (case_insenstive_equals(FIELDS[i], f))
483+
// return (field)i;
484+
// return unknown_field;
455485
}
456486

457487
//----------------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)