annotate DEPENDENCIES/generic/include/boost/heap/detail/heap_node.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: heap node 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 #ifndef BOOST_HEAP_DETAIL_HEAP_NODE_HPP
Chris@16 10 #define BOOST_HEAP_DETAIL_HEAP_NODE_HPP
Chris@16 11
Chris@16 12 #include <boost/assert.hpp>
Chris@16 13 #include <boost/static_assert.hpp>
Chris@16 14 #include <boost/intrusive/list.hpp>
Chris@16 15 #include <boost/mpl/if.hpp>
Chris@16 16
Chris@16 17 #ifdef BOOST_HEAP_SANITYCHECKS
Chris@16 18 #define BOOST_HEAP_ASSERT BOOST_ASSERT
Chris@16 19 #else
Chris@16 20 #define BOOST_HEAP_ASSERT(expression)
Chris@16 21 #endif
Chris@16 22
Chris@16 23
Chris@16 24 namespace boost {
Chris@16 25 namespace heap {
Chris@16 26 namespace detail {
Chris@16 27
Chris@16 28 namespace bi = boost::intrusive;
Chris@16 29 namespace mpl = boost::mpl;
Chris@16 30
Chris@16 31 template <bool auto_unlink = false>
Chris@16 32 struct heap_node_base:
Chris@16 33 bi::list_base_hook<typename mpl::if_c<auto_unlink,
Chris@16 34 bi::link_mode<bi::auto_unlink>,
Chris@16 35 bi::link_mode<bi::safe_link>
Chris@16 36 >::type
Chris@16 37 >
Chris@16 38 {};
Chris@16 39
Chris@16 40 typedef bi::list<heap_node_base<false> > heap_node_list;
Chris@16 41
Chris@16 42 struct nop_disposer
Chris@16 43 {
Chris@16 44 template <typename T>
Chris@16 45 void operator()(T * n)
Chris@16 46 {
Chris@16 47 BOOST_HEAP_ASSERT(false);
Chris@16 48 }
Chris@16 49 };
Chris@16 50
Chris@16 51 template <typename Node, typename HeapBase>
Chris@16 52 bool is_heap(const Node * n, typename HeapBase::value_compare const & cmp)
Chris@16 53 {
Chris@16 54 for (typename Node::const_child_iterator it = n->children.begin(); it != n->children.end(); ++it) {
Chris@16 55 Node const & this_node = static_cast<Node const &>(*it);
Chris@16 56 const Node * child = static_cast<const Node*>(&this_node);
Chris@16 57
Chris@16 58 if (cmp(HeapBase::get_value(n->value), HeapBase::get_value(child->value)) ||
Chris@16 59 !is_heap<Node, HeapBase>(child, cmp))
Chris@16 60 return false;
Chris@16 61 }
Chris@16 62 return true;
Chris@16 63 }
Chris@16 64
Chris@16 65 template <typename Node>
Chris@16 66 std::size_t count_nodes(const Node * n);
Chris@16 67
Chris@16 68 template <typename Node, typename List>
Chris@16 69 std::size_t count_list_nodes(List const & node_list)
Chris@16 70 {
Chris@16 71 std::size_t ret = 0;
Chris@16 72
Chris@16 73 for (typename List::const_iterator it = node_list.begin(); it != node_list.end(); ++it) {
Chris@16 74 const Node * child = static_cast<const Node*>(&*it);
Chris@16 75 ret += count_nodes<Node>(child);
Chris@16 76 }
Chris@16 77 return ret;
Chris@16 78 }
Chris@16 79
Chris@16 80 template <typename Node>
Chris@16 81 std::size_t count_nodes(const Node * n)
Chris@16 82 {
Chris@16 83 return 1 + count_list_nodes<Node, typename Node::child_list>(n->children);
Chris@16 84 }
Chris@16 85
Chris@16 86
Chris@16 87 /* node cloner
Chris@16 88 *
Chris@16 89 * Requires `Clone Constructor':
Chris@16 90 * template <typename Alloc>
Chris@16 91 * Node::Node(Node const &, Alloc &)
Chris@16 92 *
Chris@16 93 * template <typename Alloc>
Chris@16 94 * Node::Node(Node const &, Alloc &, Node * parent)
Chris@16 95 *
Chris@16 96 * */
Chris@16 97 template <typename Node,
Chris@16 98 typename NodeBase,
Chris@16 99 typename Alloc>
Chris@16 100 struct node_cloner
Chris@16 101 {
Chris@16 102 node_cloner(Alloc & allocator):
Chris@16 103 allocator(allocator)
Chris@16 104 {}
Chris@16 105
Chris@16 106 Node * operator() (NodeBase const & node)
Chris@16 107 {
Chris@16 108 Node * ret = allocator.allocate(1);
Chris@16 109 new (ret) Node(static_cast<Node const &>(node), allocator);
Chris@16 110 return ret;
Chris@16 111 }
Chris@16 112
Chris@16 113 Node * operator() (NodeBase const & node, Node * parent)
Chris@16 114 {
Chris@16 115 Node * ret = allocator.allocate(1);
Chris@16 116 new (ret) Node(static_cast<Node const &>(node), allocator, parent);
Chris@16 117 return ret;
Chris@16 118 }
Chris@16 119
Chris@16 120 private:
Chris@16 121 Alloc & allocator;
Chris@16 122 };
Chris@16 123
Chris@16 124 /* node disposer
Chris@16 125 *
Chris@16 126 * Requirements:
Chris@16 127 * Node::clear_subtree(Alloc &) clears the subtree via allocator
Chris@16 128 *
Chris@16 129 * */
Chris@16 130 template <typename Node,
Chris@16 131 typename NodeBase,
Chris@16 132 typename Alloc>
Chris@16 133 struct node_disposer
Chris@16 134 {
Chris@16 135 typedef typename Alloc::pointer node_pointer;
Chris@16 136
Chris@16 137 node_disposer(Alloc & alloc):
Chris@16 138 alloc_(alloc)
Chris@16 139 {}
Chris@16 140
Chris@16 141 void operator()(NodeBase * base)
Chris@16 142 {
Chris@16 143 node_pointer n = static_cast<node_pointer>(base);
Chris@16 144 n->clear_subtree(alloc_);
Chris@16 145 alloc_.destroy(n);
Chris@16 146 alloc_.deallocate(n, 1);
Chris@16 147 }
Chris@16 148
Chris@16 149 Alloc & alloc_;
Chris@16 150 };
Chris@16 151
Chris@16 152
Chris@16 153 template <typename ValueType,
Chris@16 154 bool constant_time_child_size = true
Chris@16 155 >
Chris@16 156 struct heap_node:
Chris@16 157 heap_node_base<!constant_time_child_size>
Chris@16 158 {
Chris@16 159 typedef heap_node_base<!constant_time_child_size> node_base;
Chris@16 160
Chris@16 161 public:
Chris@16 162 typedef ValueType value_type;
Chris@16 163
Chris@16 164 typedef bi::list<node_base,
Chris@16 165 bi::constant_time_size<constant_time_child_size> > child_list;
Chris@16 166
Chris@16 167 typedef typename child_list::iterator child_iterator;
Chris@16 168 typedef typename child_list::const_iterator const_child_iterator;
Chris@16 169 typedef typename child_list::size_type size_type;
Chris@16 170
Chris@16 171 heap_node(ValueType const & v):
Chris@16 172 value(v)
Chris@16 173 {}
Chris@16 174
Chris@16 175 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
Chris@16 176 template <class... Args>
Chris@16 177 heap_node(Args&&... args):
Chris@16 178 value(std::forward<Args>(args)...)
Chris@16 179 {}
Chris@16 180 #endif
Chris@16 181
Chris@16 182 /* protected: */
Chris@16 183 heap_node(heap_node const & rhs):
Chris@16 184 value(rhs.value)
Chris@16 185 {
Chris@16 186 /* we don't copy the child list, but clone it later */
Chris@16 187 }
Chris@16 188
Chris@16 189 public:
Chris@16 190
Chris@16 191 template <typename Alloc>
Chris@16 192 heap_node (heap_node const & rhs, Alloc & allocator):
Chris@16 193 value(rhs.value)
Chris@16 194 {
Chris@16 195 children.clone_from(rhs.children, node_cloner<heap_node, node_base, Alloc>(allocator), nop_disposer());
Chris@16 196 }
Chris@16 197
Chris@16 198 size_type child_count(void) const
Chris@16 199 {
Chris@16 200 BOOST_STATIC_ASSERT(constant_time_child_size);
Chris@16 201 return children.size();
Chris@16 202 }
Chris@16 203
Chris@16 204 void add_child(heap_node * n)
Chris@16 205 {
Chris@16 206 children.push_back(*n);
Chris@16 207 }
Chris@16 208
Chris@16 209 template <typename Alloc>
Chris@16 210 void clear_subtree(Alloc & alloc)
Chris@16 211 {
Chris@16 212 children.clear_and_dispose(node_disposer<heap_node, node_base, Alloc>(alloc));
Chris@16 213 }
Chris@16 214
Chris@16 215 void swap_children(heap_node * rhs)
Chris@16 216 {
Chris@16 217 children.swap(rhs->children);
Chris@16 218 }
Chris@16 219
Chris@16 220 ValueType value;
Chris@16 221 child_list children;
Chris@16 222 };
Chris@16 223
Chris@16 224 template <typename value_type>
Chris@16 225 struct parent_pointing_heap_node:
Chris@16 226 heap_node<value_type>
Chris@16 227 {
Chris@16 228 typedef heap_node<value_type> super_t;
Chris@16 229
Chris@16 230 parent_pointing_heap_node(value_type const & v):
Chris@16 231 super_t(v), parent(NULL)
Chris@16 232 {}
Chris@16 233
Chris@16 234 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
Chris@16 235 template <class... Args>
Chris@16 236 parent_pointing_heap_node(Args&&... args):
Chris@16 237 super_t(std::forward<Args>(args)...), parent(NULL)
Chris@16 238 {}
Chris@16 239 #endif
Chris@16 240
Chris@16 241 template <typename Alloc>
Chris@16 242 struct node_cloner
Chris@16 243 {
Chris@16 244 node_cloner(Alloc & allocator, parent_pointing_heap_node * parent):
Chris@16 245 allocator(allocator), parent_(parent)
Chris@16 246 {}
Chris@16 247
Chris@16 248 parent_pointing_heap_node * operator() (typename super_t::node_base const & node)
Chris@16 249 {
Chris@16 250 parent_pointing_heap_node * ret = allocator.allocate(1);
Chris@16 251 new (ret) parent_pointing_heap_node(static_cast<parent_pointing_heap_node const &>(node), allocator, parent_);
Chris@16 252 return ret;
Chris@16 253 }
Chris@16 254
Chris@16 255 private:
Chris@16 256 Alloc & allocator;
Chris@16 257 parent_pointing_heap_node * parent_;
Chris@16 258 };
Chris@16 259
Chris@16 260 template <typename Alloc>
Chris@16 261 parent_pointing_heap_node (parent_pointing_heap_node const & rhs, Alloc & allocator, parent_pointing_heap_node * parent):
Chris@16 262 super_t(static_cast<super_t const &>(rhs)), parent(parent)
Chris@16 263 {
Chris@16 264 super_t::children.clone_from(rhs.children, node_cloner<Alloc>(allocator, this), nop_disposer());
Chris@16 265 }
Chris@16 266
Chris@16 267 void update_children(void)
Chris@16 268 {
Chris@16 269 typedef heap_node_list::iterator node_list_iterator;
Chris@16 270 for (node_list_iterator it = super_t::children.begin(); it != super_t::children.end(); ++it) {
Chris@16 271 parent_pointing_heap_node * child = static_cast<parent_pointing_heap_node*>(&*it);
Chris@16 272 child->parent = this;
Chris@16 273 }
Chris@16 274 }
Chris@16 275
Chris@16 276 void remove_from_parent(void)
Chris@16 277 {
Chris@16 278 BOOST_HEAP_ASSERT(parent);
Chris@16 279 parent->children.erase(heap_node_list::s_iterator_to(*this));
Chris@16 280 parent = NULL;
Chris@16 281 }
Chris@16 282
Chris@16 283 void add_child(parent_pointing_heap_node * n)
Chris@16 284 {
Chris@16 285 BOOST_HEAP_ASSERT(n->parent == NULL);
Chris@16 286 n->parent = this;
Chris@16 287 super_t::add_child(n);
Chris@16 288 }
Chris@16 289
Chris@16 290 parent_pointing_heap_node * get_parent(void)
Chris@16 291 {
Chris@16 292 return parent;
Chris@16 293 }
Chris@16 294
Chris@16 295 const parent_pointing_heap_node * get_parent(void) const
Chris@16 296 {
Chris@16 297 return parent;
Chris@16 298 }
Chris@16 299
Chris@16 300 parent_pointing_heap_node * parent;
Chris@16 301 };
Chris@16 302
Chris@16 303
Chris@16 304 template <typename value_type>
Chris@16 305 struct marked_heap_node:
Chris@16 306 parent_pointing_heap_node<value_type>
Chris@16 307 {
Chris@16 308 typedef parent_pointing_heap_node<value_type> super_t;
Chris@16 309
Chris@16 310 marked_heap_node(value_type const & v):
Chris@16 311 super_t(v), mark(false)
Chris@16 312 {}
Chris@16 313
Chris@16 314 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
Chris@16 315 template <class... Args>
Chris@16 316 marked_heap_node(Args&&... args):
Chris@16 317 super_t(std::forward<Args>(args)...), mark(false)
Chris@16 318 {}
Chris@16 319 #endif
Chris@16 320
Chris@16 321 marked_heap_node * get_parent(void)
Chris@16 322 {
Chris@16 323 return static_cast<marked_heap_node*>(super_t::parent);
Chris@16 324 }
Chris@16 325
Chris@16 326 const marked_heap_node * get_parent(void) const
Chris@16 327 {
Chris@16 328 return static_cast<marked_heap_node*>(super_t::parent);
Chris@16 329 }
Chris@16 330
Chris@16 331 bool mark;
Chris@16 332 };
Chris@16 333
Chris@16 334
Chris@16 335 template <typename Node>
Chris@16 336 struct cmp_by_degree
Chris@16 337 {
Chris@16 338 template <typename NodeBase>
Chris@16 339 bool operator()(NodeBase const & left,
Chris@16 340 NodeBase const & right)
Chris@16 341 {
Chris@16 342 return static_cast<const Node*>(&left)->child_count() < static_cast<const Node*>(&right)->child_count();
Chris@16 343 }
Chris@16 344 };
Chris@16 345
Chris@16 346 template <typename List, typename Node, typename Cmp>
Chris@16 347 Node * find_max_child(List const & list, Cmp const & cmp)
Chris@16 348 {
Chris@16 349 BOOST_HEAP_ASSERT(!list.empty());
Chris@16 350
Chris@16 351 const Node * ret = static_cast<const Node *> (&list.front());
Chris@16 352 for (typename List::const_iterator it = list.begin(); it != list.end(); ++it) {
Chris@16 353 const Node * current = static_cast<const Node *> (&*it);
Chris@16 354
Chris@16 355 if (cmp(ret->value, current->value))
Chris@16 356 ret = current;
Chris@16 357 }
Chris@16 358
Chris@16 359 return const_cast<Node*>(ret);
Chris@16 360 }
Chris@16 361
Chris@16 362 } /* namespace detail */
Chris@16 363 } /* namespace heap */
Chris@16 364 } /* namespace boost */
Chris@16 365
Chris@16 366 #undef BOOST_HEAP_ASSERT
Chris@16 367 #endif /* BOOST_HEAP_DETAIL_HEAP_NODE_HPP */