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
|
const diagram &d, const common::model::element &e) const
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<bool> filter_visitor::match(
|
tvl::value_t filter_visitor::match(
|
||||||
const diagram &d, const common::model::relationship_t &r) const
|
const diagram &d, const common::model::relationship_t &r) const
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<bool> filter_visitor::match(
|
tvl::value_t filter_visitor::match(
|
||||||
const diagram &d, const common::model::access_t &a) const
|
const diagram &d, const common::model::access_t &a) const
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<bool> filter_visitor::match(
|
tvl::value_t filter_visitor::match(
|
||||||
const diagram &d, const common::model::namespace_ &ns) const
|
const diagram &d, const common::model::namespace_ &ns) const
|
||||||
{
|
{
|
||||||
return {};
|
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
|
const diagram &d, const common::model::element &e) const
|
||||||
{
|
{
|
||||||
std::optional<bool> res{};
|
return tvl::any_of(filters_.begin(), filters_.end(),
|
||||||
|
[&d, &e](const auto &f) { return f->match(d, e); });
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace_filter::namespace_filter(
|
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
|
const diagram &d, const namespace_ &ns) const
|
||||||
{
|
{
|
||||||
if (namespaces_.empty() || ns.is_empty())
|
if (ns.is_empty())
|
||||||
return {};
|
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; });
|
[&ns](const auto &nsit) { return ns.starts_with(nsit) || ns == nsit; });
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<bool> namespace_filter::match(
|
tvl::value_t namespace_filter::match(const diagram &d, const element &e) const
|
||||||
const diagram &d, const element &e) const
|
|
||||||
{
|
{
|
||||||
if (namespaces_.empty())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
if (dynamic_cast<const package *>(&e) != nullptr) {
|
if (dynamic_cast<const package *>(&e) != nullptr) {
|
||||||
return std::any_of(
|
return tvl::any_of(
|
||||||
namespaces_.begin(), namespaces_.end(), [&e](const auto &nsit) {
|
namespaces_.begin(), namespaces_.end(), [&e](const auto &nsit) {
|
||||||
return (e.get_namespace() | e.name()).starts_with(nsit) ||
|
return (e.get_namespace() | e.name()).starts_with(nsit) ||
|
||||||
nsit.starts_with(e.get_namespace() | e.name()) ||
|
nsit.starts_with(e.get_namespace() | e.name()) ||
|
||||||
@@ -121,7 +103,7 @@ std::optional<bool> namespace_filter::match(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return std::any_of(
|
return tvl::any_of(
|
||||||
namespaces_.begin(), namespaces_.end(), [&e](const auto &nsit) {
|
namespaces_.begin(), namespaces_.end(), [&e](const auto &nsit) {
|
||||||
return e.get_namespace().starts_with(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(
|
tvl::value_t element_filter::match(const diagram &d, const element &e) const
|
||||||
const diagram &d, const element &e) const
|
|
||||||
{
|
{
|
||||||
if (elements_.empty())
|
return tvl::any_of(elements_.begin(), elements_.end(),
|
||||||
return {};
|
|
||||||
|
|
||||||
return std::any_of(elements_.begin(), elements_.end(),
|
|
||||||
[&e](const auto &el) { return e.full_name(false) == el; });
|
[&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(
|
tvl::value_t subclass_filter::match(const diagram &d, const element &e) const
|
||||||
const diagram &d, const element &e) const
|
|
||||||
{
|
{
|
||||||
if (d.type() != diagram_t::kClass)
|
if (d.type() != diagram_t::kClass)
|
||||||
return {};
|
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
|
const diagram &d, const relationship_t &r) const
|
||||||
{
|
{
|
||||||
if (relationships_.empty())
|
return tvl::any_of(relationships_.begin(), relationships_.end(),
|
||||||
return {};
|
|
||||||
|
|
||||||
return std::any_of(relationships_.begin(), relationships_.end(),
|
|
||||||
[&r](const auto &rel) { return r == rel; });
|
[&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(
|
tvl::value_t access_filter::match(const diagram &d, const access_t &a) const
|
||||||
const diagram &d, const access_t &a) const
|
|
||||||
{
|
{
|
||||||
if (access_.empty())
|
return tvl::any_of(access_.begin(), access_.end(),
|
||||||
return {};
|
|
||||||
|
|
||||||
return std::any_of(access_.begin(), access_.end(),
|
|
||||||
[&a](const auto &access) { return a == access; });
|
[&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(
|
tvl::value_t context_filter::match(const diagram &d, const element &e) const
|
||||||
const diagram &d, const element &e) const
|
|
||||||
{
|
{
|
||||||
if (d.type() != diagram_t::kClass)
|
if (d.type() != diagram_t::kClass)
|
||||||
return {};
|
return {};
|
||||||
@@ -239,10 +208,7 @@ std::optional<bool> context_filter::match(
|
|||||||
if (!d.complete())
|
if (!d.complete())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (context_.empty())
|
return tvl::any_of(context_.begin(), context_.end(),
|
||||||
return {};
|
|
||||||
|
|
||||||
return std::any_of(context_.begin(), context_.end(),
|
|
||||||
[&e, &d](const auto &context_root_name) {
|
[&e, &d](const auto &context_root_name) {
|
||||||
const auto &context_root =
|
const auto &context_root =
|
||||||
static_cast<const class_diagram::model::diagram &>(d).get_class(
|
static_cast<const class_diagram::model::diagram &>(d).get_class(
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
#include "cx/util.h"
|
#include "cx/util.h"
|
||||||
#include "diagram.h"
|
#include "diagram.h"
|
||||||
|
#include "tvl.h"
|
||||||
|
|
||||||
namespace clanguml::common::model {
|
namespace clanguml::common::model {
|
||||||
|
|
||||||
@@ -34,16 +35,16 @@ class filter_visitor {
|
|||||||
public:
|
public:
|
||||||
filter_visitor(filter_t type);
|
filter_visitor(filter_t type);
|
||||||
|
|
||||||
virtual std::optional<bool> match(
|
virtual tvl::value_t match(
|
||||||
const diagram &d, const common::model::element &e) const;
|
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;
|
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;
|
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;
|
const diagram &d, const common::model::namespace_ &ns) const;
|
||||||
|
|
||||||
bool is_inclusive() const;
|
bool is_inclusive() const;
|
||||||
@@ -59,7 +60,7 @@ struct anyof_filter : public filter_visitor {
|
|||||||
anyof_filter(
|
anyof_filter(
|
||||||
filter_t type, std::vector<std::unique_ptr<filter_visitor>> filters);
|
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;
|
const diagram &d, const common::model::element &e) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -69,11 +70,9 @@ private:
|
|||||||
struct namespace_filter : public filter_visitor {
|
struct namespace_filter : public filter_visitor {
|
||||||
namespace_filter(filter_t type, std::vector<namespace_> namespaces);
|
namespace_filter(filter_t type, std::vector<namespace_> namespaces);
|
||||||
|
|
||||||
std::optional<bool> match(
|
tvl::value_t match(const diagram &d, const namespace_ &ns) const override;
|
||||||
const diagram &d, const namespace_ &ns) const override;
|
|
||||||
|
|
||||||
std::optional<bool> match(
|
tvl::value_t match(const diagram &d, const element &e) const override;
|
||||||
const diagram &d, const element &e) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<namespace_> namespaces_;
|
std::vector<namespace_> namespaces_;
|
||||||
@@ -82,8 +81,7 @@ private:
|
|||||||
struct element_filter : public filter_visitor {
|
struct element_filter : public filter_visitor {
|
||||||
element_filter(filter_t type, std::vector<std::string> elements);
|
element_filter(filter_t type, std::vector<std::string> elements);
|
||||||
|
|
||||||
std::optional<bool> match(
|
tvl::value_t match(const diagram &d, const element &e) const override;
|
||||||
const diagram &d, const element &e) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> elements_;
|
std::vector<std::string> elements_;
|
||||||
@@ -92,8 +90,7 @@ private:
|
|||||||
struct subclass_filter : public filter_visitor {
|
struct subclass_filter : public filter_visitor {
|
||||||
subclass_filter(filter_t type, std::vector<std::string> roots);
|
subclass_filter(filter_t type, std::vector<std::string> roots);
|
||||||
|
|
||||||
std::optional<bool> match(
|
tvl::value_t match(const diagram &d, const element &e) const override;
|
||||||
const diagram &d, const element &e) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> roots_;
|
std::vector<std::string> roots_;
|
||||||
@@ -103,7 +100,7 @@ struct relationship_filter : public filter_visitor {
|
|||||||
relationship_filter(
|
relationship_filter(
|
||||||
filter_t type, std::vector<relationship_t> relationships);
|
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;
|
const diagram &d, const relationship_t &r) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -113,8 +110,7 @@ private:
|
|||||||
struct access_filter : public filter_visitor {
|
struct access_filter : public filter_visitor {
|
||||||
access_filter(filter_t type, std::vector<access_t> access);
|
access_filter(filter_t type, std::vector<access_t> access);
|
||||||
|
|
||||||
std::optional<bool> match(
|
tvl::value_t match(const diagram &d, const access_t &a) const override;
|
||||||
const diagram &d, const access_t &a) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<access_t> access_;
|
std::vector<access_t> access_;
|
||||||
@@ -123,8 +119,7 @@ private:
|
|||||||
struct context_filter : public filter_visitor {
|
struct context_filter : public filter_visitor {
|
||||||
context_filter(filter_t type, std::vector<std::string> context);
|
context_filter(filter_t type, std::vector<std::string> context);
|
||||||
|
|
||||||
std::optional<bool> match(
|
tvl::value_t match(const diagram &d, const element &r) const override;
|
||||||
const diagram &d, const element &r) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> context_;
|
std::vector<std::string> context_;
|
||||||
@@ -142,25 +137,16 @@ public:
|
|||||||
|
|
||||||
template <typename T> bool should_include(const T &e) const
|
template <typename T> bool should_include(const T &e) const
|
||||||
{
|
{
|
||||||
bool exc = std::any_of(
|
auto exc = tvl::any_of(exclusive_.begin(), exclusive_.end(),
|
||||||
exclusive_.begin(), exclusive_.end(), [this, &e](const auto &ex) {
|
[this, &e](const auto &ex) { return ex->match(diagram_, e); });
|
||||||
auto m = ex->match(diagram_, e);
|
|
||||||
// Return true if a filter is defined for specific element
|
if (tvl::is_true(exc))
|
||||||
// and it's a match
|
|
||||||
return m.has_value() && m.value();
|
|
||||||
});
|
|
||||||
if (exc)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool inc = std::all_of(
|
auto inc = tvl::all_of(inclusive_.begin(), inclusive_.end(),
|
||||||
inclusive_.begin(), inclusive_.end(), [this, &e](const auto &in) {
|
[this, &e](const auto &in) { return in->match(diagram_, e); });
|
||||||
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();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (inc)
|
if (tvl::is_undefined(inc) || tvl::is_true(inc))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
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