1 #ifndef DOZERG_SINGLE_LIST_H_20070917 2 #define DOZERG_SINGLE_LIST_H_20070917 19 #include "template.hh" 20 #include "tools/memory.hh" 21 #include "impl/single_list_impl.hh" 27 class Alloc = std::allocator<T>
34 typedef T & reference;
35 typedef const T & const_reference;
37 typedef const T * const_pointer;
38 typedef size_t size_type;
39 typedef std::ptrdiff_t difference_type;
40 typedef typename Alloc::
41 template rebind<T>::other allocator_type;
42 typedef NS_IMPL::__slist_const_iterator<T> const_iterator;
43 typedef NS_IMPL::__slist_iterator<T,Alloc> iterator;
45 typedef typename iterator::__node __node;
46 typedef typename iterator::__node_ptr __node_ptr;
47 typedef typename Alloc::
48 template rebind<__node>::other __node_alloc;
51 explicit CSingleList(allocator_type = allocator_type())
56 explicit CSingleList(size_type sz, const_reference value = value_type())
60 insert_after(phead_->tail_, sz, value);
66 insert_after(phead_->tail_, a.begin(), a.end());
68 template<
class InputIter>
73 insert_after(phead_->tail_, first, last);
75 ~CSingleList() {destroy();}
76 iterator begin() {
return phead_->next_;}
77 iterator end() {
return 0;}
78 const_iterator begin()
const {
return phead_->next_;}
79 const_iterator end()
const {
return 0;}
80 reference front() {
return *begin();}
81 reference back() {
return *phead_->tail_->pdata_;}
82 const_reference front()
const {
return *begin();}
83 const_reference back()
const {
return *phead_->tail_->pdata_;}
84 bool empty()
const {
return size_ == 0;}
85 size_type size()
const {
return size_;}
86 void clear()
throw() {eraseChainAfter(phead_,0);}
87 allocator_type get_allocator()
const {
return allocator_type();}
88 void push_front(const_reference v) {insert_after(phead_,v);}
89 void push_back(const_reference v) {insert_after(phead_->tail_,v);}
90 void pop_front()
throw() {eraseNodeAfter(phead_);}
91 void erase_after(iterator pos)
throw() {eraseNodeAfter(pos.ptr_);}
92 void erase_after(iterator before_first,iterator last)
throw() {
93 eraseChainAfter(before_first.ptr_,last.ptr_);
95 iterator insert_after(iterator pos,const_reference v){
97 __node_ptr node = createNode(v);
98 insertNodeAfter(pos.ptr_,node);
101 void insert_after(iterator pos,size_type elemSz,const_reference v){
103 __node_ptr head = 0,tail = 0;
104 createChainFill(head,tail,elemSz,v);
105 insertChainAfter(pos.ptr_,head,tail,elemSz);
107 template<
class InputIter>
108 void insert_after(iterator pos,InputIter first,InputIter last){
109 typedef typename CTypeTraits<InputIter>::__IsInteger __Tag;
110 insertAfterAux(pos,first,last,__Tag());
112 void assign(size_type elemSz,const_reference value){
115 }
else if(elemSz < size()){
116 iterator befor_first = std::fill_n(begin(),elemSz - 1,value);
117 *befor_first = value;
118 erase_after(befor_first,end());
121 std::fill(begin(),end(),value);
122 insert_after(phead_->tail_,elemSz - size(),value);
125 template<
class InputIter>
126 void assign(InputIter first,InputIter last){
127 typedef typename CTypeTraits<InputIter>::__IsInteger __Tag;
128 assignAux(first,last,__Tag());
130 void resize(size_type sz,const_reference value = value_type()){
132 iterator befor_first = begin();
133 for(;--sz > 0;++befor_first);
134 erase_after(befor_first,end());
136 insert_after(phead_->tail_,sz - size(),value);
138 __Myt & operator =(
const __Myt & a){
140 assignAux(a.begin(),a.end(),NS_IMPL::CTrueType());
143 void swap(__Myt & a)
throw() {
144 std::swap(size_,a.size_);
145 std::swap(phead_,a.phead_);
147 void append(__Myt & a)
throw() {
149 insertChainAfter(phead_->tail_,a.phead_->next_,a.phead_->tail_,a.size());
153 bool operator ==(
const __Myt & other)
const{
154 return size() == other.size() &&
155 std::equal<const_iterator,const_iterator>(begin(),end(),other.begin());
157 bool operator <(
const __Myt & other)
const{
158 return std::lexicographical_compare(begin(),end(),other.begin(),other.end());
160 bool operator !=(
const __Myt & other)
const {
return !operator ==(other);}
161 bool operator <=(
const __Myt & other)
const {
return !(other < *
this);}
162 bool operator >(
const __Myt & other)
const {
return other < *
this;}
163 bool operator >=(
const __Myt & other)
const {
return !(*
this < other);}
165 template<
class IntegerType>
166 void assignAux(IntegerType sz,IntegerType val,NS_IMPL::CTrueType){
167 assign(size_type(sz),value_type(val));
169 template<
class InputIter>
170 void assignAux(InputIter first,InputIter last,NS_IMPL::CFalseType){
175 insertAfterAux(phead_->tail_,first,last,NS_IMPL::CFalseType());
177 iterator cur = begin(),befor_first = cur;
179 for(;first != last && cur != end();++befor_first)
182 insertAfterAux(phead_->tail_,first,last,NS_IMPL::CFalseType());
184 erase_after(befor_first,end());
188 template<
class IntegerType>
189 void insertAfterAux(iterator pos,IntegerType sz,IntegerType val,NS_IMPL::CTrueType){
190 insert_after(pos,size_type(sz),value_type(val));
192 template<
class InputIter>
193 void insertAfterAux(iterator pos,InputIter first,InputIter last,NS_IMPL::CFalseType){
196 __node_ptr head,tail;
197 size_type sz = createChainCopy(head,tail,first,last);
198 insertChainAfter(pos.ptr_,head,tail,sz);
201 void eraseNodeAfter(__node_ptr pos){
202 assert(phead_ && pos);
203 __node_ptr cur = pos->next_;
205 pos->next_ = cur->next_;
206 if(phead_->tail_ == cur)
212 void eraseChainAfter(__node_ptr pos,__node_ptr last){
213 assert(phead_ && pos);
214 __node_ptr first = pos->next_;
218 size_ -= destroyChain(first,last);
220 template<
class InputIter>
221 size_type createChainCopy(__node_ptr & head,__node_ptr & tail,InputIter first,InputIter last)
const{
224 for(__node_ptr cur = 0;first != last;++ret,++first){
226 cur = createNode(*first);
228 destroyChain(head,0);
240 void createChainFill(__node_ptr & head,__node_ptr & tail,size_type elemSz,const_reference v)
const{
242 tail = head = createNode(v);
244 for(tail->next_ = 0;--elemSz > 0;tail = tail->next_,tail->next_ = 0)
245 tail->next_ = createNode(v);
247 destroyChain(head,0);
252 size_type destroyChain(__node_ptr first,__node_ptr last)
const throw() {
254 for(;first != last;++ret){
255 __node_ptr cur = first;
256 first = first->next_;
261 void insertNodeAfter(__node_ptr pos,__node_ptr node)
throw() {
262 insertChainAfter(pos,node,node,1);
264 void insertChainAfter(__node_ptr pos,__node_ptr head,__node_ptr tail,size_type sz)
throw() {
265 assert(phead_ && pos && head && tail);
266 tail->next_ = pos->next_;
269 phead_->tail_ = tail;
272 __node_ptr createNode(const_reference v)
const{
273 __node_ptr ret = __node_alloc().allocate(1);
276 ret->pdata_ = allocator_type().allocate(1);
277 allocator_type().construct(ret->pdata_,v);
279 tools::Deallocate(ret->pdata_,allocator_type());
280 tools::Deallocate(ret,__node_alloc());
285 void destroyNode(__node_ptr & node)
const throw() {
287 tools::Delete(node->pdata_,allocator_type());
288 tools::Deallocate(node,__node_alloc());
293 phead_ = __node_alloc().allocate(1);
295 phead_->tail_ = phead_;
298 void destroy()
throw() {
300 tools::Deallocate(phead_,__node_alloc());
307 template<
class T,
class Alloc>
Definition: single_list.hh:28