diff options
author | Daniel Kirchner <daniel@ekpyron.org> | 2019-01-09 02:33:46 +0800 |
---|---|---|
committer | Daniel Kirchner <daniel@ekpyron.org> | 2019-01-10 17:36:50 +0800 |
commit | 0dfd4a726eb7e6fa8a5e886a0d80bb5bf3d9b7dc (patch) | |
tree | 8457ac70f7e9921d9825e939f2ff23ffc1259a46 /libdevcore | |
parent | 63319cfdcd7668a75caaacd0d8f3a83a62c31525 (diff) | |
download | dexon-solidity-0dfd4a726eb7e6fa8a5e886a0d80bb5bf3d9b7dc.tar.gz dexon-solidity-0dfd4a726eb7e6fa8a5e886a0d80bb5bf3d9b7dc.tar.zst dexon-solidity-0dfd4a726eb7e6fa8a5e886a0d80bb5bf3d9b7dc.zip |
Warn about unreachable code.
Diffstat (limited to 'libdevcore')
-rw-r--r-- | libdevcore/Algorithms.h | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/libdevcore/Algorithms.h b/libdevcore/Algorithms.h index 7fe2472d..34a4dfe5 100644 --- a/libdevcore/Algorithms.h +++ b/libdevcore/Algorithms.h @@ -75,4 +75,47 @@ private: V const* m_firstCycleVertex = nullptr; }; +/** + * Generic breadth first search. + * + * Example: Gather all (recursive) children in a graph starting at (and including) ``root``: + * + * Node const* root = ...; + * std::set<Node> allNodes = BreadthFirstSearch<Node>{{root}}.run([](Node const& _node, auto&& _addChild) { + * // Potentially process ``_node``. + * for (Node const& _child: _node.children()) + * // Potentially filter the children to be visited. + * _addChild(_child); + * }).visited; + * + * Note that the order of the traversal is *non-deterministic* (the children are stored in a std::set of pointers). + */ +template<typename V> +struct BreadthFirstSearch +{ + /// Runs the breadth first search. The verticesToTraverse member of the struct needs to be initialized. + /// @param _forEachChild is a callable of the form [...](V const& _node, auto&& _addChild) { ... } + /// that is called for each visited node and is supposed to call _addChild(childNode) for every child + /// node of _node. + template<typename ForEachChild> + BreadthFirstSearch& run(ForEachChild&& _forEachChild) + { + while (!verticesToTraverse.empty()) + { + V const* v = *verticesToTraverse.begin(); + verticesToTraverse.erase(verticesToTraverse.begin()); + visited.insert(v); + + _forEachChild(*v, [this](V const& _vertex) { + if (!visited.count(&_vertex)) + verticesToTraverse.insert(&_vertex); + }); + } + return *this; + } + + std::set<V const*> verticesToTraverse; + std::set<V const*> visited{}; +}; + } |