You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
220 lines
5.5 KiB
220 lines
5.5 KiB
//======================================================================= |
|
// Copyright 2002 Indiana University. |
|
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek |
|
// |
|
// Distributed under the Boost Software License, Version 1.0. (See |
|
// accompanying file LICENSE_1_0.txt or copy at |
|
// http://www.boost.org/LICENSE_1_0.txt) |
|
//======================================================================= |
|
|
|
#ifndef BOOST_LIST_BASE_HPP |
|
#define BOOST_LIST_BASE_HPP |
|
|
|
#include <boost/iterator_adaptors.hpp> |
|
|
|
// Perhaps this should go through formal review, and move to <boost/>. |
|
|
|
/* |
|
An alternate interface idea: |
|
Extend the std::list functionality by creating remove/insert |
|
functions that do not require the container object! |
|
*/ |
|
|
|
namespace boost { |
|
namespace detail { |
|
|
|
//========================================================================= |
|
// Linked-List Generic Implementation Functions |
|
|
|
template <class Node, class Next> |
|
inline Node |
|
slist_insert_after(Node pos, Node x, |
|
Next next) |
|
{ |
|
next(x) = next(pos); |
|
next(pos) = x; |
|
return x; |
|
} |
|
|
|
// return next(pos) or next(next(pos)) ? |
|
template <class Node, class Next> |
|
inline Node |
|
slist_remove_after(Node pos, |
|
Next next) |
|
{ |
|
Node n = next(pos); |
|
next(pos) = next(n); |
|
return n; |
|
} |
|
|
|
template <class Node, class Next> |
|
inline Node |
|
slist_remove_range(Node before_first, Node last, |
|
Next next) |
|
{ |
|
next(before_first) = last; |
|
return last; |
|
} |
|
|
|
template <class Node, class Next> |
|
inline Node |
|
slist_previous(Node head, Node x, Node nil, |
|
Next next) |
|
{ |
|
while (head != nil && next(head) != x) |
|
head = next(head); |
|
return head; |
|
} |
|
|
|
template<class Node, class Next> |
|
inline void |
|
slist_splice_after(Node pos, Node before_first, Node before_last, |
|
Next next) |
|
{ |
|
if (pos != before_first && pos != before_last) { |
|
Node first = next(before_first); |
|
Node after = next(pos); |
|
next(before_first) = next(before_last); |
|
next(pos) = first; |
|
next(before_last) = after; |
|
} |
|
} |
|
|
|
template <class Node, class Next> |
|
inline Node |
|
slist_reverse(Node node, Node nil, |
|
Next next) |
|
{ |
|
Node result = node; |
|
node = next(node); |
|
next(result) = nil; |
|
while(node) { |
|
Node next = next(node); |
|
next(node) = result; |
|
result = node; |
|
node = next; |
|
} |
|
return result; |
|
} |
|
|
|
template <class Node, class Next> |
|
inline std::size_t |
|
slist_size(Node head, Node nil, |
|
Next next) |
|
{ |
|
std::size_t s = 0; |
|
for ( ; head != nil; head = next(head)) |
|
++s; |
|
return s; |
|
} |
|
|
|
template <class Next, class Data> |
|
class slist_iterator_policies |
|
{ |
|
public: |
|
explicit slist_iterator_policies(const Next& n, const Data& d) |
|
: m_next(n), m_data(d) { } |
|
|
|
template <class Reference, class Node> |
|
Reference dereference(type<Reference>, const Node& x) const |
|
{ return m_data(x); } |
|
|
|
template <class Node> |
|
void increment(Node& x) const |
|
{ x = m_next(x); } |
|
|
|
template <class Node> |
|
bool equal(Node& x, Node& y) const |
|
{ return x == y; } |
|
|
|
protected: |
|
Next m_next; |
|
Data m_data; |
|
}; |
|
|
|
//=========================================================================== |
|
// Doubly-Linked List Generic Implementation Functions |
|
|
|
template <class Node, class Next, class Prev> |
|
inline void |
|
dlist_insert_before(Node pos, Node x, |
|
Next next, Prev prev) |
|
{ |
|
next(x) = pos; |
|
prev(x) = prev(pos); |
|
next(prev(pos)) = x; |
|
prev(pos) = x; |
|
} |
|
|
|
template <class Node, class Next, class Prev> |
|
void |
|
dlist_remove(Node pos, |
|
Next next, Prev prev) |
|
{ |
|
Node next_node = next(pos); |
|
Node prev_node = prev(pos); |
|
next(prev_node) = next_node; |
|
prev(next_node) = prev_node; |
|
} |
|
|
|
// This deletes every node in the list except the |
|
// sentinel node. |
|
template <class Node, class Delete> |
|
inline void |
|
dlist_clear(Node sentinel, Delete del) |
|
{ |
|
Node i, tmp; |
|
i = next(sentinel); |
|
while (i != sentinel) { |
|
tmp = i; |
|
i = next(i); |
|
del(tmp); |
|
} |
|
} |
|
|
|
template <class Node> |
|
inline bool |
|
dlist_empty(Node dummy) |
|
{ |
|
return next(dummy) == dummy; |
|
} |
|
|
|
template <class Node, class Next, class Prev> |
|
void |
|
dlist_transfer(Node pos, Node first, Node last, |
|
Next next, Prev prev) |
|
{ |
|
if (pos != last) { |
|
// Remove [first,last) from its old position |
|
next(prev(last)) = pos; |
|
next(prev(first)) = last; |
|
next(prev(pos)) = first; |
|
|
|
// Splice [first,last) into its new position |
|
Node tmp = prev(pos); |
|
prev(pos) = prev(last); |
|
prev(last) = prev(first); |
|
prev(first) = tmp; |
|
} |
|
} |
|
|
|
template <class Next, class Prev, class Data> |
|
class dlist_iterator_policies |
|
: public slist_iterator_policies<Next, Data> |
|
{ |
|
typedef slist_iterator_policies<Next, Data> Base; |
|
public: |
|
template <class Node> |
|
void decrement(Node& x) const |
|
{ x = m_prev(x); } |
|
|
|
dlist_iterator_policies(Next n, Prev p, Data d) |
|
: Base(n,d), m_prev(p) { } |
|
protected: |
|
Prev m_prev; |
|
}; |
|
|
|
} // namespace detail |
|
} // namespace boost |
|
|
|
#endif // BOOST_LIST_BASE_HPP
|
|
|