diff options
13 files changed, 226 insertions, 13 deletions
diff --git a/libcxx/include/string b/libcxx/include/string index 53ddf5e3bfb..cfae0c84c7f 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1998,7 +1998,7 @@ typename enable_if >::type basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) { - basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc()); assign(__temp.data(), __temp.size()); return *this; } @@ -2151,11 +2151,17 @@ typename enable_if >::type basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last) { - basic_string __temp (__first, __last, __alloc()); + const basic_string __temp (__first, __last, __alloc()); append(__temp.data(), __temp.size()); return *this; } +template <typename _Tp> +bool __ptr_in_range (const _Tp* __p, const _Tp* __first, const _Tp* __last) +{ + return __first <= __p && __p < __last; +} + template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> typename enable_if @@ -2171,13 +2177,21 @@ basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _For size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n) { - if (__cap - __sz < __n) - __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); - pointer __p = __get_pointer() + __sz; - for (; __first != __last; ++__p, ++__first) - traits_type::assign(*__p, *__first); - traits_type::assign(*__p, value_type()); - __set_size(__sz + __n); + if ( __ptr_in_range(&*__first, data(), data() + size())) + { + const basic_string __temp (__first, __last, __alloc()); + append(__temp.data(), __temp.size()); + } + else + { + if (__cap - __sz < __n) + __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); + pointer __p = __get_pointer() + __sz; + for (; __first != __last; ++__p, ++__first) + traits_type::assign(*__p, *__first); + traits_type::assign(*__p, value_type()); + __set_size(__sz + __n); + } } return *this; } @@ -2299,7 +2313,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIt "string::insert(iterator, range) called with an iterator not" " referring to this string"); #endif - basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc()); return insert(__pos, __temp.data(), __temp.data() + __temp.size()); } @@ -2319,11 +2333,17 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward " referring to this string"); #endif size_type __ip = static_cast<size_type>(__pos - begin()); - size_type __sz = size(); - size_type __cap = capacity(); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n) { + if ( __ptr_in_range(&*__first, data(), data() + size())) + { + const basic_string __temp(__first, __last, __alloc()); + return insert(__pos, __temp.data(), __temp.data() + __temp.size()); + } + + size_type __sz = size(); + size_type __cap = capacity(); value_type* __p; if (__cap - __sz >= __n) { @@ -2523,7 +2543,7 @@ typename enable_if basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) { - basic_string __temp(__j1, __j2, __alloc()); + const basic_string __temp(__j1, __j2, __alloc()); return this->replace(__i1, __i2, __temp); } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp index 55fc63d0621..8c54a383269 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp @@ -178,4 +178,21 @@ int main() test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter()); } #endif + + { // test appending to self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.append(s_short.begin(), s_short.end()); + assert(s_short == "123/123/"); + s_short.append(s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/"); + s_short.append(s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.append(s_long.begin(), s_long.end()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } + } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp index 7c45068a53e..e658d0f9423 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp @@ -61,4 +61,20 @@ int main() S("1234567890123456789012345678901234567890")); } #endif + + { // test appending to self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.append(s_short.c_str()); + assert(s_short == "123/123/"); + s_short.append(s_short.c_str()); + assert(s_short == "123/123/123/123/"); + s_short.append(s_short.c_str()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.append(s_long.c_str()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp index 6c594ebac3b..25a4526fd32 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp @@ -70,4 +70,20 @@ int main() S("1234567890123456789012345678901234567890")); } #endif + + { // test appending to self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.append(s_short.data(), s_short.size()); + assert(s_short == "123/123/"); + s_short.append(s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/"); + s_short.append(s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.append(s_long.data(), s_long.size()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp index e6a57519f34..0d3dac74308 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp @@ -179,4 +179,21 @@ int main() test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter()); } #endif + + { // test assigning to self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.assign(s_short.begin(), s_short.end()); + assert(s_short == "123/"); + s_short.assign(s_short.begin() + 2, s_short.end()); + assert(s_short == "3/"); + + s_long.assign(s_long.begin(), s_long.end()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/"); + + s_long.assign(s_long.begin() + 30, s_long.end()); + assert(s_long == "nsectetur/"); + } } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp index 386dee6d580..1a509e742e2 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp @@ -61,4 +61,18 @@ int main() S("12345678901234567890")); } #endif + + { // test assignment to self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.assign(s_short.c_str()); + assert(s_short == "123/"); + s_short.assign(s_short.c_str() + 2); + assert(s_short == "3/"); + + s_long.assign(s_long.c_str() + 30); + assert(s_long == "nsectetur/"); + } } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp index 0eeb9266f40..b657127d3c0 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp @@ -70,4 +70,20 @@ int main() S("12345678901234567890")); } #endif + { // test assign to self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.assign(s_short.data(), s_short.size()); + assert(s_short == "123/"); + s_short.assign(s_short.data() + 2, s_short.size() - 2); + assert(s_short == "3/"); + + s_long.assign(s_long.data(), s_long.size()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/"); + + s_long.assign(s_long.data() + 2, 8 ); + assert(s_long == "rem ipsu"); + } } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp index bbae39419da..1b5baf4f4c4 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp @@ -169,4 +169,21 @@ int main() assert(false); } #endif + + { // test inserting into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.insert(s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/"); + s_short.insert(s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/"); + s_short.insert(s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.insert(s_long.begin(), s_long.begin(), s_long.end()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } + } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp index faab5bd9267..3b1c2cbd727 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp @@ -210,4 +210,20 @@ int main() test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", S("can't happen")); } #endif + + { // test inserting into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.insert(0, s_short.c_str()); + assert(s_short == "123/123/"); + s_short.insert(0, s_short.c_str()); + assert(s_short == "123/123/123/123/"); + s_short.insert(0, s_short.c_str()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.insert(0, s_long.c_str()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp index 30d3df9f259..554b93cdce1 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp @@ -691,4 +691,20 @@ int main() test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 20, S("can't happen")); } #endif + + { // test inserting into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.insert(0, s_short.data(), s_short.size()); + assert(s_short == "123/123/"); + s_short.insert(0, s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/"); + s_short.insert(0, s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.insert(0, s_long.data(), s_long.size()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp index cc37e79c793..abf15217f9d 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp @@ -1007,4 +1007,20 @@ int main() test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 6, TIter::TAComparison), TIter()); } #endif + + { // test replacing into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.replace(s_short.begin(), s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.begin(), s_short.end()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.replace(s_long.begin(), s_long.begin(), s_long.begin(), s_long.end()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp index 730fc1a501c..20d185f399f 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp @@ -282,4 +282,20 @@ int main() test2<S>(); } #endif + + { // test replacing into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.replace(s_short.begin(), s_short.begin(), s_short.c_str()); + assert(s_short == "123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.c_str()); + assert(s_short == "123/123/123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.c_str()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.replace(s_long.begin(), s_long.begin(), s_long.c_str()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } } diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp index 4a910e49981..59d34fef26c 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp @@ -972,4 +972,20 @@ int main() test8<S>(); } #endif + + { // test replacing into self + typedef std::string S; + S s_short = "123/"; + S s_long = "Lorem ipsum dolor sit amet, consectetur/"; + + s_short.replace(s_short.begin(), s_short.begin(), s_short.data(), s_short.size()); + assert(s_short == "123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/"); + s_short.replace(s_short.begin(), s_short.begin(), s_short.data(), s_short.size()); + assert(s_short == "123/123/123/123/123/123/123/123/"); + + s_long.replace(s_long.begin(), s_long.begin(), s_long.data(), s_long.size()); + assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); + } } |