8#ifndef ADOBE_FOREST_HPP
9#define ADOBE_FOREST_HPP
18#include <boost/iterator/iterator_facade.hpp>
19#include <boost/range.hpp>
83 return !i.equal_node(std::next(
leading_of(i)));
97 friend class boost::iterator_core_access;
100 pivot(this->base_reference());
101 ++this->base_reference();
104 --this->base_reference();
105 pivot(this->base_reference());
113 while (x.edge() != edge)
120 while (x.edge() != edge)
127template <
typename I, std::
size_t Edge>
128class edge_iterator :
public boost::iterator_adaptor<edge_iterator<I, Edge>, I> {
132 template <
typename U>
136 friend class boost::iterator_core_access;
138 void increment() { this->base_reference() =
find_edge(std::next(this->base()), Edge); }
140 void decrement() { this->base_reference() =
find_edge_reverse(std::prev(this->base()), Edge); }
155 :
public boost::iterator_adaptor<filter_fullorder_iterator<I, P>, I> {
161 first_m(f), last_m(l), predicate_m(p) {}
165 first_m(f), last_m(l) {}
167 template <
typename U>
170 first_m(x.first_m), last_m(x.last_m), predicate_m(x.predicate_m) {}
174 std::size_t
edge()
const {
return this->base().edge(); }
175 std::size_t&
edge() {
return this->base_reference().edge(); }
178 return this->base().equal_node(y.base());
193 i = skip_forward(i, last_m, predicate_m);
194 this->base_reference() = i;
197 static I skip_forward(I f, I l, P p)
207 static I skip_backward(I f, I l, P p)
226 i = skip_backward(first_m, i, predicate_m);
227 this->base_reference() = i;
252 :
public boost::iterator_facade<
253 reverse_fullorder_iterator<I>, typename boost::iterator_value<I>::type,
254 std::bidirectional_iterator_tag, typename boost::iterator_reference<I>::type> {
255 typedef typename boost::iterator_facade<
257 std::bidirectional_iterator_tag,
typename boost::iterator_reference<I>::type>
267 template <
typename U>
269 : base_m(x.
base()), edge_m(x.
edge()) {}
273 std::size_t
edge()
const {
return edge_m; }
274 std::size_t&
edge() {
return edge_m; }
277 return base_m.equal_node(y.base_m);
281 friend class boost::iterator_core_access;
293 reference dereference()
const {
return *base_m; }
296 return (base_m == y.base_m) && (edge_m == y.edge_m);
308 typedef typename boost::iterator_adaptor<depth_fullorder_iterator<I>, I>
::difference_type
314 template <
typename U>
319 std::size_t
edge()
const {
return this->base().edge(); }
320 std::size_t&
edge() {
return this->base_reference().edge(); }
322 return this->base().equal_node(y.base());
329 std::size_t old_edge(
edge());
330 ++this->base_reference();
331 if (old_edge ==
edge())
335 std::size_t old_edge(
edge());
336 --this->base_reference();
337 if (old_edge ==
edge())
346template <
typename Forest>
353#if !defined(ADOBE_NO_DOCUMENTATION)
354namespace implementation {
358 enum next_prior_t { prior_s, next_s };
361 typedef node_ptr& reference;
363 node_ptr& link(std::size_t edge, next_prior_t link) {
return nodes_m[edge][std::size_t(link)]; }
365 node_ptr link(std::size_t edge, next_prior_t link)
const {
366 return nodes_m[edge][std::size_t(link)];
370 node_ptr nodes_m[2][2] = {
371 {
static_cast<node_ptr
>(
this),
static_cast<node_ptr
>(
this) },
372 {
static_cast<node_ptr
>(
this),
static_cast<node_ptr
>(
this) }
375 node_ptr nodes_m[2][2];
378 : nodes_m{{
static_cast<node_ptr
>(
this),
static_cast<node_ptr
>(
this)},
379 {
static_cast<node_ptr
>(
this),
static_cast<node_ptr
>(
this)}} {}
384struct node :
public node_base<node<T>> {
385 typedef T value_type;
387 explicit node(
const value_type& data) : data_m(data) {}
395class forest_const_iterator;
399 :
public boost::iterator_facade<forest_iterator<T>, T, std::bidirectional_iterator_tag> {
400 typedef boost::iterator_facade<forest_iterator<T>, T, std::bidirectional_iterator_tag>
404 typedef typename inherited_t::reference reference;
405 typedef typename inherited_t::difference_type difference_type;
406 typedef typename inherited_t::value_type value_type;
410 forest_iterator(
const forest_iterator& x) : node_m(x.node_m), edge_m(x.edge_m) {}
412 std::size_t edge()
const {
return edge_m; }
413 std::size_t& edge() {
return edge_m; }
414 bool equal_node(forest_iterator
const& y)
const {
return node_m == y.node_m; }
417 friend class adobe::forest<value_type>;
418 friend class boost::iterator_core_access;
420 friend class forest_iterator;
422 friend class forest_const_iterator;
423 friend struct unsafe::set_next_fn<forest_iterator>;
425 typedef node<T> node_t;
427 reference dereference()
const {
return node_m->data_m; }
430 node_t* next(node_m->link(edge_m, node_t::next_s));
433 edge_m = std::size_t(next != node_m);
435 edge_m = std::size_t(next->link(forest_leading_edge, node_t::prior_s) == node_m);
441 node_t* next(node_m->link(edge_m, node_t::prior_s));
444 edge_m = std::size_t(next->link(forest_trailing_edge, node_t::next_s) != node_m);
446 edge_m = std::size_t(next == node_m);
451 bool equal(
const forest_iterator& y)
const {
452 return (node_m == y.node_m) && (edge_m == y.edge_m);
458 forest_iterator(node_t* node, std::size_t edge) : node_m(node), edge_m(edge) {}
465class forest_const_iterator :
public boost::iterator_facade<forest_const_iterator<T>, const T,
466 std::bidirectional_iterator_tag> {
467 typedef boost::iterator_facade<forest_const_iterator<T>,
const T,
468 std::bidirectional_iterator_tag>
472 typedef typename inherited_t::reference reference;
473 typedef typename inherited_t::difference_type difference_type;
474 typedef typename inherited_t::value_type value_type;
478 forest_const_iterator(
const forest_const_iterator& x) : node_m(x.node_m), edge_m(x.edge_m) {}
480 forest_const_iterator(
const forest_iterator<T>& x) : node_m(x.node_m), edge_m(x.edge_m) {}
482 std::size_t edge()
const {
return edge_m; }
483 std::size_t& edge() {
return edge_m; }
484 bool equal_node(forest_const_iterator
const& y)
const {
return node_m == y.node_m; }
487 friend class adobe::forest<value_type>;
488 friend class boost::iterator_core_access;
490 friend class forest_const_iterator;
491 friend struct unsafe::set_next_fn<forest_const_iterator>;
493 typedef const node<T> node_t;
495 reference dereference()
const {
return node_m->data_m; }
498 node_t* next(node_m->link(edge_m, node_t::next_s));
501 edge_m = std::size_t(next != node_m);
503 edge_m = std::size_t(next->link(forest_leading_edge, node_t::prior_s) == node_m);
509 node_t* next(node_m->link(edge_m, node_t::prior_s));
512 edge_m = std::size_t(next->link(forest_trailing_edge, node_t::next_s) != node_m);
514 edge_m = std::size_t(next == node_m);
519 bool equal(
const forest_const_iterator& y)
const {
520 return (node_m == y.node_m) && (edge_m == y.edge_m);
526 forest_const_iterator(node_t* node, std::size_t edge) : node_m(node), edge_m(edge) {}
540struct set_next_fn<implementation::forest_iterator<T>> {
541 void operator()(implementation::forest_iterator<T> x,
542 implementation::forest_iterator<T> y)
const {
543 typedef typename implementation::node<T> node_t;
545 x.node_m->link(x.edge(), node_t::next_s) = y.node_m;
546 y.node_m->link(y.edge(), node_t::prior_s) = x.node_m;
557 typedef implementation::node<T> node_t;
564 typedef implementation::forest_iterator<T>
iterator;
587#if !defined(ADOBE_NO_DOCUMENTATION)
595 *
this = std::move(tmp);
607 size_type
size()
const;
649 iterator
erase(
const iterator& position);
650 iterator
erase(
const iterator& first,
const iterator& last);
653 iterator result(
new node_t(std::move(x)),
true);
675 iterator insert(iterator position, const_child_iterator first, const_child_iterator last);
677 iterator splice(iterator position,
forest<T>& x);
678 iterator splice(iterator position,
forest<T>& x, iterator i);
687#if !defined(ADOBE_NO_DOCUMENTATION)
689 friend class implementation::forest_iterator<
value_type>;
690 friend class implementation::forest_const_iterator<
value_type>;
694 implementation::node_base<node_t> tail_m;
696 node_t* tail() {
return static_cast<node_t*
>(&tail_m); }
697 const node_t* tail()
const {
return static_cast<const node_t*
>(&tail_m); }
709 first != last; ++first, ++pos) {
710 if (first.edge() != pos.edge())
712 if (first.edge() && (*first != *pos))
741#if !defined(ADOBE_NO_DOCUMENTATION)
774 size_m =
size_type(std::distance(first, last));
787 while (position != last) {
793 position =
erase(position);
796 stack_depth = std::max<difference_type>(0, stack_depth - 1);
827 delete position.node_m;
829 return position.edge() ? std::next(leading_prior) : trailing_next;
853 for (
const_iterator first(f.base()), last(l.base()); first != last; ++first, ++pos) {
855 pos =
insert(pos, *first);
866 if (first == last || first.base() == pos)
896 return splice(pos, x, first, last, 0);
937template <
typename Forest>
969auto child_range(
const I& x) -> boost::iterator_range<child_iterator<I>> {
990template <
typename R,
typename P>
995 return {
iterator(std::begin(x), std::end(x), p),
iterator(std::end(x), std::end(x), p)};
1008template <
typename R,
typename P>
1013 return {
iterator(std::begin(x), std::end(x), p),
iterator(std::end(x), std::end(x), p)};
1038template <
typename R>
1040 -> boost::iterator_range<reverse_fullorder_iterator<typename boost::range_iterator<R>::type>> {
1055template <
typename R>
1056inline boost::iterator_range<
1076template <
typename R>
1077inline boost::iterator_range<depth_fullorder_iterator<typename boost::range_iterator<R>::type>>
1093template <
typename R>
1094inline boost::iterator_range<
1113template <
typename R>
1114inline boost::iterator_range<
1131template <
typename R>
1132inline boost::iterator_range<
1152template <
typename R>
1153inline boost::iterator_range<
1170template <
typename R>
1171inline boost::iterator_range<
1197template <
typename SourceForestIterType,
typename DestForestType,
typename UnaryFunction>
1199 DestForestType& destForest,
typename DestForestType::iterator destIter,
1200 UnaryFunction transformFunc) {
1202 std::stack<typename DestForestType::iterator> insertionIterStack;
1203 insertionIterStack.push(destIter);
1205 while (first != last) {
1208 destForest.insert(!insertionIterStack.empty() ? insertionIterStack.top() : destIter,
1209 transformFunc(*first));
1210 insertionIterStack.push(
trailing_of(insertedIter));
1212 if (!insertionIterStack.empty())
1213 insertionIterStack.pop();
1232template <
typename SourceForestIterType,
typename DestForestType,
typename UnaryFunction>
1234 DestForestType& destForest, UnaryFunction transformFunc) {
1235 transform_forest(first, last, destForest, destForest.end(), transformFunc);
1252template <
typename SourceForestType,
typename DestForestType,
typename UnaryFunction>
1254 typename DestForestType::iterator destIter, UnaryFunction transformFunc) {
1255 transform_forest(sourceForest.begin(), sourceForest.end(), destForest, destIter, transformFunc);
1271template <
typename SourceForestType,
typename DestForestType,
typename UnaryFunction>
1273 UnaryFunction transformFunc) {
1274 transform_forest(sourceForest.begin(), sourceForest.end(), destForest, destForest.end(),
Forest::child_iterator iterator
Forest::iterator iterator_type
void push_back(const value_type &x)
void push_front(const value_type &x)
Forest::difference_type difference_type
Forest::value_type value_type
child_adaptor(forest_type &f, iterator_type &i)
Forest::reference reference
Forest::const_reference const_reference
An iterator used to traverse the children of a specific node in a forest.
child_iterator(const child_iterator< U > &u)
depth_fullorder_iterator(I x, difference_type d=0)
difference_type depth() const
depth_fullorder_iterator(const depth_fullorder_iterator< U > &x)
depth_fullorder_iterator(difference_type d=0)
friend class boost::iterator_core_access
boost::iterator_adaptor< depth_fullorder_iterator< I >, I >::difference_type difference_type
bool equal_node(depth_fullorder_iterator const &y) const
An iterator used to traverse a specific edge type within a forest.
edge_iterator(const edge_iterator< U, Edge > &u)
filter_fullorder_iterator(const filter_fullorder_iterator< U, P > &x)
filter_fullorder_iterator(I f, I l, P p)
filter_fullorder_iterator()
friend class boost::iterator_core_access
filter_fullorder_iterator(I f, I l)
bool equal_node(const filter_fullorder_iterator &y) const
A homogeneous hierarchical structure class.
const_reverse_iterator rend() const
iterator splice(iterator position, forest< T > &x)
const_reference front() const
iterator insert_parent(child_iterator front, child_iterator back, const T &x)
boost::iterator_range< depth_fullorder_iterator< typename boost::range_iterator< R >::type > > depth_range(R &x)
const_iterator begin() const
edge_iterator< iterator, forest_trailing_edge > postorder_iterator
void transform_forest(SourceForestType sourceForest, DestForestType &destForest, UnaryFunction transformFunc)
const_iterator root() const
void transform_forest(SourceForestType sourceForest, DestForestType &destForest, typename DestForestType::iterator destIter, UnaryFunction transformFunc)
adobe::child_iterator< iterator > child_iterator
adobe::child_iterator< const_iterator > const_child_iterator
boost::iterator_range< edge_iterator< typename boost::range_const_iterator< R >::type, forest_leading_edge > > preorder_range(const R &x)
boost::iterator_range< edge_iterator< typename boost::range_iterator< R >::type, forest_leading_edge > > preorder_range(R &x)
const_reference back() const
auto filter_fullorder_range(const R &x, P p) -> boost::iterator_range< filter_fullorder_iterator< typename boost::range_const_iterator< R >::type, P > >
std::reverse_iterator< child_iterator > reverse_child_iterator
boost::iterator_range< edge_iterator< typename boost::range_iterator< R >::type, forest_trailing_edge > > postorder_range(R &x)
boost::iterator_range< reverse_fullorder_iterator< typename boost::range_const_iterator< R >::type > > reverse_fullorder_range(const R &x)
void push_back(const T &x)
reverse_fullorder_iterator< iterator > reverse_iterator
edge_iterator< const_iterator, forest_trailing_edge > const_postorder_iterator
size_type max_size() const
edge_iterator< const_iterator, forest_leading_edge > const_preorder_iterator
void reverse(child_iterator first, child_iterator last)
reverse_fullorder_iterator< const_iterator > const_reverse_iterator
iterator erase(const iterator &position)
void push_front(const T &x)
edge_iterator< iterator, forest_leading_edge > preorder_iterator
forest & operator=(forest &&x) noexcept
implementation::forest_iterator< T > iterator
const_iterator end() const
reverse_iterator rbegin()
iterator insert(const iterator &position, T x)
std::ptrdiff_t difference_type
boost::iterator_range< depth_fullorder_iterator< typename boost::range_const_iterator< R >::type > > depth_range(const R &x)
implementation::forest_const_iterator< T > const_iterator
boost::iterator_range< edge_iterator< typename boost::range_const_iterator< R >::type, forest_trailing_edge > > postorder_range(const R &x)
void transform_forest(SourceForestIterType first, SourceForestIterType last, DestForestType &destForest, UnaryFunction transformFunc)
auto filter_fullorder_range(R &x, P p) -> boost::iterator_range< filter_fullorder_iterator< typename boost::range_iterator< R >::type, P > >
const_reverse_iterator rbegin() const
auto reverse_fullorder_range(R &x) -> boost::iterator_range< reverse_fullorder_iterator< typename boost::range_iterator< R >::type > >
void transform_forest(SourceForestIterType first, SourceForestIterType last, DestForestType &destForest, typename DestForestType::iterator destIter, UnaryFunction transformFunc)
const T & const_reference
reverse_fullorder_iterator(const reverse_fullorder_iterator< U > &x)
iterator_type base() const
inherited_t::reference reference
reverse_fullorder_iterator(I x)
reverse_fullorder_iterator()
bool equal_node(const reverse_fullorder_iterator &y) const
boost::range_difference< InputRange >::type count(InputRange &range, T &value)
count implementation
bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred)
T::iterator erase(T &x, typename T::iterator f, typename T::iterator l)
I reverse_nodes(I first, I last)
boost::range_size< Selection >::type size(const Selection &x)
void swap(any_regular_t &x, any_regular_t &y)
bool operator==(const any_regular_t &x, const any_regular_t &y)
child_iterator< I > child_begin(const I &x)
I find_edge_reverse(I x, std::size_t edge)
child_iterator< I > child_end(const I &x)
bool has_children(const I &i)
auto child_range(const I &x) -> boost::iterator_range< child_iterator< I > >
bool operator!=(const forest< T > &x, const forest< T > &y)
I find_edge(I x, std::size_t edge)
void swap(adobe::extents_t::slice_t &x, adobe::extents_t::slice_t &y) BOOST_NOEXCEPT
void operator()(child_iterator< I > x, child_iterator< I > y)