fix accessing std::list functions from within PtrList
[libasyncio] / utils / asyncio_ptr_list.hpp
CommitLineData
8c15b8c7
TJ
1/*
2The software in this package is distributed under the GNU General
3Public License version 2 (with a special exception described below).
4
5A copy of GNU General Public License (GPL) is included in this distribution,
6in the file COPYING.GPL.
7
8As a special exception, if other files instantiate templates or use macros
9or inline functions from this file, or you compile this file and link it
10with other works to produce a work based on this file, this file
11does not by itself cause the resulting work to be covered
12by the GNU General Public License.
13
14However the source code for this file must still be made available
15in accordance with section (3) of the GNU General Public License.
16
17This exception does not invalidate any other reasons why a work based
18on this file might be covered by the GNU General Public License.
19*/
aba4c34d
RP
20/**
21 * @file
22 * @brief a pointer list
23 *
24 * provides a pointer list which is prepared for being used in nested
25 * iterator loops.
26 *
27 * @author Reinhard Pfau \<reinhard.pfau@intra2net.com\>
28 *
29 * @copyright &copy; Copyright 2008 Intra2Net AG
aba4c34d
RP
30 */
31
32#ifndef __ASYNCIO__PTR_LIST_HPP__
33#define __ASYNCIO__PTR_LIST_HPP__
34
35#include <list>
36#include <algorithm>
37
38
39namespace AsyncIo
40{
41namespace Utils
42{
43
44
45/**
46 * @brief provides a global instance counter.
47 *
48 * The global instance counter must be initialized by the module which uses it.
49 * The main purpose for this is to keep track of the instances when PtrList's are
50 * used as global objects.
51 */
52template< class T, bool globalcounted >
53class GlobalCounted
54{
55 static int InstanceCount;
56
57 public:
58
59 GlobalCounted()
60 {
61 ++InstanceCount;
62 } // eo GlobalCounted
63
64
65 virtual ~GlobalCounted()
66 {
67 --InstanceCount;
68 } // eo ~GlobalCounted
69
70 static int Instances()
71 {
72 return InstanceCount;
73 }
74}; // eo GlobalCounted
75
76
77template<>
78class GlobalCounted< class T, false >
79{
80 public:
81 GlobalCounted()
82 {
83 } // eo GlobalCounted
84
85
86 virtual ~GlobalCounted()
87 {
88 } // eo ~GlobalCounted
89
90}; // eo GlobalCounted
91
92
93
94/**
95 * @brief pointer list which supports deletion by set to NULL.
96 *
97 * This list can be used in nested iterator loops as long as some conditions
98 * are fulfilled:
99 * - inside the loops each iterator value is tested for not get NULL.
100 * - cleaning the list is only allowed when the outmost loop exits.
101 * .
102 *
103 *
104 * @tparam T type of the pointers.
105 * @tparam globalcounted determine if a global instance counter should be included.
106 */
107template<class T, bool globalcounted= false>
108class PtrList
109: public GlobalCounted< PtrList< T, globalcounted >, globalcounted >
110, protected std::list<T*>
111{
112 typedef std::list<T*> inherited;
113
114 public:
115 typedef GlobalCounted< PtrList< T, globalcounted >, globalcounted > GlobalCountType;
116
117 typedef typename inherited::iterator iterator;
118 typedef typename inherited::const_iterator const_iterator;
119
120 public:
121
122 PtrList()
123 : Dirty(false)
124 {
125 } // eo PtrList
126
127
128 ~PtrList()
129 {
130 } // eo ~PtrList
131
132
133 /**
134 * @brief add a new item pointer to the list.
135 *
136 * @param item item pointer which should be added
137 */
138 void add_item(T* item)
139 {
140 typename inherited::iterator it= std::find(inherited::begin(), inherited::end(), item);
141 if (it != inherited::end())
142 {
143 // nothing to do since item is already in the list
144 return;
145 }
05682361 146 this->push_back(item);
aba4c34d
RP
147 } // eo add
148
149
150 /**
151 * @brief remove an item pointer from the list by setting to NULL.
152 *
153 * This sets the pointer in the list to NULL and marks the list as dirty.
154 *
155 * @param item the io object which should be removed from the list.
156 */
157 void remove_item(T* item)
158 {
159 typename inherited::iterator it= std::find(inherited::begin(), inherited::end(), item);
160 if (it == inherited::end())
161 {
162 // nothing to do:
163 return;
164 }
165 *it = NULL; // forget the pointer
166 Dirty= true; // ..and mark the list as dirty (i.e. has NULL elements)
167 } // eo remove
168
169
170 /**
171 * @brief cleans the list of objects by removing the NULL elements (if any).
172 *
173 * @note this function should only be called when it is ensured that no
174 * other functions using iterators of this list.
175 */
176 void clean_list()
177 {
178 if (!Dirty)
179 {
180 // nothing to do
181 return;
182 }
183 // remove the NULL elements now:
05682361 184 this->erase(
aba4c34d
RP
185 std::remove( inherited::begin(), inherited::end(), (T*)NULL),
186 inherited::end() );
187 Dirty= false;
188 } // eo clean_list
189
190
191 /**
192 * @brief explicit set the list dirty.
193 *
194 * use this to mark the list as dirty, when an item is set to NULL via
195 * a non const iterator.
196 *
197 * @note This is really dirty; better use remove_item(T*) in that cases!
198 */
199 void set_dirty()
200 {
201 Dirty= true;
202 } // eo set_dirty
203
204
205 iterator begin()
206 {
207 return inherited::begin();
208 }
209
210
211 iterator end()
212 {
213 return inherited::end();
214 }
215
216
217 const_iterator begin() const
218 {
219 return inherited::begin();
220 }
221
222
223 const_iterator end() const
224 {
225 return inherited::end();
226 }
227
228 protected:
229 bool Dirty;
230
231}; // eo class PtrList
232
233
234} // eo namespace Utils
235} // eo namespace AsyncIo
236
237#endif