Fix PR32642 - string::insert and string::append don't work with move_iterator.

llvm-svn: 300397
This commit is contained in:
Eric Fiselier 2017-04-15 06:49:02 +00:00
parent 4d53a1cb31
commit e84fcb5f3d
3 changed files with 51 additions and 6 deletions

View File

@ -2276,7 +2276,9 @@ basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe(
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
if (__n) if (__n)
{ {
if ( __ptr_in_range(&*__first, data(), data() + size())) typedef typename iterator_traits<_ForwardIterator>::reference _CharRef;
_CharRef __tmp_ref = *__first;
if (__ptr_in_range(_VSTD::addressof(__tmp_ref), data(), data() + size()))
{ {
const basic_string __temp (__first, __last, __alloc()); const basic_string __temp (__first, __last, __alloc());
append(__temp.data(), __temp.size()); append(__temp.data(), __temp.size());
@ -2440,7 +2442,9 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
if (__n) if (__n)
{ {
if ( __ptr_in_range(&*__first, data(), data() + size())) typedef typename iterator_traits<_ForwardIterator>::reference _CharRef;
_CharRef __tmp_char = *__first;
if (__ptr_in_range(_VSTD::addressof(__tmp_char), data(), data() + size()))
{ {
const basic_string __temp(__first, __last, __alloc()); const basic_string __temp(__first, __last, __alloc());
return insert(__pos, __temp.data(), __temp.data() + __temp.size()); return insert(__pos, __temp.data(), __temp.data() + __temp.size());

View File

@ -204,4 +204,20 @@ int main()
assert(s == "ABCD"); assert(s == "ABCD");
} }
{ // test with a move iterator that returns char&&
typedef forward_iterator<const char*> It;
typedef std::move_iterator<It> MoveIt;
const char p[] = "ABCD";
std::string s;
s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
assert(s == "ABCD");
}
{ // test with a move iterator that returns char&&
typedef const char* It;
typedef std::move_iterator<It> MoveIt;
const char p[] = "ABCD";
std::string s;
s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
assert(s == "ABCD");
}
} }

View File

@ -194,4 +194,29 @@ int main()
s.insert(s.begin(), p, p + 4); s.insert(s.begin(), p, p + 4);
assert(s == "ABCD"); assert(s == "ABCD");
} }
{ // test with a move iterator that returns char&&
typedef input_iterator<const char*> It;
typedef std::move_iterator<It> MoveIt;
const char p[] = "ABCD";
std::string s;
s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
assert(s == "ABCD");
}
{ // test with a move iterator that returns char&&
typedef forward_iterator<const char*> It;
typedef std::move_iterator<It> MoveIt;
const char p[] = "ABCD";
std::string s;
s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
assert(s == "ABCD");
}
{ // test with a move iterator that returns char&&
typedef const char* It;
typedef std::move_iterator<It> MoveIt;
const char p[] = "ABCD";
std::string s;
s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
assert(s == "ABCD");
}
} }