feat(cpp-object-oriented-modular-refactoring): step 11 - source-target-resolver

This commit is contained in:
KOKO\Mimi
2026-08-16 08:34:09 +09:00
parent 5430fffd62
commit a6324a9004
12 changed files with 714 additions and 273 deletions
+28
View File
@@ -0,0 +1,28 @@
#ifndef FESA_CORE_ASCII_H_
#define FESA_CORE_ASCII_H_
#include <cstdint>
#include <string_view>
#include "fesa/core/status.h"
namespace fesa {
/// @brief Converts one ASCII uppercase byte to lowercase.
/// @return The lowercase ASCII byte, or the input byte when it is not A-Z.
char AsciiLower(char value) noexcept;
/// @brief Compares two byte strings with ASCII-only case folding.
/// @return True when the strings have equal length and equal ASCII-folded
/// bytes.
bool AsciiCaseInsensitiveEquals(std::string_view lhs,
std::string_view rhs) noexcept;
/// @brief Parses a complete positive base-10 source label.
/// @return The positive label or an input failure for malformed, nonpositive,
/// or out-of-range text.
Result<std::int64_t> ParsePositiveSourceLabel(std::string_view text);
} // namespace fesa
#endif // FESA_CORE_ASCII_H_
@@ -0,0 +1,81 @@
#ifndef FESA_MODEL_SOURCE_TARGET_RESOLVER_H_
#define FESA_MODEL_SOURCE_TARGET_RESOLVER_H_
#include <cstddef>
#include <string>
#include <vector>
#include "fesa/core/source_identity.h"
#include "fesa/core/status.h"
#include "fesa/model/model_types.h"
namespace fesa {
class Domain;
/// @brief Selects the independent source node or element namespace.
enum class SourceEntityKind { kNode, kElement };
/// @brief Maps one direct label or named-target membership to stable identity.
/// @note An empty target_name denotes a direct source-label entry.
struct SourceTargetIndexEntry {
SourceEntityKind entity_kind;
std::string instance_name;
std::string target_name;
SourceEntityId source_id;
EntityIndex entity_index;
std::size_t declaration_order;
};
/// @brief Owns immutable compact source-target lookup entries.
class SourceTargetIndex {
public:
/// @brief Takes ownership of compact entries from a validated model
/// candidate.
explicit SourceTargetIndex(std::vector<SourceTargetIndexEntry> entries);
/// @brief Builds compact entries from an immutable semantic Domain.
/// @return An owning index that preserves Domain declaration order.
static SourceTargetIndex FromDomain(const Domain& domain);
/// @brief Returns owned entries without exposing mutable index state.
const std::vector<SourceTargetIndexEntry>& Entries() const noexcept;
private:
std::vector<SourceTargetIndexEntry> entries_;
};
/// @brief Describes one source target lookup.
struct SourceTargetQuery {
SourceEntityKind entity_kind;
std::string instance_name;
std::string target_name_or_label;
};
/// @brief Preserves both external source identity and stable internal index.
struct ResolvedSourceTarget {
SourceEntityId source_id;
EntityIndex entity_index;
};
/// @brief Resolves source labels and named targets without owning model state.
/// @note The referenced SourceTargetIndex must outlive this resolver.
class SourceTargetResolver {
public:
/// @brief Creates a non-owning resolver over an immutable index.
/// @param index Index whose lifetime must exceed the resolver lifetime.
explicit SourceTargetResolver(const SourceTargetIndex& index) noexcept;
/// @brief Resolves one query in stable declaration order.
/// @return Stable source targets, or a deterministic input diagnostic for an
/// invalid, missing, duplicate, or ambiguous target.
Result<std::vector<ResolvedSourceTarget>> Resolve(
const SourceTargetQuery& query) const;
private:
const SourceTargetIndex* index_;
};
} // namespace fesa
#endif // FESA_MODEL_SOURCE_TARGET_RESOLVER_H_