/** * src/common/types.h * * Copyright (c) 2021-2023 Bartek Kryza * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include #include #include "model/namespace.h" namespace clanguml::common { using id_t = int64_t; enum class generator_type_t { plantuml, json }; std::string to_string(const std::string &s); template class optional_ref { public: using optional_type = T; optional_ref() = default; optional_ref(T *value) : value_{value} { } optional_ref(const T *value) : value_{value} { } optional_ref(T &value) : value_{&value} { } optional_ref(const T &value) : value_{&value} { } optional_ref(optional_ref &right) : value_{right.get()} { } template || std::is_same_v>> optional_ref(const V &t) : value_{t.get()} { } template || std::is_same_v>> optional_ref(V &&t) : value_{t.get()} { t.reset(); } template >> optional_ref(const std::reference_wrapper &t) : value_{&t.get()} { } optional_ref &operator=(const optional_ref &right) { if (this == &right) return *this; value_ = right.value_; return *this; } optional_ref &operator=(optional_ref &&right) noexcept { if (this == &right) return *this; value_ = right.value_; right.reset(); return *this; } bool has_value() const noexcept { return value_ != nullptr; } operator bool() const noexcept { return has_value(); } const T &value() const { assert(value_ != nullptr); return *value_; } T &value() { assert(value_ != nullptr); return *value_; } T &operator*() { assert(value_ != nullptr); return *value_; } const T &operator*() const { assert(value_ != nullptr); return *value_; } void reset() { value_ = nullptr; } T *get() const { return value_; } private: T *value_{nullptr}; }; template using opt_ref = optional_ref; template using reference_vector = std::vector>; template using reference_set = std::unordered_set>; /** * @brief Wrapper around std::regex, which contains original pattern */ struct regex { regex(std::regex r, std::string p) : regexp{std::move(r)} , pattern{std::move(p)} { } [[nodiscard]] bool operator==(const std::string &v) const { return std::regex_match(v, regexp); } std::regex regexp; std::string pattern; }; template struct or_regex { or_regex() = default; or_regex(T v) : value_{std::move(v)} { } or_regex(std::regex r, std::string p) : value_{regex{std::move(r), std::move(p)}} { } or_regex &operator=(const T &v) { value_ = v; return *this; } or_regex &operator=(const regex &v) { value_ = v; return *this; } [[nodiscard]] bool operator==(const T &v) const { if (std::holds_alternative(value_)) return std::regex_match(v, std::get(value_).regexp); return std::get(value_) == v; } template std::optional get() const { if (!std::holds_alternative(value_)) return std::nullopt; return std::get(value_); } std::string to_string() const { if (std::holds_alternative(value_)) return std::get(value_).pattern; return clanguml::common::to_string(std::get(value_)); } const std::variant &value() const { return value_; } private: std::variant value_; }; using string_or_regex = or_regex; std::string to_string(const string_or_regex &sr); using namespace_or_regex = common::or_regex; struct path_or_regex : public or_regex { }; } // namespace clanguml::common