66 std::vector<Node> nodes;
67 std::vector<Vertex> free_list;
70 typedef Vertex vertex_descriptor;
71 typedef std::pair<vertex_descriptor, vertex_descriptor> edge_descriptor;
72 typedef disallow_parallel_edge_tag edge_parallel_category;
73 typedef std::size_t degree_size_type;
74 typedef std::size_t vertices_size_type;
76 BOOST_STATIC_CONSTEXPR
77 vertex_descriptor null_vertex()
79 return vertex_descriptor(-1);
86 std::size_t num_vertices()
const
88 BOOST_ASSERT(!free_list.empty());
89 BOOST_ASSERT(free_list[0] == nodes.size());
90 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
92 return nodes.size() - free_list.size() + 1;
95 Node const &operator[](vertex_descriptor u)
const
97 BOOST_ASSERT(!free_list.empty());
98 BOOST_ASSERT(free_list[0] == nodes.size());
99 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
100 BOOST_ASSERT(u < nodes.size());
101 BOOST_ASSERT(boost::find(free_list, u) == boost::end(free_list));
106 template <std::
size_t N>
bool has_successor(vertex_descriptor u)
const
108 BOOST_ASSERT(!free_list.empty());
109 BOOST_ASSERT(free_list[0] == nodes.size());
110 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
111 BOOST_ASSERT(u < nodes.size());
112 BOOST_ASSERT(boost::find(free_list, u) == boost::end(free_list));
114 return nodes[u].successors[N] != null_vertex();
119 free_list.push_back(0);
121 BOOST_ASSERT(!free_list.empty());
122 BOOST_ASSERT(free_list[0] == nodes.size());
127 class out_edge_iterator :
public boost::iterator_adaptor<out_edge_iterator, vertex_descriptor const *,
128 edge_descriptor, forward_traversal_tag, edge_descriptor>
130 vertex_descriptor
const *last;
131 vertex_descriptor source;
135 : out_edge_iterator::iterator_adaptor_(first), last(last), source(source)
137 BOOST_ASSERT(source != null_vertex());
142 edge_descriptor dereference()
const
144 return edge_descriptor(source, *this->base_reference());
147 void post_increment()
149 while (this->base_reference() != last && *this->base_reference() == null_vertex())
151 this->base_reference()++;
157 this->base_reference()++;
161 friend class boost::iterator_core_access;
164 friend vertex_descriptor source(edge_descriptor e,
binary_tree_base const &)
169 friend vertex_descriptor target(edge_descriptor e,
binary_tree_base const &)
174 friend std::pair<out_edge_iterator, out_edge_iterator> out_edges(vertex_descriptor u, binary_tree_base
const &g)
176 auto const &successors = g.nodes[u].successors;
178 return std::make_pair(out_edge_iterator(boost::begin(successors), boost::end(successors), u),
179 out_edge_iterator(boost::end(successors), boost::end(successors), u));
182 friend degree_size_type out_degree(vertex_descriptor v, binary_tree_base
const &g)
184 return 2 - count(g.nodes[v].successors, null_vertex());
189 struct vertex_iterator :
public iterator_facade<vertex_iterator, vertex_descriptor, multi_pass_input_iterator_tag,
190 vertex_descriptor const &>
192 typedef iterator_facade<
vertex_iterator, vertex_descriptor, multi_pass_input_iterator_tag,
193 vertex_descriptor
const &>
195 typedef typename super_t::value_type value_type;
196 typedef typename super_t::reference reference;
198 vertex_descriptor last;
199 std::stack<vertex_descriptor> traversal;
209 traversal.push(start);
210 while (has_left_successor(traversal.top(), g))
211 traversal.push(left_successor(traversal.top(), g));
215 friend class boost::iterator_core_access;
217 reference dereference()
const
219 return traversal.top();
224 if (has_right_successor(traversal.top(), *g))
226 if (right_successor(traversal.top(), *g) != last)
228 traversal.push(right_successor(traversal.top(), *g));
229 while (has_left_successor(traversal.top(), *g))
230 traversal.push(left_successor(traversal.top(), *g));
237 last = traversal.top();
239 }
while (!traversal.empty() &&
240 (!has_right_successor(traversal.top(), *g) || right_successor(traversal.top(), *g) == last));
245 BOOST_ASSERT(g == other.g);
247 if (traversal.empty())
248 return other.traversal.empty();
250 if (other.traversal.empty())
253 return traversal.top() == other.traversal.top();
259 return g.num_vertices();
262 friend std::pair<vertex_iterator, vertex_iterator> vertices(
binary_tree_base const &g)
264 if (g.num_vertices() == 0)
265 return std::make_pair(vertex_iterator(g), vertex_iterator(g));
266 auto const start = default_starting_vertex(g);
267 return std::make_pair(vertex_iterator(start, g), vertex_iterator(g));
272 friend vertex_descriptor add_vertex(binary_tree_base &g)
274 return g.add_vertex();
277 friend void remove_vertex(vertex_descriptor u, binary_tree_base &g)
282 friend bool has_left_successor(Vertex u, binary_tree_base
const &g)
284 return g.template has_successor<0>(u);
287 friend bool has_right_successor(Vertex u, binary_tree_base
const &g)
289 return g.template has_successor<1>(u);
292 friend Vertex left_successor(Vertex u, binary_tree_base
const &g)
294 return g.nodes[u].successors[0];
297 friend Vertex right_successor(Vertex u, binary_tree_base
const &g)
299 return g.nodes[u].successors[1];
311 nodes.shrink_to_fit();
312 free_list.shrink_to_fit();
315 friend Vertex default_starting_vertex(binary_tree_base
const &g)
318 if (g.free_list.size() != 1)
320 auto const not_successors = [](
auto x,
auto y) {
return ++x != y; };
321 auto const q = boost::adjacent_find(adaptors::reverse(g.free_list), not_successors);
333 std::pair<edge_descriptor, bool> add_edge(vertex_descriptor u, vertex_descriptor v)
335 BOOST_ASSERT(u != v);
337 BOOST_ASSERT(!free_list.empty());
338 BOOST_ASSERT(free_list[0] == nodes.size());
339 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
343 auto const result = add_edge_strict(u, v);
344 BOOST_ASSERT(!free_list.empty());
345 BOOST_ASSERT(free_list[0] == nodes.size());
346 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
351 std::pair<edge_descriptor, bool> add_edge_strict(vertex_descriptor u, vertex_descriptor v)
353 BOOST_ASSERT(u != v);
354 BOOST_ASSERT(u < nodes.size());
355 BOOST_ASSERT(v < nodes.size());
356 BOOST_ASSERT(find(free_list, u) == find(free_list, v));
358 BOOST_ASSERT(!free_list.empty());
359 BOOST_ASSERT(free_list[0] == nodes.size());
360 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
362 array<vertex_descriptor, 2>
const keys{{null_vertex(), v}};
363 auto const p = find_first_of(nodes[u].successors, keys);
364 edge_descriptor
const result(u, v);
366 if (p == boost::end(nodes[u].successors) or *p == v)
367 return std::make_pair(result,
false);
371 return std::make_pair(result,
true);
375 void remove_edge(vertex_descriptor u, vertex_descriptor v)
377 BOOST_ASSERT(u != v);
378 BOOST_ASSERT(u < nodes.size() && v < nodes.size());
379 BOOST_ASSERT(find(free_list, u) == find(free_list, v));
381 BOOST_ASSERT(!free_list.empty());
382 BOOST_ASSERT(free_list[0] == nodes.size());
383 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
385 auto const p = find(nodes[u].successors, v);
386 BOOST_ASSERT(p != boost::end(nodes[u].successors));
390 vertex_descriptor add_vertex()
392 BOOST_ASSERT(!free_list.empty());
393 BOOST_ASSERT(free_list[0] == nodes.size());
394 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
395 BOOST_ASSERT(nodes.size() >= free_list.back() + 1 || free_list.size() == 1);
397 vertex_descriptor
const result = free_list.back();
398 if (free_list.size() == 1)
400 nodes.resize(result + 1);
401 free_list.back() = nodes.size();
404 free_list.pop_back();
405 BOOST_ASSERT(!free_list.empty());
406 BOOST_ASSERT(free_list[0] == nodes.size());
407 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
412 bool add_vertex(vertex_descriptor u)
414 BOOST_ASSERT(!free_list.empty());
415 BOOST_ASSERT(free_list[0] == nodes.size());
416 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
419 if (nodes.size() < u)
421 free_list.reserve(free_list.size() + u - nodes.size());
422 for (
auto i = u - 1; i != nodes.size() - 1; i--)
423 free_list.push_back(i);
425 free_list[0] = nodes.size();
426 BOOST_ASSERT(!free_list.empty());
427 BOOST_ASSERT(free_list[0] == nodes.size());
431 auto const which = find(free_list, u);
432 if (which == boost::begin(free_list))
435 nodes.resize(*which);
439 if (which == boost::end(free_list))
441 free_list.erase(which);
444 BOOST_ASSERT(!free_list.empty());
445 BOOST_ASSERT(free_list[0] == nodes.size());
446 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
450 void remove_vertex(vertex_descriptor u)
452 BOOST_ASSERT(u || nodes.size() == 1);
454 BOOST_ASSERT(num_vertices() > 0);
455 BOOST_ASSERT(!free_list.empty());
456 BOOST_ASSERT(free_list[0] == nodes.size());
457 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
458 BOOST_ASSERT(find(free_list, u) == boost::end(free_list));
459 BOOST_ASSERT(out_degree(u, *
this) == 0);
461 if (u == nodes.size() - 1)
464 if (free_list.size() == 1)
473 auto const not_successors = [](
auto x,
auto y) {
return x != ++y; };
474 auto const least = boost::adjacent_find(free_list, not_successors);
475 auto const n = least - boost::begin(free_list);
476 nodes.erase(boost::end(nodes) - n, boost::end(nodes));
477 free_list.erase(boost::begin(free_list), least);
482 auto const here = boost::lower_bound(free_list, u, std::greater<>());
483 free_list.insert(here, u);
486 BOOST_ASSERT(find(free_list, u) != boost::end(free_list));
487 BOOST_ASSERT(!free_list.empty());
488 BOOST_ASSERT(free_list[0] == nodes.size());
489 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
492 void clear_vertex(vertex_descriptor u)
494 BOOST_ASSERT(num_vertices() > 0);
495 BOOST_ASSERT(!free_list.empty());
496 BOOST_ASSERT(free_list[0] == nodes.size());
497 BOOST_ASSERT(free_list[0] == nodes.size());
498 BOOST_ASSERT(find(free_list, u) == boost::end(free_list));
500 boost::fill(nodes[u].successors, null_vertex());
507 edge_descriptor add_left_edge(vertex_descriptor parent, vertex_descriptor child)
509 BOOST_ASSERT(parent != child);
510 BOOST_ASSERT(parent < nodes.size());
511 BOOST_ASSERT(child < nodes.size());
512 BOOST_ASSERT(find(free_list, parent) == find(free_list, child));
514 BOOST_ASSERT(!free_list.empty());
515 BOOST_ASSERT(free_list[0] == nodes.size());
516 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
518 BOOST_ASSERT(!has_left_successor(parent, *
this));
520 nodes[parent].successors[0] = child;
522 BOOST_ASSERT(has_left_successor(parent, *
this));
523 BOOST_ASSERT(left_successor(parent, *
this) == child);
525 return {parent, child};
528 edge_descriptor add_right_edge(vertex_descriptor parent, vertex_descriptor child)
530 BOOST_ASSERT(parent != child);
531 BOOST_ASSERT(parent < nodes.size());
532 BOOST_ASSERT(child < nodes.size());
533 BOOST_ASSERT(find(free_list, parent) == find(free_list, child));
535 BOOST_ASSERT(!free_list.empty());
536 BOOST_ASSERT(free_list[0] == nodes.size());
537 BOOST_ASSERT(boost::is_sorted(free_list, std::greater<>()));
539 BOOST_ASSERT(!has_right_successor(parent, *
this));
541 nodes[parent].successors[1] = child;
543 BOOST_ASSERT(has_right_successor(parent, *
this));
544 BOOST_ASSERT(right_successor(parent, *
this) == child);
546 return {parent, child};