From: restor on
Hi,
I need to perform a remove_if algorithm on a boost::ptr_vector. I am
using boost::ptr_vector to store types that have no copy or clone
operation. std::remove_if doesn't work due to the lack of copy/clone
operations. So I wrote my own function. It is possible to write it in
many ways, but any solution I can think of is worse than the one that
is using a goto statement.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

typedef boost::ptr_vector<NonCopyable> VecT;
typedef boost::function<bool(NonCopyable const&)> FunT;

void removeIf( VecT & list, FunT fun )
{
NEXT_DELETION_TARGET_ITERATION:

BOOST_AUTO( it, list.begin() );
BOOST_AUTO( end, list.end() );

for( ; it != end ; ++it ) {
if( fun(*it) ) {
list.release( it );
goto NEXT_DELETION_TARGET_ITERATION;
}
}
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In addition, I am using a VC++ 2005 compiler that automatically checks
iterator invelidation, and crashes in runtime for some solutions that
appeared correct to me.
I am not sure if I just have a bad day, or if it is a situation that
just needs a goto.
Can anyone think of a solution that doesn't use goto, but doesn't
perform redundant checks or repeat instructions?

Regards,
&rzej

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Bo Persson on
restor wrote:
> Hi,
> I need to perform a remove_if algorithm on a boost::ptr_vector. I am
> using boost::ptr_vector to store types that have no copy or clone
> operation. std::remove_if doesn't work due to the lack of copy/clone
> operations. So I wrote my own function. It is possible to write it
> in many ways, but any solution I can think of is worse than the one
> that is using a goto statement.
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> typedef boost::ptr_vector<NonCopyable> VecT;
> typedef boost::function<bool(NonCopyable const&)> FunT;
>
> void removeIf( VecT & list, FunT fun )
> {
> NEXT_DELETION_TARGET_ITERATION:
>
> BOOST_AUTO( it, list.begin() );
> BOOST_AUTO( end, list.end() );
>
> for( ; it != end ; ++it ) {
> if( fun(*it) ) {
> list.release( it );
> goto NEXT_DELETION_TARGET_ITERATION;
> }
> }
> }
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> In addition, I am using a VC++ 2005 compiler that automatically
> checks iterator invelidation, and crashes in runtime for some
> solutions that appeared correct to me.
> I am not sure if I just have a bad day, or if it is a situation that
> just needs a goto.
> Can anyone think of a solution that doesn't use goto, but doesn't
> perform redundant checks or repeat instructions?
>

It could be that you have found a use for goto. It seems to happen
about once every 10 years, or so.

Otherwise I would have expected list.release to return the next
iterator

it = list.release(it);

or that you could increment the iterator before releasing the node

list.release(it++);



Bo Persson



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: restor on

> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> typedef boost::ptr_vector<NonCopyable> VecT;
> typedef boost::function<bool(NonCopyable const&)> FunT;
>
> void removeIf( VecT & list, FunT fun )
> {
> NEXT_DELETION_TARGET_ITERATION:
>
> BOOST_AUTO( it, list.begin() );
> BOOST_AUTO( end, list.end() );
>
> for( ; it != end ; ++it ) {
> if( fun(*it) ) {
> list.release( it );
> goto NEXT_DELETION_TARGET_ITERATION;
> }
> }
> }
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> In addition, I am using a VC++ 2005 compiler that automatically checks
> iterator invelidation, and crashes in runtime for some solutions that
> appeared correct to me.
> I am not sure if I just have a bad day, or if it is a situation that
> just needs a goto.
> Can anyone think of a solution that doesn't use goto, but doesn't
> perform redundant checks or repeat instructions?


It looks like I did have a bad day. A simple code:

void removeIf( VecT & list, FunT fun )
{
list.erease_if( fun );
}

does just it.
Regards,
&rzej


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 | 
Pages: 1
Prev: comparing iterators
Next: How to convert C to C++?