71 for (std::size_t i = from; i < chain.size(); ++i) {
72 const char c = chain[i];
73 if (c ==
'[' || c ==
'{') {
75 }
else if (c ==
']' || c ==
'}') {
76 if (depth > 0) --depth;
77 }
else if ((c ==
'-') && (depth == 0)) {
81 return std::string_view::npos;
95 inline std::vector< std::pair< std::string, FastGraphOp > >
97 std::vector< std::pair< std::string, FastGraphOp > > tokens;
101 while (pos <= chain.size()) {
104 std::size_t opStart = dashPos;
105 std::size_t opLen = 1;
108 if (dashPos != std::string_view::npos) {
109 if ((dashPos + 1 < chain.size()) && (chain[dashPos + 1] ==
'>')) {
112 }
else if ((dashPos > pos) && (chain[dashPos - 1] ==
'<')) {
113 opStart = dashPos - 1;
119 const auto tokEnd = (dashPos == std::string_view::npos) ? chain.size() : opStart;
121 tokens.emplace_back(
trim_copy(chain.substr(pos, tokEnd - pos)), pendingOp);
123 if (dashPos == std::string_view::npos) {
break; }
125 pos = opStart + opLen;
137 template <
typename GRAPH_TYPE >
142 const auto id =
static_cast< NodeId >(value);
143 if (!g.existsNode(
id)) { g.addNodeWithId(
id); }
147 if (
const auto id = g.idFromName(token)) {
return *id; }
148 const NodeId id = g.addNode();
149 g.setName(
id, token);
175 template <
typename Resolve,
typename AddArc,
typename AddEdge >
177 std::string_view desc,
184 for (
const auto& [token, op]: tokens) {
187 "fastGraph: malformed description '" << desc
188 <<
"' (operator without a node token)")
190 const NodeId id = resolve(token);
194 addArc(lastId,
id, token);
196 addArc(
id, lastId, token);
198 addEdge(lastId,
id, token);
209 template < GUM_NodeGraphable GRAPH_TYPE >
213 std::vector< std::vector< std::pair< std::string, FastGraphOp > > > chains;
217 if (
trim_copy(chainStr).empty()) {
continue; }
219 auto tokens = fastGraphTokenize(chainStr);
220 for (
const auto& [token, op]: tokens) {
223 "fastGraph: malformed description '" << desc
224 <<
"' (operator without a node token)")
226 if (!fastGraphIsNodeIdToken(token)) { useIds =
false; }
228 chains.push_back(std::move(tokens));
233 auto resolve = [&](
const std::string& token) {
return fastGraphBuildNode(g, token, useIds); };
234 auto addArc = [&](
NodeId tail,
NodeId head,
const std::string& token) {
236 g.addArc(tail, head);
239 "fastGraph: '" << token <<
"' is preceded by an arc operator but the "
240 <<
"requested graph type does not support arcs")
243 auto addEdge = [&](
NodeId a,
NodeId b,
const std::string& token) {
248 "fastGraph: '" << token <<
"' is preceded by '-' but the "
249 <<
"requested graph type does not support edges")
253 for (
const auto& tokens: chains) {
254 fastGraphWalkTokens(tokens, desc, resolve, addArc, addEdge);
The base class for all directed edges.
The base class for all undirected edges.
Exception : there is something wrong with an arc.
Exception : there is something wrong with an edge.
Concept for directed graphs (arcs with parents/children).
Concept for undirected graphs (edges with neighbours).
#define GUM_ERROR(type, msg)
Builds a graph from a "fast" DOT-like textual description.
Size NodeId
Type for node ids.
std::string remove_newline(std::string_view s)
remove all newlines in a string
bool isIntegerWithResult(std::string_view val, int *res)
return true is a string contains an integer value
std::vector< std::string > split(std::string_view str, std::string_view delim)
Split str using the delimiter.
std::string trim_copy(std::string_view s)
trim from both ends (copying)
FastGraphOp
which operator (if any) precedes a node token in a fastGraph chain
std::size_t fastGraphFindDash(std::string_view chain, std::size_t from)
Finds the first '-' at bracket-depth 0, starting at from, skipping any '['...']' or '{'....
void fastGraphWalkTokens(const std::vector< std::pair< std::string, FastGraphOp > > &tokens, std::string_view desc, Resolve resolve, AddArc addArc, AddEdge addEdge)
Walks one already-tokenized chain (see fastGraphTokenize()), resolving each token to a NodeId via res...
NodeId fastGraphBuildNode(GRAPH_TYPE &g, const std::string &token, bool useIds)
gets or creates the node denoted by token, in NodeId or name mode
std::vector< std::pair< std::string, FastGraphOp > > fastGraphTokenize(std::string_view chain)
Scans one ";"-delimited chain, splitting it into node tokens while remembering, for each token,...
bool fastGraphIsNodeIdToken(const std::string &token)
true if token must be read as a NodeId (non-negative integer)
gum is the global namespace for all aGrUM entities
GRAPH_TYPE fastGraph(std::string_view desc)
Builds a GRAPH_TYPE from a DOT-like textual description.
Utilities for manipulating strings.