"Shifted" insert in std::string

E

Eric Lilja

Is there something "elegant" in the standard library I can use to
perform a "shifted insert" in a std::string? Let me examplify what I
mean with shifted insert.

Say I have:
std::string foo = "abc";

std::string shifted_foo = shifted_insert(foo, 'd');

shifted_foo should after the shifted_insert() equal "dab".
The char 'd' is inserted first, pushing everything up one index but
the size of the string should remain the same so in effect the last
char 'c' is pushed off the edge.

Doing this manually is relatively easy but I wanted to check if I'm
missing out on something in the standard library.

Thanks for any replies.

- Eric
 
V

Victor Bazarov

Eric said:
Is there something "elegant" in the standard library I can use to
perform a "shifted insert" in a std::string? Let me examplify what I
mean with shifted insert.

Say I have:
std::string foo = "abc";

std::string shifted_foo = shifted_insert(foo, 'd');

shifted_foo should after the shifted_insert() equal "dab".
The char 'd' is inserted first, pushing everything up one index but
the size of the string should remain the same so in effect the last
char 'c' is pushed off the edge.

Doing this manually is relatively easy but I wanted to check if I'm
missing out on something in the standard library.

No, you're not missing anything. This functionality is not something
that is often in demand (at least in my POV), there is no place for
it in the standard library.

V
 
K

Kai-Uwe Bux

Eric said:
Is there something "elegant" in the standard library I can use to
perform a "shifted insert" in a std::string? Let me examplify what I
mean with shifted insert.

Say I have:
std::string foo = "abc";

std::string shifted_foo = shifted_insert(foo, 'd');

shifted_foo should after the shifted_insert() equal "dab".
The char 'd' is inserted first, pushing everything up one index but
the size of the string should remain the same so in effect the last
char 'c' is pushed off the edge.

Doing this manually is relatively easy but I wanted to check if I'm
missing out on something in the standard library.

Nope, it's not there. But, as you said, it's easy to build it on top of what
is there:

#include <algorithm>

template < typename Cont, typename Value >
Cont shifted_insert( Cont the_cont, Value const & val ) {
std::rotate( the_cont.begin(), --the_cont.end(), the_cont.end() );
*the_cont.begin() = val;
return ( the_cont );
}

#include <string>
#include <iostream>

int main ( void ) {
std::string foo = "abc";
std::cout << shifted_insert( foo, 'd' ) << '\n';
}


Best

Kai-Uwe Bux
 
R

red floyd

Kai-Uwe Bux said:
Nope, it's not there. But, as you said, it's easy to build it on top of what
is there:

#include <algorithm>

template < typename Cont, typename Value >
Cont shifted_insert( Cont the_cont, Value const & val ) {
std::rotate( the_cont.begin(), --the_cont.end(), the_cont.end() );

Would this be better?

std:;rotate( the_cont.begin(), the_cont.rbegin().base(),
the_cont.end());

I just don't like the predecrement on a function return. I know,
personal taste.
 
K

Kai-Uwe Bux

red said:
Would this be better?

std:;rotate( the_cont.begin(), the_cont.rbegin().base(),
the_cont.end());

I just don't like the predecrement on a function return. I know,
personal taste.

Thanks, you are right. And it's probably not just taste. The way you wrote
it will guarantee the template to work even with vector containers that
have naked pointers for iterators. In that way, your version has smaller
conceptual requirements than mine.


Best

Kai-Uwe Bux
 
E

Eric Lilja

Nope, it's not there. But, as you said, it's easy to build it on top of what
is there:

#include <algorithm>

template < typename Cont, typename Value >
Cont shifted_insert( Cont the_cont, Value const & val ) {
std::rotate( the_cont.begin(), --the_cont.end(), the_cont.end() );
*the_cont.begin() = val;
return ( the_cont );

}

#include <string>
#include <iostream>

int main ( void ) {
std::string foo = "abc";
std::cout << shifted_insert( foo, 'd' ) << '\n';

}

Best

Kai-Uwe Bux

Thanks for the code, Kai, and also Victor for his reply. I agree that
it's rare that you need this so I'm not surprised there's no function
in standard library for performing this. I've made some design changes
in my program and no I no longer need to do this but still I've learnt
something.

- Eric
 
J

James Kanze

No, you're not missing anything. This functionality is not something
that is often in demand (at least in my POV), there is no place for
it in the standard library.

It's also extremely easy to do with the existing functionality:

size_t oldSize = foo.size() ;
foo.insert( 0, 1, 'd' ) ;
foo.resize( oldSize ) ;

In practice, the only times I've needed something anything like
this is to maintain a sliding window in e.g. a file, in which
case, the goal is to keep the window a fixed size. In that
case, I'll use deque (which was designed expressedly for this
sort of thing); the design of the STL generally allows
substituting one container for another if you're careful about
what you do with the iterators.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top