mirror of
https://github.com/NixOS/nix
synced 2025-06-25 10:41:16 +02:00
Merge pull request #13137 from xokdvium/regex-cache-transparent
libexpr: Use C++20 heterogeneous lookup for RegexCache
This commit is contained in:
commit
bd80a4f176
2 changed files with 44 additions and 5 deletions
|
@ -4311,9 +4311,7 @@ struct RegexCache
|
||||||
{
|
{
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
// TODO use C++20 transparent comparison when available
|
std::unordered_map<std::string, std::regex, StringViewHash, std::equal_to<>> cache;
|
||||||
std::unordered_map<std::string_view, std::regex> cache;
|
|
||||||
std::list<std::string> keys;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync<State> state_;
|
Sync<State> state_;
|
||||||
|
@ -4324,8 +4322,14 @@ struct RegexCache
|
||||||
auto it = state->cache.find(re);
|
auto it = state->cache.find(re);
|
||||||
if (it != state->cache.end())
|
if (it != state->cache.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
state->keys.emplace_back(re);
|
/* No std::regex constructor overload from std::string_view, but can be constructed
|
||||||
return state->cache.emplace(state->keys.back(), std::regex(state->keys.back(), std::regex::extended)).first->second;
|
from a pointer + size or an iterator range. */
|
||||||
|
return state->cache
|
||||||
|
.emplace(
|
||||||
|
std::piecewise_construct,
|
||||||
|
std::forward_as_tuple(re),
|
||||||
|
std::forward_as_tuple(/*s=*/re.data(), /*count=*/re.size(), std::regex::extended))
|
||||||
|
.first->second;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -97,4 +97,39 @@ extern template std::string dropEmptyInitThenConcatStringsSep(std::string_view,
|
||||||
* Arguments that need to be passed to ssh with spaces in them.
|
* Arguments that need to be passed to ssh with spaces in them.
|
||||||
*/
|
*/
|
||||||
std::list<std::string> shellSplitString(std::string_view s);
|
std::list<std::string> shellSplitString(std::string_view s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash implementation that can be used for zero-copy heterogenous lookup from
|
||||||
|
* P1690R1[1] in unordered containers.
|
||||||
|
*
|
||||||
|
* [1]: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1690r1.html
|
||||||
|
*/
|
||||||
|
struct StringViewHash
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
using HashType = std::hash<std::string_view>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using is_transparent = void;
|
||||||
|
|
||||||
|
auto operator()(const char * str) const
|
||||||
|
{
|
||||||
|
/* This has a slight overhead due to an implicit strlen, but there isn't
|
||||||
|
a good way around it because the hash value of all overloads must be
|
||||||
|
consistent. Delegating to string_view is the solution initially proposed
|
||||||
|
in P0919R3. */
|
||||||
|
return HashType{}(std::string_view{str});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator()(std::string_view str) const
|
||||||
|
{
|
||||||
|
return HashType{}(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator()(const std::string & str) const
|
||||||
|
{
|
||||||
|
return HashType{}(std::string_view{str});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue