annotate DEPENDENCIES/generic/include/boost/heap/detail/tree_iterator.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // boost heap: node tree iterator helper classes
Chris@16 2 //
Chris@16 3 // Copyright (C) 2010 Tim Blechmann
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8
Chris@16 9 // Disclaimer: Not a Boost library.
Chris@16 10
Chris@16 11 #ifndef BOOST_HEAP_DETAIL_TREE_ITERATOR_HPP
Chris@16 12 #define BOOST_HEAP_DETAIL_TREE_ITERATOR_HPP
Chris@16 13
Chris@16 14 #include <functional>
Chris@16 15 #include <vector>
Chris@16 16
Chris@16 17 #include <boost/iterator/iterator_adaptor.hpp>
Chris@16 18 #include <queue>
Chris@16 19
Chris@16 20 namespace boost {
Chris@16 21 namespace heap {
Chris@16 22 namespace detail {
Chris@16 23
Chris@16 24
Chris@16 25 template<typename type>
Chris@16 26 struct identity:
Chris@16 27 public std::unary_function<type,type>
Chris@16 28 {
Chris@16 29 type& operator()(type& x) const
Chris@16 30 { return x; }
Chris@16 31
Chris@16 32 const type& operator()(const type& x) const
Chris@16 33 { return x; }
Chris@16 34 };
Chris@16 35
Chris@16 36 template<typename type>
Chris@16 37 struct caster:
Chris@16 38 public std::unary_function<type,type>
Chris@16 39 {
Chris@16 40 template <typename U>
Chris@16 41 type& operator()(U& x) const
Chris@16 42 { return static_cast<type&>(x); }
Chris@16 43
Chris@16 44 template <typename U>
Chris@16 45 const type& operator()(const U& x) const
Chris@16 46 { return static_cast<const type&>(x); }
Chris@16 47 };
Chris@16 48
Chris@16 49 template<typename Node>
Chris@16 50 struct dereferencer
Chris@16 51 {
Chris@16 52 template <typename Iterator>
Chris@16 53 Node * operator()(Iterator const & it)
Chris@16 54 {
Chris@16 55 return static_cast<Node *>(*it);
Chris@16 56 }
Chris@16 57 };
Chris@16 58
Chris@16 59 template<typename Node>
Chris@16 60 struct pointer_to_reference
Chris@16 61 {
Chris@16 62 template <typename Iterator>
Chris@16 63 const Node * operator()(Iterator const & it)
Chris@16 64 {
Chris@16 65 return static_cast<const Node *>(&*it);
Chris@16 66 }
Chris@16 67 };
Chris@16 68
Chris@16 69
Chris@16 70 template <typename HandleType,
Chris@16 71 typename Alloc,
Chris@16 72 typename ValueCompare
Chris@16 73 >
Chris@16 74 struct unordered_tree_iterator_storage
Chris@16 75 {
Chris@16 76 unordered_tree_iterator_storage(ValueCompare const & cmp)
Chris@16 77 {}
Chris@16 78
Chris@16 79 void push(HandleType h)
Chris@16 80 {
Chris@16 81 data_.push_back(h);
Chris@16 82 }
Chris@16 83
Chris@16 84 HandleType const & top(void)
Chris@16 85 {
Chris@16 86 return data_.back();
Chris@16 87 }
Chris@16 88
Chris@16 89 void pop(void)
Chris@16 90 {
Chris@16 91 data_.pop_back();
Chris@16 92 }
Chris@16 93
Chris@16 94 bool empty(void) const
Chris@16 95 {
Chris@16 96 return data_.empty();
Chris@16 97 }
Chris@16 98
Chris@16 99 std::vector<HandleType, typename Alloc::template rebind<HandleType>::other > data_;
Chris@16 100 };
Chris@16 101
Chris@16 102 template <typename ValueType,
Chris@16 103 typename HandleType,
Chris@16 104 typename Alloc,
Chris@16 105 typename ValueCompare,
Chris@16 106 typename ValueExtractor
Chris@16 107 >
Chris@16 108 struct ordered_tree_iterator_storage:
Chris@16 109 ValueExtractor
Chris@16 110 {
Chris@16 111 struct compare_values_by_handle:
Chris@16 112 ValueExtractor,
Chris@16 113 ValueCompare
Chris@16 114 {
Chris@16 115 compare_values_by_handle(ValueCompare const & cmp):
Chris@16 116 ValueCompare(cmp)
Chris@16 117 {}
Chris@16 118
Chris@16 119 bool operator()(HandleType const & lhs, HandleType const & rhs) const
Chris@16 120 {
Chris@16 121 ValueType const & lhs_value = ValueExtractor::operator()(lhs->value);
Chris@16 122 ValueType const & rhs_value = ValueExtractor::operator()(rhs->value);
Chris@16 123 return ValueCompare::operator()(lhs_value, rhs_value);
Chris@16 124 }
Chris@16 125 };
Chris@16 126
Chris@16 127 ordered_tree_iterator_storage(ValueCompare const & cmp):
Chris@16 128 data_(compare_values_by_handle(cmp))
Chris@16 129 {}
Chris@16 130
Chris@16 131 void push(HandleType h)
Chris@16 132 {
Chris@16 133 data_.push(h);
Chris@16 134 }
Chris@16 135
Chris@16 136 void pop(void)
Chris@16 137 {
Chris@16 138 data_.pop();
Chris@16 139 }
Chris@16 140
Chris@16 141 HandleType const & top(void)
Chris@16 142 {
Chris@16 143 return data_.top();
Chris@16 144 }
Chris@16 145
Chris@16 146 bool empty(void) const
Chris@16 147 {
Chris@16 148 return data_.empty();
Chris@16 149 }
Chris@16 150
Chris@16 151 std::priority_queue<HandleType,
Chris@16 152 std::vector<HandleType, typename Alloc::template rebind<HandleType>::other>,
Chris@16 153 compare_values_by_handle> data_;
Chris@16 154 };
Chris@16 155
Chris@16 156
Chris@16 157 /* tree iterator helper class
Chris@16 158 *
Chris@16 159 * Requirements:
Chris@16 160 * Node provides child_iterator
Chris@16 161 * ValueExtractor can convert Node->value to ValueType
Chris@16 162 *
Chris@16 163 * */
Chris@16 164 template <typename Node,
Chris@16 165 typename ValueType,
Chris@16 166 typename Alloc = std::allocator<Node>,
Chris@16 167 typename ValueExtractor = identity<typename Node::value_type>,
Chris@16 168 typename PointerExtractor = dereferencer<Node>,
Chris@16 169 bool check_null_pointer = false,
Chris@16 170 bool ordered_iterator = false,
Chris@16 171 typename ValueCompare = std::less<ValueType>
Chris@16 172 >
Chris@16 173 class tree_iterator:
Chris@16 174 public boost::iterator_adaptor<tree_iterator<Node,
Chris@16 175 ValueType,
Chris@16 176 Alloc,
Chris@16 177 ValueExtractor,
Chris@16 178 PointerExtractor,
Chris@16 179 check_null_pointer,
Chris@16 180 ordered_iterator,
Chris@16 181 ValueCompare
Chris@16 182 >,
Chris@16 183 const Node *,
Chris@16 184 ValueType,
Chris@16 185 boost::forward_traversal_tag
Chris@16 186 >,
Chris@16 187 ValueExtractor,
Chris@16 188 PointerExtractor
Chris@16 189 {
Chris@16 190 typedef boost::iterator_adaptor<tree_iterator<Node,
Chris@16 191 ValueType,
Chris@16 192 Alloc,
Chris@16 193 ValueExtractor,
Chris@16 194 PointerExtractor,
Chris@16 195 check_null_pointer,
Chris@16 196 ordered_iterator,
Chris@16 197 ValueCompare
Chris@16 198 >,
Chris@16 199 const Node *,
Chris@16 200 ValueType,
Chris@16 201 boost::forward_traversal_tag
Chris@16 202 > adaptor_type;
Chris@16 203
Chris@16 204 friend class boost::iterator_core_access;
Chris@16 205
Chris@16 206 typedef typename boost::mpl::if_c< ordered_iterator,
Chris@16 207 ordered_tree_iterator_storage<ValueType, const Node*, Alloc, ValueCompare, ValueExtractor>,
Chris@16 208 unordered_tree_iterator_storage<const Node*, Alloc, ValueCompare>
Chris@16 209 >::type
Chris@16 210 unvisited_node_container;
Chris@16 211
Chris@16 212 public:
Chris@16 213 tree_iterator(void):
Chris@16 214 adaptor_type(0), unvisited_nodes(ValueCompare())
Chris@16 215 {}
Chris@16 216
Chris@16 217 tree_iterator(ValueCompare const & cmp):
Chris@16 218 adaptor_type(0), unvisited_nodes(cmp)
Chris@16 219 {}
Chris@16 220
Chris@16 221 tree_iterator(const Node * it, ValueCompare const & cmp):
Chris@16 222 adaptor_type(it), unvisited_nodes(cmp)
Chris@16 223 {
Chris@16 224 if (it)
Chris@16 225 discover_nodes(it);
Chris@16 226 }
Chris@16 227
Chris@16 228 /* fills the iterator from a list of possible top nodes */
Chris@16 229 template <typename NodePointerIterator>
Chris@16 230 tree_iterator(NodePointerIterator begin, NodePointerIterator end, const Node * top_node, ValueCompare const & cmp):
Chris@16 231 adaptor_type(0), unvisited_nodes(cmp)
Chris@16 232 {
Chris@16 233 BOOST_STATIC_ASSERT(ordered_iterator);
Chris@16 234 if (begin == end)
Chris@16 235 return;
Chris@16 236
Chris@16 237 adaptor_type::base_reference() = top_node;
Chris@16 238 discover_nodes(top_node);
Chris@16 239
Chris@16 240 for (NodePointerIterator it = begin; it != end; ++it) {
Chris@16 241 const Node * current_node = static_cast<const Node*>(&*it);
Chris@16 242 if (current_node != top_node)
Chris@16 243 unvisited_nodes.push(current_node);
Chris@16 244 }
Chris@16 245 }
Chris@16 246
Chris@16 247 bool operator!=(tree_iterator const & rhs) const
Chris@16 248 {
Chris@16 249 return adaptor_type::base() != rhs.base();
Chris@16 250 }
Chris@16 251
Chris@16 252 bool operator==(tree_iterator const & rhs) const
Chris@16 253 {
Chris@16 254 return !operator!=(rhs);
Chris@16 255 }
Chris@16 256
Chris@16 257 const Node * get_node() const
Chris@16 258 {
Chris@16 259 return adaptor_type::base_reference();
Chris@16 260 }
Chris@16 261
Chris@16 262 private:
Chris@16 263 void increment(void)
Chris@16 264 {
Chris@16 265 if (unvisited_nodes.empty())
Chris@16 266 adaptor_type::base_reference() = 0;
Chris@16 267 else {
Chris@16 268 const Node * next = unvisited_nodes.top();
Chris@16 269 unvisited_nodes.pop();
Chris@16 270 discover_nodes(next);
Chris@16 271 adaptor_type::base_reference() = next;
Chris@16 272 }
Chris@16 273 }
Chris@16 274
Chris@16 275 ValueType const & dereference() const
Chris@16 276 {
Chris@16 277 return ValueExtractor::operator()(adaptor_type::base_reference()->value);
Chris@16 278 }
Chris@16 279
Chris@16 280 void discover_nodes(const Node * n)
Chris@16 281 {
Chris@16 282 for (typename Node::const_child_iterator it = n->children.begin(); it != n->children.end(); ++it) {
Chris@16 283 const Node * n = PointerExtractor::operator()(it);
Chris@16 284 if (check_null_pointer && n == NULL)
Chris@16 285 continue;
Chris@16 286 unvisited_nodes.push(n);
Chris@16 287 }
Chris@16 288 }
Chris@16 289
Chris@16 290 unvisited_node_container unvisited_nodes;
Chris@16 291 };
Chris@16 292
Chris@16 293 template <typename Node, typename NodeList>
Chris@16 294 struct list_iterator_converter
Chris@16 295 {
Chris@16 296 typename NodeList::const_iterator operator()(const Node * node)
Chris@16 297 {
Chris@16 298 return NodeList::s_iterator_to(*node);
Chris@16 299 }
Chris@16 300
Chris@16 301 Node * operator()(typename NodeList::const_iterator it)
Chris@16 302 {
Chris@16 303 return const_cast<Node*>(static_cast<const Node*>(&*it));
Chris@16 304 }
Chris@16 305 };
Chris@16 306
Chris@16 307 template <typename Node,
Chris@16 308 typename NodeIterator,
Chris@16 309 typename ValueType,
Chris@16 310 typename ValueExtractor = identity<typename Node::value_type>,
Chris@16 311 typename IteratorCoverter = identity<NodeIterator>
Chris@16 312 >
Chris@16 313 class recursive_tree_iterator:
Chris@16 314 public boost::iterator_adaptor<recursive_tree_iterator<Node,
Chris@16 315 NodeIterator,
Chris@16 316 ValueType,
Chris@16 317 ValueExtractor,
Chris@16 318 IteratorCoverter
Chris@16 319 >,
Chris@16 320 NodeIterator,
Chris@16 321 ValueType const,
Chris@16 322 boost::bidirectional_traversal_tag>,
Chris@16 323 ValueExtractor, IteratorCoverter
Chris@16 324 {
Chris@16 325 typedef boost::iterator_adaptor<recursive_tree_iterator<Node,
Chris@16 326 NodeIterator,
Chris@16 327 ValueType,
Chris@16 328 ValueExtractor,
Chris@16 329 IteratorCoverter
Chris@16 330 >,
Chris@16 331 NodeIterator,
Chris@16 332 ValueType const,
Chris@16 333 boost::bidirectional_traversal_tag> adaptor_type;
Chris@16 334
Chris@16 335 friend class boost::iterator_core_access;
Chris@16 336
Chris@16 337
Chris@16 338 public:
Chris@16 339 recursive_tree_iterator(void):
Chris@16 340 adaptor_type(0)
Chris@16 341 {}
Chris@16 342
Chris@16 343 explicit recursive_tree_iterator(NodeIterator const & it):
Chris@16 344 adaptor_type(it)
Chris@16 345 {}
Chris@16 346
Chris@16 347 void increment(void)
Chris@16 348 {
Chris@16 349 NodeIterator next = adaptor_type::base_reference();
Chris@16 350
Chris@16 351 const Node * n = get_node(next);
Chris@16 352 if (n->children.empty()) {
Chris@16 353 const Node * parent = get_node(next)->get_parent();
Chris@16 354
Chris@16 355 ++next;
Chris@16 356
Chris@16 357 while (true) {
Chris@16 358 if (parent == NULL || next != parent->children.end())
Chris@16 359 break;
Chris@16 360
Chris@16 361 next = IteratorCoverter::operator()(parent);
Chris@16 362 parent = get_node(next)->get_parent();
Chris@16 363 ++next;
Chris@16 364 }
Chris@16 365 } else
Chris@16 366 next = n->children.begin();
Chris@16 367
Chris@16 368 adaptor_type::base_reference() = next;
Chris@16 369 return;
Chris@16 370 }
Chris@16 371
Chris@16 372 ValueType const & dereference() const
Chris@16 373 {
Chris@16 374 return ValueExtractor::operator()(get_node(adaptor_type::base_reference())->value);
Chris@16 375 }
Chris@16 376
Chris@16 377 static const Node * get_node(NodeIterator const & it)
Chris@16 378 {
Chris@16 379 return static_cast<const Node *>(&*it);
Chris@16 380 }
Chris@16 381
Chris@16 382 const Node * get_node() const
Chris@16 383 {
Chris@16 384 return get_node(adaptor_type::base_reference());
Chris@16 385 }
Chris@16 386 };
Chris@16 387
Chris@16 388
Chris@16 389 } /* namespace detail */
Chris@16 390 } /* namespace heap */
Chris@16 391 } /* namespace boost */
Chris@16 392
Chris@16 393 #endif /* BOOST_HEAP_DETAIL_TREE_ITERATOR_HPP */