19#ifndef LIBSEMIGROUPS_DOT_HPP_
20#define LIBSEMIGROUPS_DOT_HPP_
30#include "exception.hpp"
31#include "libsemigroups/bipart.hpp"
34#include "detail/fmt.hpp"
35#include "detail/report.hpp"
39#ifndef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
42 inline std::string
const& dot_to_string(std::string
const& x) {
46 inline std::string& dot_to_string(std::string& x) {
50 inline std::string&& dot_to_string(std::string&& x) {
54 inline std::string dot_to_string(
char const* x) {
55 return std::string(x);
58 inline std::string dot_to_string(std::string_view x) {
59 return std::string(x);
62 template <
typename Thing>
63 std::string dot_to_string(Thing&& thing) {
142 template <
typename Thing>
144 :
attrs(),
name(detail::dot_to_string(
std::forward<Thing>(thing))) {}
184 template <
typename Thing1,
typename Thing2>
189 add_or_replace_attr(
attrs, key_str, val_str);
213 template <
typename Thing1,
typename Thing2>
216 head(detail::dot_to_string(
std::forward<Thing1>(h))),
217 tail(detail::dot_to_string(
std::forward<Thing2>(t))) {}
240 template <
typename Thing1,
typename Thing2>
245 add_or_replace_attr(
attrs, key_str, val_str);
291 = {
"#00ff00",
"#ff00ff",
"#007fff",
"#ff7f00",
"#7fbf7f",
"#4604ac",
292 "#de0328",
"#19801d",
"#d881f5",
"#00ffff",
"#ffff00",
"#00ff7f",
293 "#ad5867",
"#85f610",
"#84e9f5",
"#f5c778",
"#207090",
"#764ef3",
294 "#7b4c00",
"#0000ff",
"#b80c9a",
"#601045",
"#29b7c0",
"#839f12"};
374 return rx::iterator_range(_nodes.begin(), _nodes.end())
375 | rx::transform([](
auto& pair) ->
Node& {
return pair.second; });
388 return rx::iterator_range(_nodes.begin(), _nodes.end())
390 [](
auto& pair) ->
Node const& {
return pair.second; });
507 template <
typename Thing1,
typename Thing2>
512 add_or_replace_attr(_attrs, key_str, val_str);
535 template <
typename Thing>
537 add_or_replace_attr(_attrs, key,
"");
550 return _nodes.count(
name);
564 template <
typename Thing,
565 typename std::enable_if_t<
566 !std::is_same_v<std::decay_t<Thing>,
std::string>>>
567 [[nodiscard]]
bool is_node(Thing&& thing)
const {
586 template <
typename Thing>
589 auto [it, inserted] = _nodes.emplace(name_str,
Node(name_str));
611 template <
typename Thing>
614 auto it = _nodes.find(name_str);
615 if (it == _nodes.cend()) {
638 template <
typename Thing1,
typename Thing2>
642 throw_if_not_node(head_str);
643 throw_if_not_node(tail_str);
644 _edges.emplace_back(head_str, tail_str);
645 return _edges.back();
668 template <
typename Thing1,
typename Thing2>
672 throw_if_not_node(head_str);
673 throw_if_not_node(tail_str);
675 return e.head == head_str && e.tail == tail_str;
677 if (it == _edges.cend()) {
679 "there is no edges from {} to {}!", head_str, tail_str);
699 std::string_view edge_string() const noexcept;
701 static
void add_or_replace_attr(
std::map<
std::
string,
std::
string>&
attrs,
702 std::
string const& key,
703 std::
string const& val);
754 std::
string const& sep =
"::");
bool is_node(Thing &&thing) const
Check if there is a node with name obtained from an object.
Definition dot.hpp:567
auto nodes() noexcept
Returns a range object of references to the current nodes.
Definition dot.hpp:373
Dot & add_subgraph(Dot const &subgraph)
Add a Dot object as a subgraph.
auto nodes() const noexcept
Returns a range object of const references to the current nodes.
Definition dot.hpp:387
std::vector< Dot > const & subgraphs() const noexcept
Returns a const reference to the vector of subgraphs.
Definition dot.hpp:443
std::string to_human_readable_repr(Dot const &d)
Return a human readable representation of a Dot object.
Dot & add_attr(Thing &&key)
Add an attribute to the graph.
Definition dot.hpp:536
Node & node(Thing &&thing)
Return a node from the represented graph.
Definition dot.hpp:612
std::vector< Edge > & edges() noexcept
Returns a reference to the vector of edges.
Definition dot.hpp:402
Dot & add_subgraph(Dot &&subgraph)
Add a Dot object as a subgraph.
Dot & operator=(Dot &&)
Default move assignment operator.
static constexpr std::array< std::string_view, 24 > colors
An array of default HTML/hex colours.
Definition dot.hpp:291
Dot & add_attr(Thing1 &&key, Thing2 &&val)
Add an attribute to the graph.
Definition dot.hpp:508
Dot(Dot &&)
Default move constructor.
Dot(Dot const &)
Default copy constructor.
std::map< std::string, std::string > const & attrs() const noexcept
Returns a const reference to the map of attributes.
Definition dot.hpp:457
Node & add_node(Thing &&thing)
Add a node to the represented graph.
Definition dot.hpp:587
Dot()
Default constructor.
Dot & kind(Kind val) noexcept
Set the kind of the represented graph.
Definition dot.hpp:330
Edge & add_edge(Thing1 &&head, Thing2 &&tail)
Add an edge with given head and tail.
Definition dot.hpp:639
Dot & name(std::string const &val)
Set the name of the represented graph.
Definition dot.hpp:350
Dot & operator=(Dot const &)
Default copy assignment operator.
Kind
The kind of object represented.
Definition dot.hpp:277
@ subgraph
Definition dot.hpp:284
@ digraph
Value indicating that the represented graph has directed edges ->.
Definition dot.hpp:279
@ graph
Value indicating that the represented graph has undirected edges --.
Definition dot.hpp:281
std::string to_string() const
Convert a Dot object to a string.
bool is_node(std::string const &name) const
Check if there is a node with a given name.
Definition dot.hpp:549
std::vector< Dot > & subgraphs() noexcept
Returns a reference to the vector of subgraphs.
Definition dot.hpp:429
std::string const & name() const noexcept
Get the current name of the represented graph.
Definition dot.hpp:360
Edge & edge(Thing1 &&head, Thing2 &&tail)
Returns the first edge with given head and tail.
Definition dot.hpp:669
std::vector< Edge > const & edges() const noexcept
Returns a const reference to the vector of edges.
Definition dot.hpp:415
Kind kind() const noexcept
Get the kind of the represented graph.
Definition dot.hpp:341
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:99
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
This nested struct represents an edge in the represented graph.
Definition dot.hpp:199
std::string head
Name of the head of the edge.
Definition dot.hpp:270
Edge(Thing1 &&h, Thing2 &&t)
Construct from head and tail.
Definition dot.hpp:214
Edge & add_attr(Thing1 &&key, Thing2 &&val)
Add an attribute to an edge.
Definition dot.hpp:241
std::map< std::string, std::string > attrs
Map of attributes.
Definition dot.hpp:267
Edge & operator=(Edge &&)=default
Default move assignment.
std::string tail
Name of the tail of the edge.
Definition dot.hpp:273
std::string to_human_readable_repr(Dot::Edge const &e)
Return a human readable representation of a Dot::Edge object.
Edge & operator=(Edge const &)=default
Default copy assignment.
Edge()=default
Default constructor.
Edge(Edge &&)=default
Default move constructor.
Edge(Edge const &)=default
Default copy constructor.
This nested struct represents a node in the represented graph.
Definition dot.hpp:123
Node & operator=(Node &&)=default
Default move assignment.
Node(Node &&)=default
Default move constructor.
Node(Thing &&thing)
Construct from anything.
Definition dot.hpp:143
Node()=default
Default constructor.
std::map< std::string, std::string > attrs
Map containing the attributes of the Node.
Definition dot.hpp:125
std::string name
The name of the node.
Definition dot.hpp:128
Node(Node const &)=default
Default copy constructor.
Node & operator=(Node const &)=default
Default copy assignment.
std::string to_human_readable_repr(Dot::Node const &n)
Return a human readable representation of a Dot::Node object.
Node & add_attr(Thing1 &&key, Thing2 &&val)
Add an attribute to a node.
Definition dot.hpp:185