/* Miscellaneous types used across stage boundaries. Copyright (C) 2025 Free Software Foundation, Inc. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "elna/boot/result.h" #include namespace elna::boot { location::location(const std::size_t line, const std::size_t column) : m_line(line), m_column(column) { } std::size_t location::line() const { return this->m_line; } std::size_t location::column() const { return this->m_column; } bool location::available() const { return this->m_line != 0 || this->m_column != 0; } source_position::source_position(location start, location end) : m_start(start), m_end(end) { } const location& source_position::start() const { return this->m_start; } const location& source_position::end() const { return this->m_end; } bool source_position::is_span() const { return this->m_start != this->m_end; } error::error(const source_position position) : position(position) { } std::deque>& error_container::errors() { return m_errors; } bool error_container::has_errors() const { return !m_errors.empty(); } identifier::identifier(const std::string& name, const source_position& position) : m_name(name), m_position(position) { } const std::string& identifier::name() const { return this->m_name; } const source_position& identifier::position() const { return this->m_position; } std::strong_ordering identifier::operator<=>(const identifier& that) const { auto comparison = this->m_name.compare(that.name()); if (comparison < 0) { return std::strong_ordering::less; } else if (comparison > 0) { return std::strong_ordering::greater; } else { return std::strong_ordering::equal; } } bool identifier::operator==(std::string_view that) const { return this->m_name == that; } bool identifier::operator!=(std::string_view that) const { return !(*this == that); } identifier_definition::identifier_definition(const std::string& name, const source_position& position, const bool exported) : m_identifier(name, position), m_exported(exported) { } const std::string& identifier_definition::name() const { return this->m_identifier.name(); } const identifier& identifier_definition::id() const { return this->m_identifier; } bool identifier_definition::exported() const { 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; return std::hash{}(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; using U = std::decay_t; if constexpr (std::is_same_v) { 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::operator()( const elna::boot::identifier& key) const noexcept { return std::hash{}(key.name()); } std::size_t std::hash::operator()( const elna::boot::global_address& key) const noexcept { return std::hash{}(key.name); } std::size_t std::hash>::operator()( const elna::boot::constant_aggregate& 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>::operator()( const elna::boot::constant_aggregate& 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{}(element.first) + hasher(element.second); }); return hash.seed(); }