00001
00002
00003 #ifndef s11n_POINTERLIST_H_INCLUDED
00004 #define s11n_POINTERLIST_H_INCLUDED
00005 #include <string>
00006 #include <list>
00007 #include <map>
00008 #define POINTERLIST_USES_VECTOR 0 // define to true if you want to use a vector instead of a list (should be a bit faster?)
00009 #if POINTERLIST_USES_VECTOR
00010 # include <vector>
00011 #else
00012 # include <list>
00013 #endif
00014
00015 namespace s11n
00016 {
00017 using namespace std;
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 template < class ChildType > class pointer_list
00042 {
00043 public:
00044
00045
00046
00047 typedef pointer_list < ChildType > ThisType;
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 typedef ChildType *value_type;
00063
00064
00065
00066
00067
00068 #if POINTERLIST_USES_VECTOR
00069 typedef std::vector < value_type > list_type;
00070 #else
00071 typedef std::list < value_type > list_type;
00072 #endif
00073
00074
00075
00076
00077 typedef typename list_type::iterator iterator;
00078
00079
00080
00081
00082 typedef typename list_type::const_iterator const_iterator;
00083
00084
00085
00086
00087
00088 pointer_list( bool autodel = false ):m_autodel( autodel )
00089 {
00090 }
00091
00092
00093
00094
00095 virtual ~pointer_list()
00096 {
00097 if ( this->auto_delete() ) this->delete_all();
00098 }
00099
00100
00101
00102
00103
00104
00105 bool auto_delete() const
00106 {
00107 return this->m_autodel;
00108 }
00109
00110
00111
00112
00113 void auto_delete( bool autodel )
00114 {
00115 this->m_autodel = autodel;
00116 }
00117
00118
00119
00120
00121
00122
00123 typename ThisType::const_iterator begin() const
00124 {
00125 return this->list.begin();
00126 }
00127
00128
00129
00130
00131
00132 typename ThisType::iterator begin()
00133 {
00134 return this->list.begin();
00135 }
00136
00137
00138
00139
00140 typename ThisType::const_iterator end() const
00141 {
00142 return this->list.end();
00143 }
00144
00145
00146
00147
00148 typename ThisType::iterator end()
00149 {
00150 return this->list.end();
00151 }
00152
00153
00154
00155
00156
00157
00158
00159 typename ThisType::iterator find( typename ThisType::value_type a )
00160 {
00161 typename ThisType::iterator iter = list.begin();
00162 typename ThisType::iterator enditer = list.end();
00163 for ( ; iter != enditer; ++iter )
00164 {
00165 if ( ( *iter ) == a )
00166 {
00167
00168 return iter;
00169 }
00170 }
00171 return list.end();
00172 }
00173
00174
00175
00176
00177
00178 unsigned long count() const
00179 {
00180 return ( unsigned long ) this->list.size();
00181 }
00182
00183
00184
00185 unsigned long size() const
00186 {
00187 return ( unsigned long ) this->list.size();
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 typename ThisType::value_type add( typename ThisType::value_type a, bool front = false )
00199 {
00200 if ( !a )
00201 return NULL;
00202 if ( !front )
00203 list.push_back( a );
00204 else
00205 {
00206 #if POINTERLIST_USES_VECTOR
00207 list.insert( list.begin(), a );
00208 #else
00209 list.push_front( a );
00210 #endif
00211 }
00212 return a;
00213 }
00214
00215
00216
00217
00218
00219
00220 typename ThisType::value_type push_back( typename ThisType::value_type a )
00221 {
00222 return this->add( a, false );
00223 }
00224
00225
00226
00227
00228
00229
00230 typename ThisType::value_type push_front( typename ThisType::value_type a )
00231 {
00232 return this->add( a, true );
00233 }
00234
00235
00236
00237
00238
00239 enum DeletionPolicy
00240 {
00241
00242
00243
00244 CheckAutoDelete = -1,
00245
00246
00247
00248 DoNotDelete = 0,
00249
00250
00251
00252 Delete = 1
00253 };
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 typename ThisType::value_type remove( typename ThisType::value_type a, DeletionPolicy deletionPolicy = CheckAutoDelete )
00276 {
00277
00278
00279 if ( !a )
00280 return NULL;
00281 typename ThisType::iterator iter = list.begin();
00282 while ( iter != list.end() )
00283 {
00284 if ( ( *iter ) == a )
00285 {
00286 list.erase( iter );
00287 if ( deletionPolicy > 0 || ( ( deletionPolicy == -1 ) && this->auto_delete() ) )
00288 {
00289 delete( a );
00290 return NULL;
00291 }
00292 return a;
00293 }
00294 ++iter;
00295 }
00296 return NULL;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305 void erase( ThisType::iterator it )
00306 {
00307 if ( this->m_autodel ) delete( *it );
00308 this->list.erase( it );
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 void erase( ThisType::iterator begin, ThisType::iterator end )
00320 {
00321 for( ; begin != end; ++begin )
00322 {
00323 if( this->m_autodel ) delete( *begin );
00324 this->list.erase( begin );
00325 }
00326 }
00327
00328
00329
00330
00331 void clear()
00332 {
00333 this->erase( this->begin(), this->end() );
00334 }
00335
00336
00337
00338
00339 void delete_all()
00340 {
00341 typedef std::map < typename ThisType::value_type, int > Protector;
00342 typename ThisType::value_type ptr;
00343 #define POINTER_LIST_SAFE_DELETE 0
00344 #if POINTER_LIST_SAFE_DELETE // causes a hang sometimes. See below.
00345 Protector delmap;
00346 #endif
00347 typename ThisType::iterator iter = list.begin();
00348 typename ThisType::iterator eter = list.end();
00349 for( ; iter != eter; ++iter )
00350 {
00351 ptr = ( *iter );
00352 #if POINTER_LIST_SAFE_DELETE
00353 if ( delmap.end() != delmap.find(ptr) ) continue;
00354 delmap[ptr] = 0;
00355 #endif
00356 delete( ptr );
00357 }
00358 list.clear();
00359 #undef POINTER_LIST_SAFE_DELETE
00360 }
00361
00362
00363
00364
00365 virtual bool contains( typename ThisType::value_type a )
00366 {
00367 return this->list.end() != this->find( a );
00368 }
00369
00370
00371 private:
00372 pointer_list( const ThisType & );
00373 ThisType & operator=( const ThisType & );
00374 bool m_autodel;
00375 list_type list;
00376
00377 };
00378 }
00379
00380
00381
00382
00383 using s11n::pointer_list;
00384 template < class Type > std::ostream & operator<<( std::ostream & os, const pointer_list < Type > &obj )
00385 {
00386 typename pointer_list < Type >::const_iterator citer = obj.begin();
00387 os << "pointer_list@" << std::hex << &obj << ":";
00388 for ( ; citer != obj.end(); ++citer )
00389 {
00390 os << " ptr[";
00391 os << std::hex << ( *citer );
00392 os << "]";
00393 }
00394 return os;
00395 }
00396
00397
00398
00399
00400 template < class Type >
00401 s11n::pointer_list < Type > & operator +=( s11n::pointer_list < Type > &el, Type * ptr )
00402 {
00403 el.add( ptr );
00404 return el;
00405 }
00406
00407
00408
00409
00410
00411 template < class Type >
00412 s11n::pointer_list < Type > & operator -=( s11n::pointer_list < Type > &el, Type * ptr )
00413 {
00414 el.remove( ptr );
00415 return el;
00416 }
00417
00418 #endif // s11n_POINTERLIST_H_INCLUDED