Honeycomb  0.1
Component-Model Framework
Dep.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Misc/Enum.h"
5 #include "Honey/Misc/MtMap.h"
8 
9 namespace honey
10 {
11 
13 template<class Data_, class Key_ = Id, template<class> class Alloc_ = SmallAllocator>
14 class DepNode
15 {
16 public:
17  enum class DepType
18  {
19  out,
20  in
21  };
22  static const int depTypeMax = 2;
23 
24  typedef Data_ Data;
25  typedef Key_ Key;
26  template<class T> using Alloc = Alloc_<T>;
28 
29  DepNode(const Data& data = Data(), const Key& key = Key()) : _data(data), _key(key) {}
30 
32  void setData(const Data& data) { _data = data; }
33  const Data& getData() const { return _data; }
34  Data& getData() { return _data; }
36  operator const Data&() const { return getData(); }
37  operator Data&() { return getData(); }
39  const Data& operator*() const { return getData(); }
40  Data& operator*() { return getData(); }
41  const Data& operator->() const { return getData(); }
42  Data& operator->() { return getData(); }
43 
45  void setKey(const Key& key) { _key = key; }
46  const Key& getKey() const { return _key; }
47  Key& getKey() { return _key; }
48 
50  void add(const Key& key, DepType type = DepType::out)
51  {
52  //Can't depend on itself
53  if (key == _key) return;
54  _deps[key] = type;
55  }
56 
58  void remove(const Key& key) { _deps.erase(key); }
60  void clear() { _deps.clear(); }
61 
63  const DepMap& deps() const { return _deps; }
64 
66  static DepType depTypeOpp(DepType type) { return type == DepType::out ? DepType::in : DepType::out; }
67 
68 private:
69  Data _data;
70  Key _key;
71  DepMap _deps;
72 };
73 
74 
75 
77 
81 template<class DepNode_>
82 class DepGraph
83 {
84  typedef DepNode_ DepNode;
85  typedef typename DepNode::Data Data;
86  typedef typename DepNode::Key Key;
87  typedef typename DepNode::DepType DepType;
88  template<class T> using Alloc = typename DepNode::template Alloc<T>;
89 
90 public:
91  class Vertex;
92 
93 private:
95  typedef list<Vertex, Alloc<Vertex>> VertexList;
96 
97 public:
101 
103 
107  class Vertex
108  {
109  friend class DepGraph;
110  public:
113 
115  const NodeList& nodes() { return nodeList; }
116  const NodeListConst& nodes() const { return reinterpret_cast<const NodeListConst&>(nodeList); }
118  const KeyList& keys() const { return keyList; }
120  auto links(DepType type = DepType::out) -> decltype(honey::keys(declval<const LinkMap>()))
121  { return honey::keys(const_cast<const Vertex*>(this)->linkMaps[static_cast<int>(type)]); }
122  auto links(DepType type = DepType::out) const -> decltype(honey::keys(declval<const LinkMapConst>()))
123  { return honey::keys(reinterpret_cast<const LinkMapConst&>(linkMaps[static_cast<int>(type)])); }
124 
125  private:
127  void add(DepType type, Vertex* vertex, int count = 1)
128  {
129  auto& linkMap = this->linkMap(type);
130  auto itMap = linkMap.find(vertex);
131  auto& refCount = (itMap == linkMap.end()) ? linkMap[vertex] = 0 : itMap->second;
132  refCount += count;
133  }
134 
136  void remove(DepType type, Vertex* vertex, int count = 1)
137  {
138  auto& linkMap = this->linkMap(type);
139  auto itMap = linkMap.find(vertex);
140  assert(itMap != linkMap.end(), sout() << "Unable to remove dependency link. Vertex: " << *keyList.begin() <<
141  " ; Link Type: " << static_cast<int>(type) << " ; Link Key: " << *vertex->keyList.begin());
142  auto& refCount = itMap->second;
143  refCount -= count;
144  if (refCount <= 0) linkMap.erase(itMap);
145  }
146 
147  const LinkMap& linkMap(DepType type) const { return linkMaps[static_cast<int>(type)]; }
148  LinkMap& linkMap(DepType type) { return linkMaps[static_cast<int>(type)]; }
149 
151  bool isPhantom() const { return nodeList.empty(); }
153  bool isMerged() const { return keyList.size() > 1; }
154 
155  typename VertexList::iterator itAlloc;
156  NodeList nodeList;
157  KeyList keyList;
158  array<LinkMap, DepNode::depTypeMax> linkMaps;
159  };
160 
161 private:
162  typedef vector<Vertex*, Alloc<Vertex*>> VertexPList;
163  typedef stdutil::unordered_set<Vertex*, Alloc> VertexSet;
164 
165  struct CondenseData
166  {
167  CondenseData() : preOrd(0) {}
168 
169  typedef stdutil::unordered_map<Vertex*, int, Alloc> PreOrdMap;
170  //Merge vertex -> Component vertices
171  typedef stdutil::unordered_map<Vertex*, VertexSet, Alloc> MergeMap;
172  //Component vertices -> Merge vertex
173  typedef stdutil::unordered_map<Vertex*, Vertex*, Alloc> MergeMapR;
174 
175  VertexPList stackS;
176  VertexPList stackP;
177  int preOrd;
178  PreOrdMap preOrdMap;
179  VertexSet assignedList;
180  MergeMap mergeMap;
181  MergeMapR mergeMapR;
182  };
183 
184  mtkey(k_vertex)
185  mtkey(k_linkMap)
186  mtkey(k_linkIt)
187 
188  typedef MtMap< Vertex*, k_vertex,
189  const typename Vertex::LinkMap*, k_linkMap,
190  typename Vertex::LinkMap::const_iterator, k_linkIt
191  > VertexLink;
192 
193  typedef vector<VertexLink, Alloc<VertexLink>> VertexLinkList;
194 
195 public:
197  bool add(DepNode& node)
198  {
199  auto& vertex = createVertex(node.getKey());
200  //Check if already added
201  if (!vertex.nodeList.insert(&node).second) return false;
202 
203  for (auto& e : node.deps())
204  {
205  auto& key = e.first;
206  auto type = e.second;
207 
208  //Create phantom vertex if it doesn't exist
209  auto& depVertex = createVertex(key);
210  //Vertex can't depend on itself
211  if (&depVertex == &vertex) continue;
212 
213  switch (type)
214  {
215  case DepType::out:
216  vertex.add(DepType::out, &depVertex);
217  depVertex.add(DepType::in, &vertex);
218  break;
219  case DepType::in:
220  vertex.add(DepType::in, &depVertex);
221  depVertex.add(DepType::out, &vertex);
222  break;
223  }
224  }
225  return true;
226  }
227 
229  bool remove(DepNode& node)
230  {
231  auto itMap = _vertexMap.find(node.getKey());
232  if (itMap == _vertexMap.end()) return false;
233 
234  auto& vertex = *itMap->second;
235 
236  //Node must be referenced
237  auto itNode = vertex.nodeList.find(&node);
238  if (itNode == vertex.nodeList.end()) return false;
239  vertex.nodeList.erase(itNode);
240 
241  for (auto& e : node.deps())
242  {
243  auto& key = e.first;
244  auto type = e.second;
245 
246  //Find dependency vertex in map
247  auto itMap = _vertexMap.find(key);
248  assert(itMap != _vertexMap.end(), sout() << "Unable to remove dependency. Node: " << node.getKey() <<
249  " ; DepType: " << static_cast<int>(type) << " ; DepKey: " << key);
250  auto& depVertex = *itMap->second;
251  //Vertex can't depend on itself
252  if (&depVertex == &vertex) continue;
253 
254  switch (type)
255  {
256  case DepType::out:
257  vertex.remove(DepType::out, &depVertex);
258  depVertex.remove(DepType::in, &vertex);
259  break;
260  case DepType::in:
261  vertex.remove(DepType::in, &depVertex);
262  depVertex.remove(DepType::out, &vertex);
263  break;
264  }
265 
266  //Don't keep around unreferenced phantoms
267  if (depVertex.isPhantom() && depVertex.linkMap(DepType::in).empty() && depVertex.linkMap(DepType::out).empty())
268  deleteVertex(depVertex);
269  }
270 
271  //Don't keep around unreferenced phantoms
272  if (vertex.isPhantom() && vertex.linkMap(DepType::in).empty() && vertex.linkMap(DepType::out).empty())
273  deleteVertex(vertex);
274  //If we changed a merged vertex then we've probably broken the cyclic dependency so we should decompose it
275  else if (vertex.isMerged())
276  decondense(vertex);
277  return true;
278  }
279 
281  void clear()
282  {
283  _vertexList.clear();
284  _vertexMap.clear();
285  }
286 
288 
294  template<class Vertex_>
295  class Iter_
296  {
297  friend class DepGraph;
298  template<class Vertex> friend class NodeIter_;
299 
300  public:
301  typedef std::forward_iterator_tag iterator_category;
302  typedef Vertex_ value_type;
304  typedef Vertex_* pointer;
305  typedef Vertex_& reference;
306 
307  Iter_() :
308  _graph(nullptr), _vertex(nullptr), _type(DepType::out), _skipEdges(false) {}
309 
310  Iter_(const DepGraph& graph, optional<const Key&> start, DepType type) :
311  _graph(&graph) { reset(start, type); }
312 
314  {
315  if (!_vertex) return *this;
316 
317  if (_skipEdges)
318  {
319  while (!_stack.empty() && _stack.back()[k_vertex()] == _vertex) _stack.pop_back();
320  _skipEdges = false;
321  }
322 
323  while (_vertexIt != _graph->_vertexList.end() || !_stack.empty())
324  {
325  if (_stack.empty())
326  {
327  //move to next root vertex in global list
328  ++_vertexIt;
329  nextRoot();
330  }
331  else
332  {
333  //move along links
334  if (_stack.back()[k_linkIt()] == _stack.back()[k_linkMap()]->end()) { _stack.pop_back(); continue; }
335  _vertex = (_stack.back()[k_linkIt()]++)->first;
336  }
337  if (!_vertex || _vertex->isPhantom() || !_visited.insert(_vertex).second) continue;
338 
339  //next iter move along links
340  _stack.push_back(mtmap( k_vertex() = _vertex,
341  k_linkMap() = &_vertex->linkMap(_type),
342  k_linkIt() = _vertex->linkMap(_type).begin() ));
343  return *this;
344  }
345 
346  _vertex = nullptr;
347  return *this;
348  }
349 
350  Iter_ operator++(int) { auto tmp = *this; ++*this; return tmp; }
351 
352  bool operator==(const Iter_& rhs) const { return _vertex == rhs._vertex; }
353  bool operator!=(const Iter_& rhs) const { return !operator==(rhs); }
354 
355  reference operator*() const { assert(_vertex); return *_vertex; }
356  pointer operator->() const { return &operator*(); }
357 
359  void reset(optional<const Key&> start = optnull, DepType type = DepType::out)
360  {
361  _type = type;
362  _skipEdges = false;
363  _vertexIt = _graph->_vertexList.end();
364  _stack.clear();
365  _visited.clear();
366 
367  if (start)
368  {
369  //find start vertex by key (ignore phantom)
370  auto itMap = _graph->_vertexMap.find(*start);
371  _vertex = itMap != _graph->_vertexMap.end() && !itMap->second->isPhantom() ? itMap->second : nullptr;
372  }
373  else
374  {
375  //get first root vertex in global list (ignore phantom)
376  _vertexIt = _graph->_vertexList.begin();
377  nextRoot();
378  }
379  if (!_vertex) return;
380 
381  //next iter move along links
382  _visited.insert(_vertex);
383  _stack.push_back(mtmap( k_vertex() = _vertex,
384  k_linkMap() = &_vertex->linkMap(_type),
385  k_linkIt() = _vertex->linkMap(_type).begin() ));
386  }
387 
389  void skipEdges() { _skipEdges = true; }
390 
391  private:
392  void nextRoot()
393  {
394  auto typeOpp = DepNode::depTypeOpp(_type);
395  for (; _vertexIt != _graph->_vertexList.end() && (_vertexIt->isPhantom() || !_vertexIt->linkMap(typeOpp).empty()); ++_vertexIt);
396  _vertex = _vertexIt != _graph->_vertexList.end() ? const_cast<Vertex*>(&*_vertexIt) : nullptr;
397  }
398 
399  const DepGraph* _graph;
400  Vertex* _vertex;
401  DepType _type;
402  bool _skipEdges;
403  typename VertexList::const_iterator _vertexIt;
404  VertexLinkList _stack;
405  VertexSet _visited;
406  };
407  typedef Iter_<Vertex> Iter;
408  typedef Iter_<const Vertex> ConstIter;
409 
411  Range_<ConstIter, ConstIter> range(optional<const Key&> start = optnull, DepType type = DepType::out) const { return honey::range(ConstIter(*this, start, type), ConstIter()); }
412  Range_<Iter, Iter> range(optional<const Key&> start = optnull, DepType type = DepType::out) { return honey::range(Iter(*this, start, type), Iter()); }
413 
414 
416  template<class Vertex_>
417  class NodeIter_
418  {
419  public:
421  typedef typename std::conditional<std::is_const<Vertex_>::value, NodeListConst, NodeList>::type NodeList;
423  typedef std::forward_iterator_tag iterator_category;
424  typedef DepNode value_type;
426  typedef DepNode* pointer;
427  typedef DepNode& reference;
428 
429  NodeIter_() : _node(nullptr) {}
430  NodeIter_(Iter&& it) : _it(move(it)) { initIt(); }
431 
433  {
434  if (!_it._vertex) return *this;
435  if (++_nodeIt == _it->nodes().end()) { ++_it; initIt(); }
436  else _node = *_nodeIt;
437  return *this;
438  }
439 
440  NodeIter_ operator++(int) { auto tmp = *this; ++*this; return tmp; }
441 
442  bool operator==(const NodeIter_& rhs) const { return _node == rhs._node; }
443  bool operator!=(const NodeIter_& rhs) const { return !operator==(rhs); }
444 
445  reference operator*() const { assert(_node); return *_node; }
446  pointer operator->() const { return &operator*(); }
447 
449  void reset(optional<const Key&> start = optnull, DepType type = DepType::out)
450  { _it.reset(start, type); initIt(); }
452  void skipEdges() { _it._skipEdges(); }
454  Vertex_& vertex() const { return *_it; }
455 
456  private:
457  void initIt() { _node = _it._vertex ? *(_nodeIt = _it->nodes().begin()) : nullptr; }
458 
459  Iter _it;
460  typename NodeList::const_iterator _nodeIt;
461  DepNode* _node;
462  };
463  typedef NodeIter_<Vertex> NodeIter;
464  typedef NodeIter_<const Vertex> NodeConstIter;
465 
469 
471  bool depends(const Key& vertex, const Key& dependency, DepType type = DepType::out) const
472  {
473  auto range = this->range(vertex, type);
474  for (auto it = begin(range); it != end(range); ++it) if (it->keys().count(dependency)) return true;
475  return false;
476  }
478  bool depends(const Key& vertex, const DepNode& dependency, DepType type = DepType::out) const
479  {
480  auto range = this->range(vertex, type);
481  return find(range, [&](auto& e) { return e.nodes().count(&dependency); }) != end(range);
482  }
483 
485 
488  const Vertex* vertex(const Key& key) const
489  {
490  auto itMap = _vertexMap.find(key);
491  return itMap != _vertexMap.end() && !itMap->second->isPhantom() ? itMap->second : nullptr;
492  }
493  Vertex* vertex(const Key& key)
494  {
495  auto itMap = _vertexMap.find(key);
496  return itMap != _vertexMap.end() && !itMap->second->isPhantom() ? itMap->second : nullptr;
497  }
498 
500 
506  void condense()
507  {
508  CondenseData data;
509  VertexLinkList linkList;
510 
511  for (auto& vertex : values(_vertexMap))
512  {
513  assert(data.stackS.empty() && data.stackP.empty(), "Condense algorithm failure");
514  linkList.clear();
515  linkList.push_back(mtmap( k_vertex() = vertex,
516  k_linkMap() = &vertex->linkMap(DepType::out),
517  k_linkIt() = vertex->linkMap(DepType::out).begin() ));
518  condense(data, linkList);
519  }
520 
521  for (auto& e : data.mergeMap)
522  {
523  auto& mergeVertex = *e.first;
524  auto& oldVertexList = e.second;
525 
526  //Build merged vertex links
527  for (auto i : honey::range(DepNode::depTypeMax))
528  {
529  auto type = DepType(i);
530  auto depTypeOpp = DepNode::depTypeOpp(type);
531 
532  //Loop through old vertices
533  for (auto& e : oldVertexList)
534  {
535  auto& oldVertex = *e;
536  for (auto& e : oldVertex.linkMap(type))
537  {
538  auto& vertex = *e.first;
539 
540  //Ignore link to self
541  if (oldVertexList.count(&vertex)) continue;
542 
543  //If the vertex at the other end is also being merged then link to that merged vertex instead
544  auto pVertex = &vertex;
545  auto itMerged = data.mergeMapR.find(pVertex);
546  if (itMerged != data.mergeMapR.end()) pVertex = itMerged->second;
547 
548  //Add link to merged vertex
549  mergeVertex.add(type, pVertex, e.second);
550 
551  //Merge links at other end
552  //If the vertex at the other end is also being merged then its links are clean
553  if (pVertex != &vertex) continue;
554 
555  //Get old link
556  auto& linkMap = vertex.linkMap(depTypeOpp);
557  auto itOld = linkMap.find(&oldVertex);
558  assert(itOld != linkMap.end(), "Old link not found, problem with algorithm");
559  //Move old link into merged link
560  vertex.add(depTypeOpp, &mergeVertex, itOld->second);
561  linkMap.erase(itOld);
562  }
563  }
564  }
565 
566  //Remap to merged vertex
567  for (auto& e : mergeVertex.keyList) { _vertexMap[e] = &mergeVertex; }
568 
569  //Delete old vertices
570  for (auto& e : oldVertexList)
571  {
572  auto& oldVertex = *e;
573  //Clear key list so delete doesn't unmap merged vertex
574  oldVertex.keyList.clear();
575  deleteVertex(oldVertex);
576  }
577  }
578  }
579 
580 private:
581  Vertex& createVertex()
582  {
583  //Add to allocated list
584  _vertexList.resize(_vertexList.size()+1);
585  //Set up self iterator for fast removal
586  _vertexList.back().itAlloc = --_vertexList.end();
587  return _vertexList.back();
588  }
589 
591  Vertex& createVertex(const Key& key)
592  {
593  auto itMap = _vertexMap.find(key);
594  if (itMap == _vertexMap.end()) itMap = mapVertex(createVertex(), key);
595  return *itMap->second;
596  }
597 
599  typename VertexMap::iterator mapVertex(Vertex& vertex, const Key& key)
600  {
601  vertex.keyList.insert(key);
602  return _vertexMap.insert(make_pair(key, &vertex)).first;
603  }
604 
605  void deleteVertex(Vertex& vertex)
606  {
607  //Remove all keys from map
608  for (auto& e : vertex.keyList) { _vertexMap.erase(e); }
609  //Remove from allocated list
610  _vertexList.erase(vertex.itAlloc);
611  }
612 
628  void condense(CondenseData& data, const VertexLinkList& linkList)
629  {
630  auto vertex = linkList.back()[k_vertex()];
631  if (!data.preOrdMap.insert(make_pair(vertex, data.preOrd)).second) return;
632  ++data.preOrd;
633  data.stackS.push_back(vertex);
634  data.stackP.push_back(vertex);
635 
636  VertexLinkList recurseList;
637 
638  for (auto& e : linkList)
639  {
640  auto links = honey::range(e[k_linkIt()], e[k_linkMap()]->end());
641  for (auto& linkVertex : keys(links))
642  {
643  auto itPreOrd = data.preOrdMap.find(linkVertex);
644  if (itPreOrd == data.preOrdMap.end())
645  {
646  //Move along out links
647  recurseList.clear();
648  recurseList.push_back(mtmap(k_vertex() = linkVertex,
649  k_linkMap() = &linkVertex->linkMap(DepType::out),
650  k_linkIt() = linkVertex->linkMap(DepType::out).begin() ));
651  condense(data, recurseList);
652  }
653  else if (!data.assignedList.count(linkVertex))
654  {
655  auto linkPreOrd = itPreOrd->second;
656  while (data.preOrdMap.find(data.stackP.back())->second > linkPreOrd)
657  {
658  data.stackP.pop_back();
659  assert(!data.stackP.empty(), "Condense algorithm failure");
660  }
661  }
662  }
663  }
664 
665  if (data.stackP.back() == vertex)
666  {
667  //Only merge if there is more than one node in merge list
668  if (data.stackS.back() != vertex)
669  {
670  //Merge strongly connected vertices
671  auto& mergeVertex = createVertex();
672 
673  Vertex* assignVertex;
674  do
675  {
676  assignVertex = data.stackS.back();
677  data.stackS.pop_back();
678 
679  data.assignedList.insert(assignVertex);
680  data.mergeMap[&mergeVertex].insert(assignVertex);
681  data.mergeMapR[assignVertex] = &mergeVertex;
682 
683  //Merge nodes into one node
684 
685  //Merge references
686  for (auto& e : assignVertex->nodeList)
687  {
688  //Ensure that merged references are unique. If this assert fails then there is a problem with the class' algorithms.
689  assert(!mergeVertex.nodeList.count(e), sout() << "Duplicate reference during condense merge. Node: " << e->getKey());
690  mergeVertex.nodeList.insert(e);
691  }
692 
693  //Merge keys
694  for (auto& e : assignVertex->keyList)
695  {
696  //Ensure that merged keys are unique. If this assert fails then there is a problem with the class' algorithms.
697  assert(!mergeVertex.keyList.count(e), sout() << "Duplicate key during condense merge. Node: " << e);
698  mergeVertex.keyList.insert(e);
699  }
700 
701  } while (assignVertex != vertex);
702  }
703  else
704  {
705  //There was only one node in merge list, ignore it
706  data.assignedList.insert(data.stackS.back());
707  data.stackS.pop_back();
708  }
709 
710  data.stackP.pop_back();
711  }
712  }
713 
715  void decondense(Vertex& mergeVertex)
716  {
717  //Unmap merged vertex
718  for (auto& e : mergeVertex.keyList) { _vertexMap.erase(e); }
719  //Re-add component nodes
720  for (auto& e : mergeVertex.nodeList) { add(*e); }
721 
722  //Loop through links and update links on other side
723  for (auto i : honey::range(DepNode::depTypeMax))
724  {
725  auto type = DepType(i);
726  auto depTypeOpp = DepNode::depTypeOpp(type);
727 
728  for (auto& e : keys(mergeVertex.linkMap(type)))
729  {
730  auto& vertex = *e;
731  //Remove link to merged vertex
732  vertex.linkMap(depTypeOpp).erase(&mergeVertex);
733  //Loop through nodes and re-add links that have the same type and reference a component vertex
734  for (auto& e : vertex.nodeList)
735  {
736  auto& node = *e;
737  for (auto& e : node.deps())
738  {
739  auto type = e.second;
740  if (type != depTypeOpp) continue;
741 
742  auto& key = e.first;
743  if (!mergeVertex.keyList.count(key)) continue;
744 
745  //Create phantom vertex if it doesn't exist
746  auto& depVertex = createVertex(key);
747 
748  switch (type)
749  {
750  case DepType::out:
751  vertex.add(DepType::out, &depVertex);
752  depVertex.add(DepType::in, &vertex);
753  break;
754 
755  case DepType::in:
756  vertex.add(DepType::in, &depVertex);
757  depVertex.add(DepType::out, &vertex);
758  break;
759  }
760  }
761  }
762  }
763  }
764 
765  //Clear key list so delete doesn't unmap component vertices
766  mergeVertex.keyList.clear();
767  deleteVertex(mergeVertex);
768  }
769 
770  VertexList _vertexList;
771  VertexMap _vertexMap;
772 };
773 
774 }
NodeIter_< const Vertex > NodeConstIter
Definition: Dep.h:464
bool operator!=(const NodeIter_ &rhs) const
Definition: Dep.h:443
Data & operator*()
Definition: Dep.h:40
bool operator!=(const Iter_ &rhs) const
Definition: Dep.h:353
void skipEdges()
Skip the current vertex's edges on next step of this iterator.
Definition: Dep.h:389
this node depends on the target node
void skipEdges()
Skip the current vertex's edges on next step of this iterator.
Definition: Dep.h:452
Vertex_ value_type
Definition: Dep.h:302
Depth-first pre-order iterator over nodes. Iterates over nodes that constitute each vertex in a verte...
Definition: Dep.h:417
static optnull_t optnull
Null optional, use to reset an optional to an uninitialized state or test for initialization.
Definition: Optional.h:12
const NodeList & nodes()
Get all nodes that constitute this vertex.
Definition: Dep.h:115
static DepType depTypeOpp(DepType type)
Get opposite dependency type.
Definition: Dep.h:66
this node is depended on by the target node
stdutil::unordered_map< const Vertex *, int, Alloc > LinkMapConst
Definition: Dep.h:112
Iter_ operator++(int)
Definition: Dep.h:350
reference operator*() const
Definition: Dep.h:355
auto links(DepType type=DepType::out) -> decltype(honey::keys(declval< const LinkMap >()))
Get all vertices along in/out links.
Definition: Dep.h:120
ptrdiff_t sdt
Size difference type, shorthand for ptrdiff_t.
Definition: Core.h:92
Data_ Data
Definition: Dep.h:24
DepNode * pointer
Definition: Dep.h:426
Iter find(Range &&, Seqs &&..., Func &&pred)
Find an element in a series of sequences.
Vertex_ & reference
Definition: Dep.h:305
DepNode value_type
Definition: Dep.h:424
Iter_()
Definition: Dep.h:307
NodeIter_(Iter &&it)
Definition: Dep.h:430
const Data & operator->() const
Definition: Dep.h:41
NodeIter_ & operator++()
Definition: Dep.h:432
bool depends(const Key &vertex, const Key &dependency, DepType type=DepType::out) const
Check if vertex depends on another vertex.
Definition: Dep.h:471
NodeIter_< Vertex > NodeIter
Definition: Dep.h:463
stdutil::unordered_set< DepNode *, Alloc > NodeList
Definition: Dep.h:98
std::unordered_map< Key, Value, std::hash< Key >, std::equal_to< Key >, Alloc< pair< const Key, Value >>> unordered_map
std::unordered_map with custom allocator
Definition: StdUtil.h:83
std::enable_if< mt::isIterator< Iter1 >::value, Range_< Iter1, Iter2 > >::type range(Iter1 &&first, Iter2 &&last)
Range from iterators [first, last)
Definition: Range.h:116
std::remove_pointer< T > removePtr
Remove pointer from type.
Definition: Meta.h:48
auto mtmap(Pairs &&...pairs) -> decltype(priv::mtmap_(priv::PairSeqGen< Pairs... >(), forward< Pairs >(pairs)...))
Construct a map from (key() = value) pairs.
Definition: MtMap.h:103
Iter_< Vertex_ > Iter
Definition: Dep.h:420
Range_< ConstIter, ConstIter > range(optional< const Key & > start=optnull, DepType type=DepType::out) const
Get a depth-first pre-order range starting from a vertex. If start vertex is null then range is over ...
Definition: Dep.h:411
Vertex_ & vertex() const
Get the current vertex.
Definition: Dep.h:454
Iter_ & operator++()
Definition: Dep.h:313
Range_< NodeIter, NodeIter > rangeNode(optional< const Key & > start=optnull, DepType type=DepType::out)
Definition: Dep.h:468
auto keys(Range &&range) -> Range_< TupleIter< mt_iterOf(range), 0 >, TupleIter< mt_iterOf(range), 0 >>
Create a range over the keys of a map or map iterator range.
Definition: StdUtil.h:23
bool depends(const Key &vertex, const DepNode &dependency, DepType type=DepType::out) const
Check if vertex depends on node.
Definition: Dep.h:478
pointer operator->() const
Definition: Dep.h:356
bool operator==(const Iter_ &rhs) const
Definition: Dep.h:352
ostringstream sout()
Shorthand to create ostringstream.
Definition: Stream.h:15
stdutil::unordered_map< Key, DepType, Alloc > DepMap
Definition: Dep.h:27
Dependency node for insertion into graph.
Definition: Dep.h:14
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
void add(const Key &key, DepType type=DepType::out)
Add a dependency link.
Definition: Dep.h:50
DepType
Definition: Dep.h:17
Range_< NodeConstIter, NodeConstIter > rangeNode(optional< const Key & > start=optnull, DepType type=DepType::out) const
Get a depth-first pre-order range over nodes starting from a vertex. If start vertex is null then ran...
Definition: Dep.h:467
sdt difference_type
Definition: Dep.h:303
Vertex * vertex(const Key &key)
Definition: Dep.h:493
pointer operator->() const
Definition: Dep.h:446
Iter_(const DepGraph &graph, optional< const Key & > start, DepType type)
Definition: Dep.h:310
reference operator*() const
Definition: Dep.h:445
A vertex is initially associated with one key and acts like a multi-map, storing all nodes and graph ...
Definition: Dep.h:107
void reset(optional< const Key & > start=optnull, DepType type=DepType::out)
Reset iterator to begin at vertex in graph.
Definition: Dep.h:359
stdutil::unordered_set< Key, Alloc > KeyList
Definition: Dep.h:100
bool operator==(const NodeIter_ &rhs) const
Definition: Dep.h:442
const Data & operator*() const
Get the data at this node.
Definition: Dep.h:39
Enables any type to be optional so it can exist in an uninitialized null state.
Definition: Optional.h:52
void condense()
Condense directed graph into directed acyclic graph. Useful for finding dependency cycles and optimiz...
Definition: Dep.h:506
auto links(DepType type=DepType::out) const -> decltype(honey::keys(declval< const LinkMapConst >()))
Definition: Dep.h:122
auto values(Range &&range) -> Range_< TupleIter< mt_iterOf(range), 1 >, TupleIter< mt_iterOf(range), 1 >>
Create a range over the values of a map or map iterator range.
Definition: StdUtil.h:30
void clear()
Clear graph of all nodes.
Definition: Dep.h:281
DepNode & reference
Definition: Dep.h:427
const DepMap & deps() const
Get dep links.
Definition: Dep.h:63
Global allocator for small memory blocks. To provide a custom pool define SmallAllocator_createSingle...
Definition: SmallAllocator.h:23
Dependency graph. Collects nodes and builds a searchable directed graph.
Definition: Dep.h:82
void setData(const Data &data)
Set the data that this node contains.
Definition: Dep.h:32
static const int depTypeMax
Definition: Dep.h:22
stdutil::unordered_set< const DepNode *, Alloc > NodeListConst
Definition: Dep.h:99
Iterator range. See range(Iter1&&, Iter2&&) to create.
Definition: Range.h:88
const Data & getData() const
Definition: Dep.h:33
sdt difference_type
Definition: Dep.h:425
std::forward_iterator_tag iterator_category
Definition: Dep.h:301
void reset(optional< const Key & > start=optnull, DepType type=DepType::out)
Reset iterator to begin at vertex in graph.
Definition: Dep.h:449
Key_ Key
Definition: Dep.h:25
Depth-first pre-order iterator over vertices.
Definition: Dep.h:295
stdutil::unordered_map< Vertex *, int, Alloc > LinkMap
Definition: Dep.h:111
const NodeListConst & nodes() const
Definition: Dep.h:116
const Vertex * vertex(const Key &key) const
Get a vertex which contains a list of cyclical (strongly connected) dependency nodes.
Definition: Dep.h:488
Vertex_ * pointer
Definition: Dep.h:304
const Key & getKey() const
Definition: Dep.h:46
void clear()
Remove all dependency links.
Definition: Dep.h:60
const KeyList & keys() const
Get all keys mapped to this vertex.
Definition: Dep.h:118
bool add(DepNode &node)
Add a node to the graph.
Definition: Dep.h:197
Data & operator->()
Definition: Dep.h:42
std::forward_iterator_tag iterator_category
Definition: Dep.h:423
NodeIter_()
Definition: Dep.h:429
std::unordered_set< Key, std::hash< Key >, std::equal_to< Key >, Alloc< Key >> unordered_set
std::unordered_set with custom allocator
Definition: StdUtil.h:89
Data & getData()
Definition: Dep.h:34
std::conditional< std::is_const< Vertex_ >::value, NodeListConst, NodeList >::type NodeList
Definition: Dep.h:421
DepNode(const Data &data=Data(), const Key &key=Key())
Definition: Dep.h:29
void setKey(const Key &key)
Set the key used to identify this node.
Definition: Dep.h:45
Global Honeycomb namespace.
mt::removePtr< typename NodeList::value_type >::type DepNode
Definition: Dep.h:422
Range_< Iter, Iter > range(optional< const Key & > start=optnull, DepType type=DepType::out)
Definition: Dep.h:412
Iter_< const Vertex > ConstIter
Definition: Dep.h:408
Iter_< Vertex > Iter
Definition: Dep.h:407
Key & getKey()
Definition: Dep.h:47
typename priv::MtMap_< Pairs... >::type MtMap
Declare a map type with MtMap
Definition: MtMap.h:46
NodeIter_ operator++(int)
Definition: Dep.h:440