O_o
I think you'll have to find some other name; what you describe is very definitely not a range iterator, but is instead a kind of insertion iterator; then, 'range_inserter' is probably a good name.
But even so, right now I'm working on something even more intriguing which actually might (or might have) benefited the standard library.
The STL already supports this goal by providing many generic functions. You only need a better interface--because as I've said, it can be verbose.
The code I provided below should work, but it isn't tested either.
Edit: In retrospect, the container type should be a required template parameter--not derived from a function parameter. With this is mind the function could take the target contents as a range, as for the old and new contents, and return an iterator to the last element yielding the much more sophisticated:
Code:
my_container_instance.erase(replace_range<my_container_type>(my_container_instance.begin(), my_container_instance.end(), old_contents.begin(), old_contents.end(), new_contents.begin(), new_contents.end()), my_container_instance.end());
Which has the bonus of allowing 'replace_range_all' to be written quite simply.
Soma
Code:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
template
<
typename element_F
>
struct rollover
{
element_F operator ()
(
const element_F & value_f
)
{
return(value_f);
}
};
template
<
typename element_F
>
struct rollover_left
{
element_F operator ()
(
const element_F & value_f,
const element_F & ignored_f
)
{
return(value_f);
}
};
template
<
typename element_F
>
struct rollover_right
{
element_F operator ()
(
const element_F & ignored_f,
const element_F & value_f
)
{
return(value_f);
}
};
template
<
typename container_F
>
void replace_range
(
container_F & container_f,
const typename container_F::const_iterator old_contents_beginning,
const typename container_F::const_iterator old_contents_ending,
const typename container_F::const_iterator new_contents_beginning,
const typename container_F::const_iterator new_contents_ending
)
{
const typename container_F::difference_type old_contents_size(std::distance(old_contents_beginning, old_contents_ending));
const typename container_F::difference_type new_contents_size(std::distance(new_contents_beginning, new_contents_ending));
if(old_contents_size >= new_contents_size)
{
typename container_F::iterator modifier(std::search(container_f.begin(), container_f.end(), old_contents_beginning, old_contents_ending));
typename container_F::iterator container_cursor(std::transform(new_contents_beginning, new_contents_ending, modifier, rollover<typename container_F::value_type>()));
std::advance(modifier, new_contents_size);
std::advance(container_cursor, old_contents_size - new_contents_size);
container_f.erase(std::copy(container_cursor, container_f.end(), modifier), container_f.end());
}
else
{
typename container_F::iterator container_cursor(std::search(container_f.begin(), container_f.end(), old_contents_beginning, old_contents_ending));
container_cursor = std::transform(old_contents_beginning, old_contents_ending, new_contents_beginning, container_cursor, rollover_right<typename container_F::value_type>());
std::insert_iterator<container_F> modifier(container_f, container_cursor);
typename container_F::const_iterator replacement_cursor(new_contents_beginning);
std::advance(replacement_cursor, old_contents_size);
std::copy(replacement_cursor, new_contents_ending, modifier);
}
}
int main()
{
std::string message("This is a test.");
std::string is(" is ");
std::string correction(" is not ");
replace_range(message, is.begin(), is.end(), correction.begin(), correction.end());
std::copy(message.begin(), message.end(), std::ostream_iterator<std::string::value_type>(std::cout, ""));
std::cout << '\n';
replace_range(message, correction.begin(), correction.end(), is.begin(), is.end());
std::copy(message.begin(), message.end(), std::ostream_iterator<std::string::value_type>(std::cout, ""));
std::cout << '\n';
return(0);
}