Refactored filter diagrams to three value logic
This commit is contained in:
@@ -25,25 +25,25 @@ filter_visitor::filter_visitor(filter_t type)
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<bool> filter_visitor::match(
|
||||
tvl::value_t filter_visitor::match(
|
||||
const diagram &d, const common::model::element &e) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<bool> filter_visitor::match(
|
||||
tvl::value_t filter_visitor::match(
|
||||
const diagram &d, const common::model::relationship_t &r) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<bool> filter_visitor::match(
|
||||
tvl::value_t filter_visitor::match(
|
||||
const diagram &d, const common::model::access_t &a) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<bool> filter_visitor::match(
|
||||
tvl::value_t filter_visitor::match(
|
||||
const diagram &d, const common::model::namespace_ &ns) const
|
||||
{
|
||||
return {};
|
||||
@@ -68,25 +68,11 @@ anyof_filter::anyof_filter(
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<bool> anyof_filter::match(
|
||||
tvl::value_t anyof_filter::match(
|
||||
const diagram &d, const common::model::element &e) const
|
||||
{
|
||||
std::optional<bool> res{};
|
||||
|
||||
for (const auto &filter : filters_) {
|
||||
auto m = filter->match(d, e);
|
||||
if (m.has_value()) {
|
||||
if (m.value() == true) {
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return tvl::any_of(filters_.begin(), filters_.end(),
|
||||
[&d, &e](const auto &f) { return f->match(d, e); });
|
||||
}
|
||||
|
||||
namespace_filter::namespace_filter(
|
||||
@@ -96,24 +82,20 @@ namespace_filter::namespace_filter(
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<bool> namespace_filter::match(
|
||||
tvl::value_t namespace_filter::match(
|
||||
const diagram &d, const namespace_ &ns) const
|
||||
{
|
||||
if (namespaces_.empty() || ns.is_empty())
|
||||
if (ns.is_empty())
|
||||
return {};
|
||||
|
||||
return std::any_of(namespaces_.begin(), namespaces_.end(),
|
||||
return tvl::any_of(namespaces_.begin(), namespaces_.end(),
|
||||
[&ns](const auto &nsit) { return ns.starts_with(nsit) || ns == nsit; });
|
||||
}
|
||||
|
||||
std::optional<bool> namespace_filter::match(
|
||||
const diagram &d, const element &e) const
|
||||
tvl::value_t namespace_filter::match(const diagram &d, const element &e) const
|
||||
{
|
||||
if (namespaces_.empty())
|
||||
return {};
|
||||
|
||||
if (dynamic_cast<const package *>(&e) != nullptr) {
|
||||
return std::any_of(
|
||||
return tvl::any_of(
|
||||
namespaces_.begin(), namespaces_.end(), [&e](const auto &nsit) {
|
||||
return (e.get_namespace() | e.name()).starts_with(nsit) ||
|
||||
nsit.starts_with(e.get_namespace() | e.name()) ||
|
||||
@@ -121,7 +103,7 @@ std::optional<bool> namespace_filter::match(
|
||||
});
|
||||
}
|
||||
else {
|
||||
return std::any_of(
|
||||
return tvl::any_of(
|
||||
namespaces_.begin(), namespaces_.end(), [&e](const auto &nsit) {
|
||||
return e.get_namespace().starts_with(nsit);
|
||||
});
|
||||
@@ -134,13 +116,9 @@ element_filter::element_filter(filter_t type, std::vector<std::string> elements)
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<bool> element_filter::match(
|
||||
const diagram &d, const element &e) const
|
||||
tvl::value_t element_filter::match(const diagram &d, const element &e) const
|
||||
{
|
||||
if (elements_.empty())
|
||||
return {};
|
||||
|
||||
return std::any_of(elements_.begin(), elements_.end(),
|
||||
return tvl::any_of(elements_.begin(), elements_.end(),
|
||||
[&e](const auto &el) { return e.full_name(false) == el; });
|
||||
}
|
||||
|
||||
@@ -150,8 +128,7 @@ subclass_filter::subclass_filter(filter_t type, std::vector<std::string> roots)
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<bool> subclass_filter::match(
|
||||
const diagram &d, const element &e) const
|
||||
tvl::value_t subclass_filter::match(const diagram &d, const element &e) const
|
||||
{
|
||||
if (d.type() != diagram_t::kClass)
|
||||
return {};
|
||||
@@ -198,13 +175,10 @@ relationship_filter::relationship_filter(
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<bool> relationship_filter::match(
|
||||
tvl::value_t relationship_filter::match(
|
||||
const diagram &d, const relationship_t &r) const
|
||||
{
|
||||
if (relationships_.empty())
|
||||
return {};
|
||||
|
||||
return std::any_of(relationships_.begin(), relationships_.end(),
|
||||
return tvl::any_of(relationships_.begin(), relationships_.end(),
|
||||
[&r](const auto &rel) { return r == rel; });
|
||||
}
|
||||
|
||||
@@ -214,13 +188,9 @@ access_filter::access_filter(filter_t type, std::vector<access_t> access)
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<bool> access_filter::match(
|
||||
const diagram &d, const access_t &a) const
|
||||
tvl::value_t access_filter::match(const diagram &d, const access_t &a) const
|
||||
{
|
||||
if (access_.empty())
|
||||
return {};
|
||||
|
||||
return std::any_of(access_.begin(), access_.end(),
|
||||
return tvl::any_of(access_.begin(), access_.end(),
|
||||
[&a](const auto &access) { return a == access; });
|
||||
}
|
||||
|
||||
@@ -230,8 +200,7 @@ context_filter::context_filter(filter_t type, std::vector<std::string> context)
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<bool> context_filter::match(
|
||||
const diagram &d, const element &e) const
|
||||
tvl::value_t context_filter::match(const diagram &d, const element &e) const
|
||||
{
|
||||
if (d.type() != diagram_t::kClass)
|
||||
return {};
|
||||
@@ -239,10 +208,7 @@ std::optional<bool> context_filter::match(
|
||||
if (!d.complete())
|
||||
return {};
|
||||
|
||||
if (context_.empty())
|
||||
return {};
|
||||
|
||||
return std::any_of(context_.begin(), context_.end(),
|
||||
return tvl::any_of(context_.begin(), context_.end(),
|
||||
[&e, &d](const auto &context_root_name) {
|
||||
const auto &context_root =
|
||||
static_cast<const class_diagram::model::diagram &>(d).get_class(
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "config/config.h"
|
||||
#include "cx/util.h"
|
||||
#include "diagram.h"
|
||||
#include "tvl.h"
|
||||
|
||||
namespace clanguml::common::model {
|
||||
|
||||
@@ -34,16 +35,16 @@ class filter_visitor {
|
||||
public:
|
||||
filter_visitor(filter_t type);
|
||||
|
||||
virtual std::optional<bool> match(
|
||||
virtual tvl::value_t match(
|
||||
const diagram &d, const common::model::element &e) const;
|
||||
|
||||
virtual std::optional<bool> match(
|
||||
virtual tvl::value_t match(
|
||||
const diagram &d, const common::model::relationship_t &r) const;
|
||||
|
||||
virtual std::optional<bool> match(
|
||||
virtual tvl::value_t match(
|
||||
const diagram &d, const common::model::access_t &a) const;
|
||||
|
||||
virtual std::optional<bool> match(
|
||||
virtual tvl::value_t match(
|
||||
const diagram &d, const common::model::namespace_ &ns) const;
|
||||
|
||||
bool is_inclusive() const;
|
||||
@@ -59,7 +60,7 @@ struct anyof_filter : public filter_visitor {
|
||||
anyof_filter(
|
||||
filter_t type, std::vector<std::unique_ptr<filter_visitor>> filters);
|
||||
|
||||
std::optional<bool> match(
|
||||
tvl::value_t match(
|
||||
const diagram &d, const common::model::element &e) const override;
|
||||
|
||||
private:
|
||||
@@ -69,11 +70,9 @@ private:
|
||||
struct namespace_filter : public filter_visitor {
|
||||
namespace_filter(filter_t type, std::vector<namespace_> namespaces);
|
||||
|
||||
std::optional<bool> match(
|
||||
const diagram &d, const namespace_ &ns) const override;
|
||||
tvl::value_t match(const diagram &d, const namespace_ &ns) const override;
|
||||
|
||||
std::optional<bool> match(
|
||||
const diagram &d, const element &e) const override;
|
||||
tvl::value_t match(const diagram &d, const element &e) const override;
|
||||
|
||||
private:
|
||||
std::vector<namespace_> namespaces_;
|
||||
@@ -82,8 +81,7 @@ private:
|
||||
struct element_filter : public filter_visitor {
|
||||
element_filter(filter_t type, std::vector<std::string> elements);
|
||||
|
||||
std::optional<bool> match(
|
||||
const diagram &d, const element &e) const override;
|
||||
tvl::value_t match(const diagram &d, const element &e) const override;
|
||||
|
||||
private:
|
||||
std::vector<std::string> elements_;
|
||||
@@ -92,8 +90,7 @@ private:
|
||||
struct subclass_filter : public filter_visitor {
|
||||
subclass_filter(filter_t type, std::vector<std::string> roots);
|
||||
|
||||
std::optional<bool> match(
|
||||
const diagram &d, const element &e) const override;
|
||||
tvl::value_t match(const diagram &d, const element &e) const override;
|
||||
|
||||
private:
|
||||
std::vector<std::string> roots_;
|
||||
@@ -103,7 +100,7 @@ struct relationship_filter : public filter_visitor {
|
||||
relationship_filter(
|
||||
filter_t type, std::vector<relationship_t> relationships);
|
||||
|
||||
std::optional<bool> match(
|
||||
tvl::value_t match(
|
||||
const diagram &d, const relationship_t &r) const override;
|
||||
|
||||
private:
|
||||
@@ -113,8 +110,7 @@ private:
|
||||
struct access_filter : public filter_visitor {
|
||||
access_filter(filter_t type, std::vector<access_t> access);
|
||||
|
||||
std::optional<bool> match(
|
||||
const diagram &d, const access_t &a) const override;
|
||||
tvl::value_t match(const diagram &d, const access_t &a) const override;
|
||||
|
||||
private:
|
||||
std::vector<access_t> access_;
|
||||
@@ -123,8 +119,7 @@ private:
|
||||
struct context_filter : public filter_visitor {
|
||||
context_filter(filter_t type, std::vector<std::string> context);
|
||||
|
||||
std::optional<bool> match(
|
||||
const diagram &d, const element &r) const override;
|
||||
tvl::value_t match(const diagram &d, const element &r) const override;
|
||||
|
||||
private:
|
||||
std::vector<std::string> context_;
|
||||
@@ -142,25 +137,16 @@ public:
|
||||
|
||||
template <typename T> bool should_include(const T &e) const
|
||||
{
|
||||
bool exc = std::any_of(
|
||||
exclusive_.begin(), exclusive_.end(), [this, &e](const auto &ex) {
|
||||
auto m = ex->match(diagram_, e);
|
||||
// Return true if a filter is defined for specific element
|
||||
// and it's a match
|
||||
return m.has_value() && m.value();
|
||||
});
|
||||
if (exc)
|
||||
auto exc = tvl::any_of(exclusive_.begin(), exclusive_.end(),
|
||||
[this, &e](const auto &ex) { return ex->match(diagram_, e); });
|
||||
|
||||
if (tvl::is_true(exc))
|
||||
return false;
|
||||
|
||||
bool inc = std::all_of(
|
||||
inclusive_.begin(), inclusive_.end(), [this, &e](const auto &in) {
|
||||
auto m = in->match(diagram_, e);
|
||||
// Return true if a filter is undefined for specific element
|
||||
// or it's a match
|
||||
return !m.has_value() || m.value();
|
||||
});
|
||||
auto inc = tvl::all_of(inclusive_.begin(), inclusive_.end(),
|
||||
[this, &e](const auto &in) { return in->match(diagram_, e); });
|
||||
|
||||
if (inc)
|
||||
if (tvl::is_undefined(inc) || tvl::is_true(inc))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
74
src/common/model/tvl.h
Normal file
74
src/common/model/tvl.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* src/class_diagram/model/tvl.h
|
||||
*
|
||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
||||
*
|
||||
* 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 <optional>
|
||||
#include <string>
|
||||
|
||||
namespace clanguml::common::model::tvl {
|
||||
|
||||
using value_t = std::optional<bool>;
|
||||
|
||||
inline bool is_true(const value_t &v) { return v.has_value() && v.value(); }
|
||||
|
||||
inline bool is_false(const value_t &v) { return v.has_value() && !v.value(); }
|
||||
|
||||
inline bool is_undefined(const value_t &v) { return !v.has_value(); }
|
||||
|
||||
template <typename InputIterator, typename Predicate>
|
||||
inline value_t all_of(InputIterator first, InputIterator last, Predicate pred)
|
||||
{
|
||||
value_t res{};
|
||||
|
||||
for (InputIterator it = first; it != last; it++) {
|
||||
value_t m = pred(*it);
|
||||
if (m.has_value()) {
|
||||
if (m.value() == true) {
|
||||
res = true;
|
||||
}
|
||||
else {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename Predicate>
|
||||
inline value_t any_of(InputIterator first, InputIterator last, Predicate pred)
|
||||
{
|
||||
value_t res{};
|
||||
|
||||
for (InputIterator it = first; it != last; it++) {
|
||||
value_t m = pred(*it);
|
||||
if (m.has_value()) {
|
||||
if (m.value() == true) {
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user