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) {
141 template <
typename Thing>
143 :
attrs(),
name(detail::dot_to_string(
std::forward<Thing>(thing))) {}
183 template <
typename Thing1,
typename Thing2>
188 add_or_replace_attr(
attrs, key_str, val_str);
212 template <
typename Thing1,
typename Thing2>
215 head(detail::dot_to_string(
std::forward<Thing1>(h))),
216 tail(detail::dot_to_string(
std::forward<Thing2>(t))) {}
239 template <
typename Thing1,
typename Thing2>
244 add_or_replace_attr(
attrs, key_str, val_str);
290 = {
"#00ff00",
"#ff00ff",
"#007fff",
"#ff7f00",
"#7fbf7f",
"#4604ac",
291 "#de0328",
"#19801d",
"#d881f5",
"#00ffff",
"#ffff00",
"#00ff7f",
292 "#ad5867",
"#85f610",
"#84e9f5",
"#f5c778",
"#207090",
"#764ef3",
293 "#7b4c00",
"#0000ff",
"#b80c9a",
"#601045",
"#29b7c0",
"#839f12"};
373 return rx::iterator_range(_nodes.begin(), _nodes.end())
374 | rx::transform([](
auto& pair) ->
Node& {
return pair.second; });
387 return rx::iterator_range(_nodes.begin(), _nodes.end())
389 [](
auto& pair) ->
Node const& {
return pair.second; });
506 template <
typename Thing1,
typename Thing2>
511 add_or_replace_attr(_attrs, key_str, val_str);
534 template <
typename Thing>
536 add_or_replace_attr(_attrs, key,
"");
549 return _nodes.count(
name);
563 template <
typename Thing,
564 typename std::enable_if_t<
565 !std::is_same_v<std::decay_t<Thing>,
std::string>>>
566 [[nodiscard]]
bool is_node(Thing&& thing)
const {
585 template <
typename Thing>
588 auto [it, inserted] = _nodes.emplace(name_str,
Node(name_str));
610 template <
typename Thing>
613 auto it = _nodes.find(name_str);
614 if (it == _nodes.cend()) {
637 template <
typename Thing1,
typename Thing2>
641 throw_if_not_node(head_str);
642 throw_if_not_node(tail_str);
643 _edges.emplace_back(head_str, tail_str);
644 return _edges.back();
667 template <
typename Thing1,
typename Thing2>
671 throw_if_not_node(head_str);
672 throw_if_not_node(tail_str);
674 return e.head == head_str && e.tail == tail_str;
676 if (it == _edges.cend()) {
678 "there is no edges from {} to {}!", head_str, tail_str);
698 std::string_view edge_string() const noexcept;
700 static
void add_or_replace_attr(
std::map<
std::
string,
std::
string>&
attrs,
701 std::
string const& key,
702 std::
string const& val);
753 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:566
auto nodes() noexcept
Returns a range object of references to the current nodes.
Definition dot.hpp:372
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:386
std::vector< Dot > const & subgraphs() const noexcept
Returns a const reference to the vector of subgraphs.
Definition dot.hpp:442
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:535
Node & node(Thing &&thing)
Return a node from the represented graph.
Definition dot.hpp:611
std::vector< Edge > & edges() noexcept
Returns a reference to the vector of edges.
Definition dot.hpp:401
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:290
Dot & add_attr(Thing1 &&key, Thing2 &&val)
Add an attribute to the graph.
Definition dot.hpp:507
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:456
Node & add_node(Thing &&thing)
Add a node to the represented graph.
Definition dot.hpp:586
Dot()
Default constructor.
Dot & kind(Kind val) noexcept
Set the kind of the represented graph.
Definition dot.hpp:329
Edge & add_edge(Thing1 &&head, Thing2 &&tail)
Add an edge with given head and tail.
Definition dot.hpp:638
Dot & name(std::string const &val)
Set the name of the represented graph.
Definition dot.hpp:349
Dot & operator=(Dot const &)
Default copy assignment operator.
Kind
The kind of object represented.
Definition dot.hpp:276
@ subgraph
Definition dot.hpp:283
@ digraph
Value indicating that the represented graph has directed edges ->.
Definition dot.hpp:278
@ graph
Value indicating that the represented graph has undirected edges --.
Definition dot.hpp:280
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:548
std::vector< Dot > & subgraphs() noexcept
Returns a reference to the vector of subgraphs.
Definition dot.hpp:428
std::string const & name() const noexcept
Get the current name of the represented graph.
Definition dot.hpp:359
Edge & edge(Thing1 &&head, Thing2 &&tail)
Returns the first edge with given head and tail.
Definition dot.hpp:668
std::vector< Edge > const & edges() const noexcept
Returns a const reference to the vector of edges.
Definition dot.hpp:414
Kind kind() const noexcept
Get the kind of the represented graph.
Definition dot.hpp:340
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:95
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
This nested struct represents an edge in the represented graph.
Definition dot.hpp:198
std::string head
Name of the head of the edge.
Definition dot.hpp:269
Edge(Thing1 &&h, Thing2 &&t)
Construct from head and tail.
Definition dot.hpp:213
Edge & add_attr(Thing1 &&key, Thing2 &&val)
Add an attribute to an edge.
Definition dot.hpp:240
std::map< std::string, std::string > attrs
Map of attributes.
Definition dot.hpp:266
Edge & operator=(Edge &&)=default
Default move assignment.
std::string tail
Name of the tail of the edge.
Definition dot.hpp:272
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:122
Node & operator=(Node &&)=default
Default move assignment.
Node(Node &&)=default
Default move constructor.
Node(Thing &&thing)
Construct from anything.
Definition dot.hpp:142
Node()=default
Default constructor.
std::map< std::string, std::string > attrs
Map containing the attributes of the Node.
Definition dot.hpp:124
std::string name
The name of the node.
Definition dot.hpp:127
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:184