www.digitalmars.com         C & C++   DMDScript  

c++.stlsoft - Interesting? Maybe even for 1.7.1?

reply "Anton Sekeris" <no.spam inter.nl.net> writes:
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);
}
Mar 10 2004
parent reply "Matthew" <matthew stlsoft.org> writes:
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);
 }
Mar 10 2004
parent reply "Anton Sekeris" <no.spam inter.nl.net> writes:
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
 
Mar 15 2004
parent "Matthew" <matthew stlsoft.org> writes:
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
Mar 15 2004