utils functions, expect, ensure, error handling refactoring (string -> string_view), std::source_location

This commit is contained in:
ProgramSnail 2024-03-11 00:33:53 +03:00
parent 5afbaf06ae
commit d6a3ce1946
7 changed files with 149 additions and 29 deletions

View file

@ -1,10 +1,13 @@
#pragma once
#include "utils.hpp"
#include <optional>
#include <ranges>
#include <string>
#include <utility>
#include <variant>
#include <vector>
namespace nodes {
@ -222,6 +225,8 @@ private:
class Identifier : public Node {
public:
static constexpr char NAME_DELIMITER = '.';
enum IdentifierType {
SIMPLE_NAME,
SIMPLE_TYPE,
@ -251,18 +256,51 @@ public:
//
void append_before(const std::string &name) { value_ = name + "." + value_; }
void append_before(const std::string &name) {
value_ = name + NAME_DELIMITER + value_;
}
void append_before(
const Identifier &identifier,
std::source_location location = std::source_location::current()) {
error_handling::expect(identifier.type_ == type_,
"different Identifier types on append_before",
location);
value_ = *identifier.get() + NAME_DELIMITER + value_;
}
void append_after(const std::string &name) {
value_ += "." + name;
value_ += NAME_DELIMITER + name;
}
void append_after(
const Identifier &identifier,
std::source_location location = std::source_location::current()) {
error_handling::expect(identifier.type_ == type_,
"different Identifier types on append_after",
location);
value_ += NAME_DELIMITER + *identifier.get();
}
std::vector<Identifier> git_fragments() const {
std::vector<Identifier> fragments;
for (auto &&fragment_name :
std::ranges::views::split(value_, NAME_DELIMITER)) {
fragments.emplace_back(
*this, type_,
std::string(fragment_name.begin(), fragment_name.end()));
}
return fragments;
}
std::pair<Identifier, Identifier> split_first() {
const auto pos = value_.find('.');
const auto pos = value_.find(NAME_DELIMITER);
if (pos == std::string::npos) {
return {Identifier(*this, type_, ""), *this};
}
return {Identifier(*this, type_, value_.substr(0, pos)), Identifier(*this, type_, value_.substr(pos + 1))}; // '.' is leaved out
return {
Identifier(*this, type_, value_.substr(0, pos)),
Identifier(*this, type_, value_.substr(pos + 1))}; // '.' is leaved out
}
//

View file

@ -4,6 +4,7 @@
#include "builtin_types.hpp"
#include "utils.hpp"
#include <algorithm>
#include <iterator>
#include <memory>
#include <optional>
@ -28,7 +29,7 @@ public:
bool operator==(const TypeProxy &other) const;
bool operator!=(const TypeProxy&) const = default;
bool operator!=(const TypeProxy &) const = default;
private:
TypeProxy(TypeStorage &type_storage, size_t id)
@ -75,13 +76,40 @@ public:
size_t parameters_size() const { return parameters_.size(); }
Type *get_parameter(size_t id) { return parameters_.at(id).get(); }
TypeProxy get_parameter_proxy(size_t id) const { return parameters_.at(id); }
Type *get_parameter(size_t id) { return get_parameter_proxy(id).get(); }
const Type *get_parameter(size_t id) const {
return parameters_.at(id).get();
return get_parameter_proxy(id).get();
}
TypeProxy get_parameter_proxy(size_t id) const { return parameters_.at(id); }
// TODO: cache with map ??
std::optional<TypeProxy>
get_parameter_proxy_by_name(const std::string &name) const {
const auto it = std::find_if(
parameters_.begin(), parameters_.end(), [&name](const auto &parameter) {
return parameter.get()->has_annotation() &&
*parameter.get()->get_annotation().value() == name;
});
if (it != parameters_.end()) {
return *it;
}
return std::nullopt;
}
std::optional<const Type *>
get_parameter_by_name(const std::string &name) const {
const auto proxy = get_parameter_proxy_by_name(name);
return proxy.has_value() ? proxy.value().get()
: std::optional<const Type *>{};
}
std::optional<Type *> get_parameter_by_name(const std::string &name) {
auto proxy = get_parameter_proxy_by_name(name);
return proxy.has_value() ? proxy.value().get() : std::optional<Type *>{};
}
//
@ -93,6 +121,8 @@ public:
//
bool has_annotation() const { return annotation_.has_value(); }
std::optional<std::string *> get_annotation() {
if (annotation_.has_value()) {
return &annotation_.value();