InspIRCd  4.0
intrusive_list_impl.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2014 Attila Molnar <[email protected]>
5  *
6  * This file is part of InspIRCd. InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 
20 namespace insp
21 {
22 
23 template <typename T, typename Tag>
24 class INSPIRCD_INTRUSIVE_LIST_NAME
25 {
26  public:
27  class iterator : public std::iterator<std::bidirectional_iterator_tag, T*>
28  {
29  T* curr;
30 
31  public:
32  iterator(T* i = NULL)
33  : curr(i)
34  {
35  }
36 
37  iterator& operator++()
38  {
39  curr = curr->intrusive_list_node<T, Tag>::ptr_next;
40  return *this;
41  }
42 
43  iterator operator++(int)
44  {
45  iterator ret(*this);
46  operator++();
47  return ret;
48  }
49 
50  iterator& operator--()
51  {
52  curr = curr->intrusive_list_node<T, Tag>::ptr_prev;
53  return *this;
54  }
55 
56  iterator operator--(int)
57  {
58  iterator ret(*this);
59  operator--();
60  return ret;
61  }
62 
63  bool operator==(const iterator& other) const { return (curr == other.curr); }
64  bool operator!=(const iterator& other) const { return (curr != other.curr); }
65  T* operator*() const { return curr; }
66  };
67 
68  typedef iterator const_iterator;
69 
70  bool empty() const
71  {
72  return (size() == 0);
73  }
74 
75  size_t size() const
76  {
77  return listsize;
78  }
79 
80  iterator begin() const
81  {
82  return iterator(listhead);
83  }
84 
85  iterator end() const
86  {
87  return iterator();
88  }
89 
90  void pop_front()
91  {
92  erase(listhead);
93  }
94 
95  T* front() const
96  {
97  return listhead;
98  }
99 
100  void push_front(T* x)
101  {
102  if (listsize++)
103  {
104  x->intrusive_list_node<T, Tag>::ptr_next = listhead;
105  listhead->intrusive_list_node<T, Tag>::ptr_prev = x;
106  }
107 #ifdef INSPIRCD_INTRUSIVE_LIST_HAS_TAIL
108  else
109  listtail = x;
110 #endif
111  listhead = x;
112  }
113 
114 #ifdef INSPIRCD_INTRUSIVE_LIST_HAS_TAIL
115  T* back() const
116  {
117  return listtail;
118  }
119 
120  void push_back(T* x)
121  {
122  if (listsize++)
123  {
124  x->intrusive_list_node<T, Tag>::ptr_prev = listtail;
125  listtail->intrusive_list_node<T, Tag>::ptr_next = x;
126  }
127  else
128  listhead = x;
129  listtail = x;
130  }
131 
132  void pop_back()
133  {
134  erase(listtail);
135  }
136 #endif
137 
138  void erase(const iterator& it)
139  {
140  erase(*it);
141  }
142 
143  void erase(T* x)
144  {
145  if (listhead == x)
146  listhead = x->intrusive_list_node<T, Tag>::ptr_next;
147 #ifdef INSPIRCD_INTRUSIVE_LIST_HAS_TAIL
148  if (listtail == x)
149  listtail = x->intrusive_list_node<T, Tag>::ptr_prev;
150 #endif
151  x->intrusive_list_node<T, Tag>::unlink();
152  listsize--;
153  }
154 
155  private:
156  T* listhead = nullptr;
157 #ifdef INSPIRCD_INTRUSIVE_LIST_HAS_TAIL
158  T* listtail = nullptr;
159 #endif
160  size_t listsize = 0;
161 };
162 
163 } // namespace insp
Definition: intrusive_list_impl.h:28