Thread overview
Interesting? Maybe even for 1.7.1?
Mar 10, 2004
Anton Sekeris
Mar 10, 2004
Matthew
Mar 15, 2004
Anton Sekeris
Mar 15, 2004
Matthew
March 10, 2004
I have a long story, please bear with me. Today I ran into a problem at work where I needed to splice a list into another list at a given position. I needed the source list to remain intact with all its iterators still valid. I also needed the item pointed to by the iterator before which the second list to be removed. Preferably all iterators on the first list must remain valid as well. If you're still with me: bravo.

An example to illustrate:
list 1: 1 2 3 4 5
list 2: 6 7 8 9 10
when my iterator it reaches the item 3 in list 1, it splices in list 2,
removes item 3 and can resume iterating, thus resulting effectively in
1 2 (3) 6 7 8 9 10 4 5

The practical problem at hand is the parsing of a list of items in which particular items need to be substitued with list of other items when encountered, sort of like parsing macro instances in a source file while traversing a tokenlist.

I didn't find anything in stlsoft doing this or achieving this easily (but I may have overlooked something), so I figured it might be of interest to you/others.

I was in a huge hurry so a quickly hacked out the function below (see also attached source including simple test). Off the bat i'd say it at least needs polishing, error handling and is probably completely wrong, but it works for me at this time. If you want to pick up the idea be my guest. If you have something similar or better to use in stlsoft or elsewhere, please let me know. I prefer using good tested code of regarded others to my own shortsighted hacks.

Kind regards,
Anton Sekeris.

//
// function      : splice_replace
// description   : Splice the specified range of items (default begin
to end) from oListSrc into rListDest, in front of
//                 the position indicated by rDestPos. The item at
rDestPos itself is removed.
//                 Effectively a given item im the destination list is
replaced by a (range of items from) a source
//                 list.
//
// precondition  : source != destionation. Behaviour is undefined if
source and destination lists are equal
//
// postconditions: - iterators on the destination list should still be
valid
//                 - the iterator passed in as destination will point
at the start of the spliced in range of elements
//                 - the source list and any of its iterators should be
valid and unchanged
//
// notes         : This operation pretty is expensive.
//
template <typename T>
void splice_replace (
  list<T> &rListDest,
  list<T>::iterator& rDestPos,
  list<T> oListSrc,
  list<T>::iterator oBegin = 0,
  list<T>::iterator oEnd = 0
)
{
  list<T>::iterator oBeginLocal = (oBegin == 0 ? oListSrc.begin () :
oBegin);
  list<T>::iterator oEndLocal = (oEnd == 0 ? oListSrc.end () : oEnd);

  int iDist = distance (oBeginLocal, oEndLocal);

  rListDest.splice (rDestPos, oListSrc, oBeginLocal, oEndLocal);
  rListDest.erase (rDestPos);
  advance (rDestPos, -iDist);
}



March 10, 2004
Anton

Just wanted to acknowledge your post. I'll look into it in the next few days and let you know.

Thanks for the interest.

Cheers

Matthew

"Anton Sekeris" <no.spam@inter.nl.net> wrote in message news:c2o2gg$2fsd$1@digitaldaemon.com...
> Matthew,
>
> I have a long story, please bear with me. Today I ran into a problem at work where I needed to splice a list into another list at a given position. I needed the source list to remain intact with all its iterators still valid. I also needed the item pointed to by the iterator before which the second list to be removed. Preferably all iterators on the first list must remain valid as well. If you're still with me: bravo.
>
> An example to illustrate:
> list 1: 1 2 3 4 5
> list 2: 6 7 8 9 10
> when my iterator it reaches the item 3 in list 1, it splices in list 2,
> removes item 3 and can resume iterating, thus resulting effectively in
> 1 2 (3) 6 7 8 9 10 4 5
>
> The practical problem at hand is the parsing of a list of items in which particular items need to be substitued with list of other items when encountered, sort of like parsing macro instances in a source file while traversing a tokenlist.
>
> I didn't find anything in stlsoft doing this or achieving this easily (but I may have overlooked something), so I figured it might be of interest to you/others.
>
> I was in a huge hurry so a quickly hacked out the function below (see also attached source including simple test). Off the bat i'd say it at least needs polishing, error handling and is probably completely wrong, but it works for me at this time. If you want to pick up the idea be my guest. If you have something similar or better to use in stlsoft or elsewhere, please let me know. I prefer using good tested code of regarded others to my own shortsighted hacks.
>
> Kind regards,
> Anton Sekeris.
>
> //
> // function      : splice_replace
> // description   : Splice the specified range of items (default begin
> to end) from oListSrc into rListDest, in front of
> //                 the position indicated by rDestPos. The item at
> rDestPos itself is removed.
> //                 Effectively a given item im the destination list is
> replaced by a (range of items from) a source
> //                 list.
> //
> // precondition  : source != destionation. Behaviour is undefined if
> source and destination lists are equal
> //
> // postconditions: - iterators on the destination list should still be
> valid
> //                 - the iterator passed in as destination will point
> at the start of the spliced in range of elements
> //                 - the source list and any of its iterators should be
> valid and unchanged
> //
> // notes         : This operation pretty is expensive.
> //
> template <typename T>
> void splice_replace (
>   list<T> &rListDest,
>   list<T>::iterator& rDestPos,
>   list<T> oListSrc,
>   list<T>::iterator oBegin = 0,
>   list<T>::iterator oEnd = 0
> )
> {
>   list<T>::iterator oBeginLocal = (oBegin == 0 ? oListSrc.begin () :
> oBegin);
>   list<T>::iterator oEndLocal = (oEnd == 0 ? oListSrc.end () : oEnd);
>
>   int iDist = distance (oBeginLocal, oEndLocal);
>
>   rListDest.splice (rDestPos, oListSrc, oBeginLocal, oEndLocal);
>   rListDest.erase (rDestPos);
>   advance (rDestPos, -iDist);
> }
>
>


March 15, 2004
Matthew,

I think I was having a very bad day when I wrote my splice_replace. I forgot all about using an inserter as a parameter to the STL copy algorithm. Using that and a simple erase to remove the element to replace solves it all. Which makes the entire matter a lot less interesting.

Sorry for wasting your time.

Anton.

P.S. My lapse of sanity was actually pointed out to me by one of my junior engineers. I'll never hear the end of it :-(


Matthew wrote:

> Anton
> 
> Just wanted to acknowledge your post. I'll look into it in the next few days and let you know.
> 
> Thanks for the interest.
> 
> Cheers
> 
> Matthew
> 

March 15, 2004
LOL! I shall congratulate myself for wisely not having expended any effort on it as yet. ;)

"Anton Sekeris" <no.spam@inter.nl.net> wrote in message news:c357m6$cte$1@digitaldaemon.com...
> Matthew,
>
> I think I was having a very bad day when I wrote my splice_replace. I forgot all about using an inserter as a parameter to the STL copy algorithm. Using that and a simple erase to remove the element to replace solves it all. Which makes the entire matter a lot less interesting.
>
> Sorry for wasting your time.
>
> Anton.
>
> P.S. My lapse of sanity was actually pointed out to me by one of my junior engineers. I'll never hear the end of it :-(
>
>
> Matthew wrote:
>
> > Anton
> >
> > Just wanted to acknowledge your post. I'll look into it in the next few days and let you know.
> >
> > Thanks for the interest.
> >
> > Cheers
> >
> > Matthew
> >
>