diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-07-28 19:19:32 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-07-28 19:19:32 +0200 |
| commit | 36a274c9a8bca944234589220def025d3920b3ef (patch) | |
| tree | f198ad272b74ffa3abb13e5063b55514d521e1f6 /boot/result.cc | |
| parent | 5cdaceb77af6a1d98145f8afb34ce6884e21a3d6 (diff) | |
| download | elna-36a274c9a8bca944234589220def025d3920b3ef.tar.gz | |
Enforce case label uniqueness and constness
Diffstat (limited to 'boot/result.cc')
| -rw-r--r-- | boot/result.cc | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/boot/result.cc b/boot/result.cc index 86b0e7a..0eb5c12 100644 --- a/boot/result.cc +++ b/boot/result.cc @@ -17,6 +17,8 @@ along with GCC; see the file COPYING3. If not see #include "elna/boot/result.h" +#include <numeric> + namespace elna::boot { location::location(const std::size_t line, const std::size_t column) @@ -137,6 +139,49 @@ namespace elna::boot { return this->m_exported; } + + std::size_t constant_value_hash::operator()(const elna::boot::constant_value& value) const noexcept + { + return std::visit([](auto&& alternative) -> std::size_t { + using T = std::decay_t<decltype(alternative)>; + + return std::hash<T>{}(alternative); + }, value); + } + + bool constant_value_hash::operator()(const elna::boot::constant_value& lhs, + const elna::boot::constant_value& rhs) const noexcept + { + return std::visit([](auto&& first, auto&& second) -> bool { + using T = std::decay_t<decltype(first)>; + using U = std::decay_t<decltype(second)>; + + if constexpr (std::is_same_v<T, U>) + { + return first == second; + } + else + { + return false; + } + }, lhs, rhs); + } + + hash_accumulator hash_accumulator::operator+(const std::size_t& that) const + { + hash_accumulator result{}; + + result.m_seed ^= that + hash_accumulator::golden_ratio + // NOLINTNEXTLINE(readability-magic-numbers) + + (this->m_seed << 6) + (this->m_seed >> 2); + + return result; + } + + std::size_t hash_accumulator::seed() const + { + return this->m_seed; + } } std::size_t std::hash<elna::boot::identifier>::operator()( @@ -144,3 +189,33 @@ std::size_t std::hash<elna::boot::identifier>::operator()( { return std::hash<std::string>{}(key.name()); } + +std::size_t std::hash<elna::boot::global_address>::operator()( + const elna::boot::global_address& key) const noexcept +{ + return std::hash<std::string>{}(key.name); +} + +std::size_t std::hash<elna::boot::constant_aggregate<std::vector>>::operator()( + const elna::boot::constant_aggregate<std::vector>& key) const noexcept +{ + const elna::boot::constant_value_hash hasher{}; + auto hash = std::accumulate(key->begin(), key->end(), elna::boot::hash_accumulator{}, + [&hasher](const auto& accumulator, const auto& element) { + return accumulator + hasher(element); + }); + + return hash.seed(); +} + +std::size_t std::hash<elna::boot::constant_aggregate<elna::boot::ordered_map>>::operator()( + const elna::boot::constant_aggregate<elna::boot::ordered_map>& key) const noexcept +{ + const elna::boot::constant_value_hash hasher{}; + auto hash = std::accumulate(key->begin(), key->end(), elna::boot::hash_accumulator{}, + [&hasher](const auto& accumulator, const auto& element) { + return accumulator + std::hash<std::string>{}(element.first) + hasher(element.second); + }); + + return hash.seed(); +} |
