stlab 2.3.0
Modern, modular C++ algorithms, data structures, and concurrency primitives
Loading...
Searching...
No Matches
forest_algorithms.hpp
Go to the documentation of this file.
1/**************************************************************************************************/
2
3#ifndef STLAB_FOREST_ALGORITHMS_HPP
4#define STLAB_FOREST_ALGORITHMS_HPP
5
15
16/**************************************************************************************************/
17
18// stdc++
19#include <optional>
20
21// stlab
22#include <stlab/forest.hpp>
23
24/**************************************************************************************************/
25
26namespace stlab::forests {
27
36
37/**************************************************************************************************/
38
44template <class Forest1, class Forest2>
45auto equal_shape(const Forest1& x, const Forest2& y) -> bool {
46 if (x.size_valid() && y.size_valid() && x.size() != y.size()) return false;
47 auto pos{y.begin()};
48 for (auto first(x.begin()), last(x.end()); first != last; ++first, ++pos) {
49 if (first.edge() != pos.edge()) return false;
50 }
51 return true;
52}
53
54/**************************************************************************************************/
55
61template <class Container>
62struct transcribe_iterator {
63 using iterator_category = std::output_iterator_tag;
64 using value_type = void;
65 using difference_type = void;
66 using pointer = void;
67 using reference = void;
68 using container_type = Container;
69
70 transcribe_iterator(Container& c, const typename Container::iterator& i) : _c{&c}, _i{i} {}
71
72 constexpr auto operator*() -> auto& { return *this; }
73 constexpr auto operator++() -> auto& {
74 ++_i;
75 return *this;
76 }
77 constexpr auto operator++(int) -> auto {
78 auto result{*this};
79 ++_i;
80 return result;
81 }
82
83 constexpr auto operator=(const typename Container::value_type& value) -> auto& {
84 _i = _c->insert(_i, value);
85 return *this;
86 }
87
88 constexpr auto operator=(typename Container::value_type&& value) -> auto& {
89 _i = _c->insert(_i, std::move(value));
90 return *this;
91 }
92
93 constexpr auto trailing() { _i = trailing_of(_i); }
94
95private:
96 Container* _c;
97 typename Container::iterator _i;
98};
99
101template <class Container>
102auto transcriber(Container& c) {
103 return transcribe_iterator<Container>(c, c.begin());
104}
105
106/**************************************************************************************************/
107
110template <class I, class O, class P, class UP>
111auto transcribe(I first, const I& last, O out, P proj, UP pred) {
112 for (; first != last; ++first, ++out) {
113 if (pred(first)) {
114 out = proj(*first);
115 } else {
116 out.trailing();
117 }
118 }
119 return out;
120}
121
123template <class R, class O, class P, class UP>
124auto transcribe(const R& range, O out, P proj, UP pred) {
125 return transcribe(std::cbegin(range), std::cend(range), std::move(out), std::move(proj),
126 std::move(pred));
127}
128
130template <class I, class O, class P>
131auto transcribe(const I& first, const I& last, O out, P proj) {
132 return transcribe(first, last, std::move(out), std::move(proj),
133 [](const auto& p) { return is_leading(p); });
134}
135
137template <class R, class O, class P>
138auto transcribe(const R& range, O out, P proj) {
139 return transcribe(std::cbegin(range), std::cend(range), std::move(out), std::move(proj));
140}
141
142/**************************************************************************************************/
143
148template <class I, // models ForestFullorderIterator
149 class O> // models OutputIterator
150auto flatten(I first, const I& last, O out) {
151 for (; first != last; ++first) {
152 if (is_leading(first)) {
153 *out++ = *first;
154 } else {
155 *out++ = std::nullopt;
156 }
157 }
158 return out;
159}
160
161/**************************************************************************************************/
162
164template <class I, // I models ForwardIterator; I::value_type == std::optional<T>
165 class F> // F models Forest
166auto unflatten(I first, I last, F& f) {
167 return forests::transcribe(
168 first, last, transcriber(f), [](const auto& x) { return *x; },
169 [](const auto& p) { return *p; });
170}
171
172/**************************************************************************************************/
173
175
176} // namespace stlab::forests
177
178/**************************************************************************************************/
179
180#endif // STLAB_FOREST_ALGORITHMS_HPP
181
182/**************************************************************************************************/
Forest (tree-of-sequences) iterators, ranges, and algorithms.
auto unflatten(I first, I last, F &f)
Rebuilds forest f from a flattened std::optional sequence (inverse of flatten).
Definition forest_algorithms.hpp:166
auto equal_shape(const Forest1 &x, const Forest2 &y) -> bool
Returns true if x and y have the same full-order edge sequence (values may differ).
Definition forest_algorithms.hpp:45
auto flatten(I first, const I &last, O out)
Writes each leading node's value to out; writes std::nullopt at trailing edges.
Definition forest_algorithms.hpp:150
auto transcriber(Container &c)
Returns a transcribe_iterator starting at c.begin() for building c from a walk.
Definition forest_algorithms.hpp:102
auto transcribe(I first, const I &last, O out, P proj, UP pred)
Walks [first, last); for positions where pred is true, assigns proj(*first) to out,...
Definition forest_algorithms.hpp:111
auto trailing_of(I i)
Positions i on the trailing edge of the same node.
Definition forest.hpp:94
constexpr auto is_leading(forest_edge e)
True if e is a leading-edge position.
Definition forest.hpp:102
Definition forest_algorithms.hpp:26
Output iterator that inserts projected values into a forest (or similar container).
Definition forest_algorithms.hpp:62