TRIQS/triqs_cthyb 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
rbt_iterators.hpp
1/*******************************************************************************
2 *
3 * TRIQS: a Toolbox for Research in Interacting Quantum Systems
4 *
5 * Copyright (C) 2014 by O. Parcollet, M. Ferrero, P. Seth
6 * Adapted from Algorithms (fourth edition) by R. Sedgewick
7 *
8 * TRIQS is free software: you can redistribute it and/or modify it under the
9 * terms of the GNU General Public License as published by the Free Software
10 * Foundation, either version 3 of the License, or (at your option) any later
11 * version.
12 *
13 * TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * TRIQS. If not, see <http://www.gnu.org/licenses/>.
20 *
21 ******************************************************************************/
22#pragma once
23#include <stack>
24
25namespace triqs {
26 namespace utility {
27
28 template <typename RBT> using get_node_t = std::conditional_t<std::is_const<RBT>::value, typename RBT::node const, typename RBT::node>;
29
30 // flatten the tree in ascending order
31 template <typename RBT> std::vector<get_node_t<RBT>> flatten2(RBT &tree) {
32 using node_t = get_node_t<RBT>;
33 std::vector<node_t> R;
34 R.reserve(tree.size());
35 std::stack<node_t> stack;
36 node_t n = tree.get_root();
37 while (1) {
38 while (n != nullptr) {
39 stack.push(n);
40 n = n->left;
41 }
42 if (stack.size() == 0) break;
43 n = stack.top();
44 stack.pop();
45 R.push_back(n);
46 n = n->right;
47 }
48 return R;
49 }
50
51 template <typename RBT> std::vector<get_node_t<RBT>> flatten(RBT &tree) {
52 using node_t = get_node_t<RBT>;
53 std::vector<node_t> R;
54 R.reserve(tree.size());
55 foreach (tree, [&R](node_t n) { R.push_back(n); })
56 ;
57 return R;
58 }
59
61 namespace detail {
62
63 // forward iterator
64 template <typename RBT, typename Node> class rbt_iterator {
65
66 using iterator_category = std::forward_iterator_tag;
67 using value_type = Node;
68 using difference_type = std::ptrdiff_t;
69 using pointer = Node *;
70 using reference = Node &;
71
72 RBT *tree = nullptr;
73 Node n = nullptr;
74 Node current = nullptr;
75 std::stack<Node> stack;
76
77 public:
78 rbt_iterator() = default;
79 rbt_iterator(RBT *tree, bool at_end) : tree(tree), n(at_end ? nullptr : tree->get_root()) { operator++(); }
80
81 rbt_iterator &operator++() {
82 while (n != nullptr) {
83 stack.push(n);
84 n = n->left;
85 }
86 if (stack.size() != 0) {
87 n = stack.top();
88 stack.pop();
89 current = n;
90 n = n->right;
91 } else
92 current = nullptr;
93 return *this;
94 }
95
96 Node &operator*() { return current; }
97 Node &operator->() { return current; }
98
99 rbt_iterator operator++(int) {
100 auto c = *this;
101 operator++();
102 return c;
103 }
104
105 bool operator==(rbt_iterator const &other) const { return (other.current == current); }
106 bool operator!=(rbt_iterator const &other) const { return (!operator==(other)); }
107 };
108 }
109 }
110}
implementation of iterators