File indexing completed on 2025-01-18 09:53:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_LIST_HPP_EAN_10_26_2009
0012 #define BOOST_XPRESSIVE_DETAIL_CORE_LIST_HPP_EAN_10_26_2009
0013
0014
0015 #if defined(_MSC_VER)
0016 # pragma once
0017 #endif
0018
0019 #include <cstddef>
0020 #include <iterator>
0021 #include <algorithm>
0022 #include <boost/assert.hpp>
0023 #include <boost/iterator/iterator_facade.hpp>
0024
0025 namespace boost { namespace xpressive { namespace detail
0026 {
0027
0028
0029
0030
0031 template<typename T>
0032 struct list
0033 {
0034 private:
0035 struct node_base
0036 {
0037 node_base *_prev;
0038 node_base *_next;
0039 };
0040
0041 struct node : node_base
0042 {
0043 explicit node(T const &value)
0044 : _value(value)
0045 {}
0046
0047 T _value;
0048 };
0049
0050 node_base _sentry;
0051
0052 template<typename Ref = T &>
0053 struct list_iterator
0054 : boost::iterator_facade<list_iterator<Ref>, T, std::bidirectional_iterator_tag, Ref>
0055 {
0056 list_iterator(list_iterator<> const &it) : _node(it._node) {}
0057 explicit list_iterator(node_base *n = 0) : _node(n) {}
0058 private:
0059 friend struct list<T>;
0060 friend class boost::iterator_core_access;
0061 Ref dereference() const { return static_cast<node *>(_node)->_value; }
0062 void increment() { _node = _node->_next; }
0063 void decrement() { _node = _node->_prev; }
0064 bool equal(list_iterator const &it) const { return _node == it._node; }
0065 node_base *_node;
0066 };
0067
0068 public:
0069 typedef T *pointer;
0070 typedef T const *const_pointer;
0071 typedef T &reference;
0072 typedef T const &const_reference;
0073 typedef list_iterator<> iterator;
0074 typedef list_iterator<T const &> const_iterator;
0075 typedef std::size_t size_type;
0076
0077 list()
0078 {
0079 _sentry._next = _sentry._prev = &_sentry;
0080 }
0081
0082 list(list const &that)
0083 {
0084 _sentry._next = _sentry._prev = &_sentry;
0085 const_iterator it = that.begin(), e = that.end();
0086 for( ; it != e; ++it)
0087 push_back(*it);
0088 }
0089
0090 list &operator =(list const &that)
0091 {
0092 list(that).swap(*this);
0093 return *this;
0094 }
0095
0096 ~list()
0097 {
0098 clear();
0099 }
0100
0101 void clear()
0102 {
0103 while(!empty())
0104 pop_front();
0105 }
0106
0107 void swap(list &that)
0108 {
0109 list temp;
0110 temp.splice(temp.begin(), that);
0111 that.splice(that.begin(), *this);
0112 splice(begin(), temp);
0113 }
0114
0115 void push_front(T const &t)
0116 {
0117 node *new_node = new node(t);
0118
0119 new_node->_next = _sentry._next;
0120 new_node->_prev = &_sentry;
0121
0122 _sentry._next->_prev = new_node;
0123 _sentry._next = new_node;
0124 }
0125
0126 void push_back(T const &t)
0127 {
0128 node *new_node = new node(t);
0129
0130 new_node->_next = &_sentry;
0131 new_node->_prev = _sentry._prev;
0132
0133 _sentry._prev->_next = new_node;
0134 _sentry._prev = new_node;
0135 }
0136
0137 void pop_front()
0138 {
0139 BOOST_ASSERT(!empty());
0140 node *old_node = static_cast<node *>(_sentry._next);
0141 _sentry._next = old_node->_next;
0142 _sentry._next->_prev = &_sentry;
0143 delete old_node;
0144 }
0145
0146 void pop_back()
0147 {
0148 BOOST_ASSERT(!empty());
0149 node *old_node = static_cast<node *>(_sentry._prev);
0150 _sentry._prev = old_node->_prev;
0151 _sentry._prev->_next = &_sentry;
0152 delete old_node;
0153 }
0154
0155 bool empty() const
0156 {
0157 return _sentry._next == &_sentry;
0158 }
0159
0160 void splice(iterator it, list &x)
0161 {
0162 if(x.empty())
0163 return;
0164
0165 x._sentry._prev->_next = it._node;
0166 x._sentry._next->_prev = it._node->_prev;
0167
0168 it._node->_prev->_next = x._sentry._next;
0169 it._node->_prev = x._sentry._prev;
0170
0171 x._sentry._prev = x._sentry._next = &x._sentry;
0172 }
0173
0174 void splice(iterator it, list &, iterator xit)
0175 {
0176 xit._node->_prev->_next = xit._node->_next;
0177 xit._node->_next->_prev = xit._node->_prev;
0178
0179 xit._node->_next = it._node;
0180 xit._node->_prev = it._node->_prev;
0181
0182 it._node->_prev = it._node->_prev->_next = xit._node;
0183 }
0184
0185 reference front()
0186 {
0187 BOOST_ASSERT(!empty());
0188 return static_cast<node *>(_sentry._next)->_value;
0189 }
0190
0191 const_reference front() const
0192 {
0193 BOOST_ASSERT(!empty());
0194 return static_cast<node *>(_sentry._next)->_value;
0195 }
0196
0197 reference back()
0198 {
0199 BOOST_ASSERT(!empty());
0200 return static_cast<node *>(_sentry._prev)->_value;
0201 }
0202
0203 const_reference back() const
0204 {
0205 BOOST_ASSERT(!empty());
0206 return static_cast<node *>(_sentry._prev)->_value;
0207 }
0208
0209 iterator begin()
0210 {
0211 return iterator(_sentry._next);
0212 }
0213
0214 const_iterator begin() const
0215 {
0216 return const_iterator(_sentry._next);
0217 }
0218
0219 iterator end()
0220 {
0221 return iterator(&_sentry);
0222 }
0223
0224 const_iterator end() const
0225 {
0226 return const_iterator(const_cast<node_base *>(&_sentry));
0227 }
0228
0229 size_type size() const
0230 {
0231 return static_cast<size_type>(std::distance(begin(), end()));
0232 }
0233 };
0234
0235 template<typename T>
0236 void swap(list<T> &lhs, list<T> &rhs)
0237 {
0238 lhs.swap(rhs);
0239 }
0240
0241 }}}
0242
0243 #endif