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