Wiselib
|
00001 00002 #ifndef __WISELIB_UTIL_PSTL_LIST_DYNAMIC_H 00003 #define __WISELIB_UTIL_PSTL_LIST_DYNAMIC_H 00004 00005 namespace wiselib { 00006 00007 namespace { 00008 template< 00009 typename Value_P, 00010 typename Allocator_P 00011 > 00012 struct DoublyConnectedListNode { 00013 typedef DoublyConnectedListNode<Value_P, Allocator_P> self_type; 00014 typename Allocator_P::template Ref<self_type>::pointer_t next; 00015 typename Allocator_P::template Ref<self_type>::pointer_t prev; 00016 Value_P value; 00017 00018 DoublyConnectedListNode() { } 00019 }; 00020 00021 00022 template< 00023 typename List_P 00024 > 00025 class list_dynamic_iterator { 00026 public: 00027 typedef List_P List; 00028 typedef typename List::Allocator Allocator; 00029 typedef typename List::value_type value_type; 00030 typedef typename List::node_type node_type; 00031 typedef value_type& reference; 00032 typedef value_type* pointer; 00033 typedef list_dynamic_iterator<List> iterator_type; 00034 typedef list_dynamic_iterator<List> self_type; 00035 typedef typename Allocator::template Ref<node_type>::pointer_t node_pointer_t; 00036 00037 list_dynamic_iterator() : list_(0) { } 00038 list_dynamic_iterator(List& l) : list_(&l) { } 00039 list_dynamic_iterator(List& l, const node_pointer_t node) : list_(&l), node_(node) { } 00040 list_dynamic_iterator(const self_type& other) : list_(other.list_), node_(other.node_) { } 00041 00042 reference operator*() { return node_->value; } 00043 pointer operator->() { return &node_->value; } 00044 00045 node_pointer_t node() { return node_; } 00046 00047 iterator_type& operator++() { node_ = node_->next; return *this; } 00048 00049 iterator_type& operator--() { 00050 if(!node_) { node_ = list_->last(); } 00051 else { node_ = node_->prev; } 00052 return *this; 00053 } 00054 bool operator==(const iterator_type& other) const { 00055 return node_ == other.node_; 00056 } 00057 bool operator!=(const iterator_type& other) const { 00058 return node_ != other.node_; 00059 } 00060 00061 private: 00062 List* list_; 00063 node_pointer_t node_; 00064 }; 00065 } // ns 00066 00067 00068 00069 00072 template< 00073 typename OsModel_P, 00074 typename Value_P, 00075 typename Allocator_P 00076 > 00077 class list_dynamic { 00078 public: 00079 typedef DoublyConnectedListNode<Value_P, Allocator_P> Node_P; 00080 00081 typedef OsModel_P OsModel; 00082 typedef typename OsModel::size_t size_t; 00083 typedef Value_P value_type; 00084 typedef value_type& reference; 00085 typedef const value_type& const_reference; 00086 typedef Allocator_P Allocator; 00087 typedef Node_P node_type; 00088 typedef typename Allocator::template Ref<node_type>::pointer_t node_pointer_t; 00089 typedef list_dynamic<OsModel_P, Value_P, Allocator_P> self_type; 00090 typedef list_dynamic_iterator<self_type> iterator; 00091 typedef list_dynamic_iterator<const self_type> const_iterator; 00092 00093 list_dynamic() : allocator_(0) { }; 00094 list_dynamic(Allocator& alloc) : allocator_(&alloc) { }; 00095 00096 ~list_dynamic() { 00097 clear(); 00098 } 00099 00100 list_dynamic& operator=(const self_type&); 00101 00102 void set_allocator(Allocator& alloc) { allocator_ = &alloc; } 00103 00104 iterator begin() { return iterator(*this, first_node_); } 00105 iterator end() { return iterator(*this); } 00106 00107 const_iterator begin() const { return const_iterator(*this, first_node_); } 00108 const_iterator end() const { return const_iterator(*this); } 00109 00110 bool empty() const { return begin() == end(); } 00111 00112 size_t size() const { 00113 size_t s = 0; 00114 for(const_iterator i(begin()); i != end(); ++i) { 00115 s++; 00116 } 00117 return s; 00118 } 00119 00120 const value_type& front() const { return first_node_->value; } 00121 const value_type& back() const { return last_node_->value; } 00122 iterator back_iterator() { return iterator(*this, last_node_); } 00123 00124 iterator insert(iterator iter, const_reference v) { 00125 node_pointer_t n = allocator_-> template allocate<node_type>(); 00126 n->value = v; 00127 00128 iterator before(iter), after(iter); 00129 --before; 00130 if(before.node()) { before.node()->next = n; } 00131 else { first_node_ = n; } 00132 00133 if(after.node()) { after.node()->prev = n; } 00134 else { last_node_ = n; } 00135 00136 n->prev = before.node(); 00137 n->next = after.node(); 00138 00139 iterator new_iter(*this, n); 00140 return new_iter; 00141 } 00142 00143 iterator push_back(value_type v) { 00144 return insert(end(), v); 00145 } 00146 iterator push_front(value_type v) { 00147 return insert(begin(), v); 00148 } 00149 00150 iterator erase(iterator iter) { 00151 if(!iter.node()) { return iter; } 00152 if(iter.node() == first_node_) { first_node_ = iter.node()->next; } 00153 if(iter.node() == last_node_) { last_node_ = iter.node()->prev; } 00154 if(iter.node()->next) { iter.node()->next->prev = iter.node()->prev; } 00155 if(iter.node()->prev) { iter.node()->prev->next = iter.node()->next; } 00156 00157 iterator n(*this, iter.node()->next); 00158 allocator_-> template free<node_type>(iter.node()); 00159 return n; 00160 } 00161 00162 void swap(self_type& other) { 00163 node_pointer_t tmp_first = first_node_, tmp_last = last_node_; 00164 typename Allocator::self_pointer_t tmp_alloc = allocator_; 00165 00166 first_node_ = other.first_node_; 00167 last_node_ = other.last_node_; 00168 allocator_ = other.allocator_; 00169 00170 other.first_node_ = tmp_first; 00171 other.last_node_ = tmp_last; 00172 other.allocator_ = tmp_alloc; 00173 } 00174 00175 00176 void clear() { 00177 iterator rm = begin(); 00178 while(rm.node()) { rm = erase(rm); } 00179 } 00180 00181 node_pointer_t first() const { return first_node_; } 00182 node_pointer_t last() const { return last_node_; } 00183 00184 private: 00185 typename Allocator::self_pointer_t allocator_; 00186 node_pointer_t first_node_, last_node_; 00187 }; 00188 00189 00190 template< 00191 typename OsModel_P, 00192 typename Allocator_P 00193 > 00194 struct maplist_adaptors { 00195 template< 00196 typename Value_P 00197 > 00198 class list_dynamic : public wiselib::list_dynamic<OsModel_P, Value_P, Allocator_P> { 00199 }; 00200 }; 00201 00202 } // ns 00203 00204 #endif // __WISELIB_UTIL_PSTL_LIST_DYNAMIC_H 00205