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