Is std::string::npos portably incrementable?

M

Marcus Kwok

Is std::string::npos portably able to be incremented?

For example, I want to insert some text into a string. If a certain
character is found, I want to insert this text immediately after this
character; otherwise I insert at the beginning of the string. On my
implementation string::npos has the value of (string::size_type)-1, so
incrementing it will make it 0, but can I rely on it?

Also, say that the character occurs at the end of the string. Is it
valid to specify the insert position as one greater than this value?

Example usage of what I want to do is shown in fix_path(). Everything
behaves as I would expect on my implementation (VS 2005).


#include <iostream>
#include <string>

void fix_path(std::string& s)
{
using std::string;

string to_insert = "goes/";
string::size_type pos = s.rfind('/');
s.insert(pos + 1, to_insert);
}

void test(const std::string& s)
{
using std::cout;
using std::string;

string t(s);
cout << t << '\n';
fix_path(t);
cout << t << "\n\n";
}

int main()
{
using std::cout;
using std::string;

test("my/stuff/here");
test("here");
test("another/");
test("/beginning");
}


/*
Output:
my/stuff/here
my/stuff/goes/here

here
goes/here

another/
another/goes/

/beginning
/goes/beginning
*/
 
F

Fei Liu

Marcus said:
Is std::string::npos portably able to be incremented?

For example, I want to insert some text into a string. If a certain
character is found, I want to insert this text immediately after this
character; otherwise I insert at the beginning of the string. On my
implementation string::npos has the value of (string::size_type)-1, so
incrementing it will make it 0, but can I rely on it?

Also, say that the character occurs at the end of the string. Is it
valid to specify the insert position as one greater than this value?

Example usage of what I want to do is shown in fix_path(). Everything
behaves as I would expect on my implementation (VS 2005).


#include <iostream>
#include <string>

void fix_path(std::string& s)
{
using std::string;

string to_insert = "goes/";
string::size_type pos = s.rfind('/');
s.insert(pos + 1, to_insert);
}

void test(const std::string& s)
{
using std::cout;
using std::string;

string t(s);
cout << t << '\n';
fix_path(t);
cout << t << "\n\n";
}

int main()
{
using std::cout;
using std::string;

test("my/stuff/here");
test("here");
test("another/");
test("/beginning");
}


/*
Output:
my/stuff/here
my/stuff/goes/here

here
goes/here

another/
another/goes/

/beginning
/goes/beginning
*/
Would boost::regex_replace be a better choice in this case?

Fei
 
M

Marcus Kwok

Fei Liu said:
Would boost::regex_replace be a better choice in this case?

Looking at the documentation for it, it seems it only gives you the
option to replace all occurrences or only the first occurrence; however
I am not replacing, but inserting, and I am inserting at the last
occurrence.

Also, I can not guarantee that Boost will necessarily be available for
the people using this, especially since the Standard Library covers this
usage.
 
O

Obnoxious User

Is std::string::npos portably able to be incremented?

For example, I want to insert some text into a string. If a certain
character is found, I want to insert this text immediately after this
character; otherwise I insert at the beginning of the string. On my
implementation string::npos has the value of (string::size_type)-1, so
incrementing it will make it 0, but can I rely on it?

Most likely yes, since the standard defines 'npos' as:
static const size_type npos = -1;

And 'size_type' is:
typedef typename Allocator::size_type size_type;
 
V

Victor Bazarov

Marcus said:
Is std::string::npos portably able to be incremented?

By definition, npos is 'size_type' and has the value -1. See 21.3/6.
For example, I want to insert some text into a string. If a certain
character is found, I want to insert this text immediately after this
character; otherwise I insert at the beginning of the string. On my
implementation string::npos has the value of (string::size_type)-1

It is required to be that on all implementations.
, so
incrementing it will make it 0, but can I rely on it?

I believe so.

V
 
J

John Harrison

Marcus said:
Thanks. Do know the answer to my other question (whether or not it is
well-defined to specify s.size() as the insert position for string)?

It's well defined.

john
 
M

Marcus Kwok

Victor Bazarov said:
I believe so.

Thanks. Do know the answer to my other question (whether or not it is
well-defined to specify s.size() as the insert position for string)?
 
J

James Kanze

Is std::string::npos portably able to be incremented?

The obvious answer is that it's a constant, and you can't
increment a constant. But from the rest of your post, I gather
that what you really want to know is whether npos + 1 is
guaranteed to be zero.

Technically, the answer is no. npos is guaranteed to have the
value (size_t)(-1), and size_t is guaranteed to be an unsigned
type, so the value would be guaranteed to be 0, unless integral
promotion occurs. However:

-- I've never heard of an implementation where size_t was
smaller than an unsigned int, so integral promotion won't
occur, and

-- even if integral promotion occurs, if you immediately
reconvert the results back to a size_t, you're guaranteed to
end up with 0.

So in practice, I think you can count on it.
 
M

Marcus Kwok

James Kanze said:
On Jun 29, 5:14 pm, (e-mail address removed) (Marcus Kwok) wrote:
-- even if integral promotion occurs, if you immediately
reconvert the results back to a size_t, you're guaranteed to
end up with 0.

So in practice, I think you can count on it.

Thanks for the confirmation. I am just using it as the parameter for
string::insert(), which is of size_type, so I should be fine.
 

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,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top