From 1d2fbacc31ee69624ee8bb71b8f634ac150ae9af Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Thu, 31 Oct 2019 16:42:04 -0400 Subject: [PATCH] Fixed small bug in replace --- include/boost/fixed_string/fixed_string.hpp | 16 +++---- .../boost/fixed_string/impl/fixed_string.hpp | 43 +++++++++++-------- test/fixed_string.cpp | 10 ++++- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/include/boost/fixed_string/fixed_string.hpp b/include/boost/fixed_string/fixed_string.hpp index ed3fc4f..869c8cd 100644 --- a/include/boost/fixed_string/fixed_string.hpp +++ b/include/boost/fixed_string/fixed_string.hpp @@ -472,14 +472,14 @@ public: CharT* data() noexcept { - return &s_[0]; + return s_; } /// Returns a pointer to the first character of a string. CharT const* data() const noexcept { - return &s_[0]; + return s_; } /// Returns a non-modifiable standard C character array version of the string. @@ -506,21 +506,21 @@ public: iterator begin() noexcept { - return &s_[0]; + return s_; } /// Returns an iterator to the beginning. const_iterator begin() const noexcept { - return &s_[0]; + return s_; } /// Returns an iterator to the beginning. const_iterator cbegin() const noexcept { - return &s_[0]; + return s_; } /// Returns an iterator to the end. @@ -1147,7 +1147,7 @@ public: fixed_string const& s) const { return detail::lexicographical_compare( - &s_[0], n_, &s.s_[0], s.n_); + s_, n_, &s.s_[0], s.n_); } template @@ -1179,7 +1179,7 @@ public: CharT const* s) const { return detail::lexicographical_compare( - &s_[0], n_, s, Traits::length(s)); + s_, n_, s, Traits::length(s)); } int @@ -1208,7 +1208,7 @@ public: string_view_type s) const { return detail::lexicographical_compare( - &s_[0], n_, s.data(), s.size()); + s_, n_, s.data(), s.size()); } int diff --git a/include/boost/fixed_string/impl/fixed_string.hpp b/include/boost/fixed_string/impl/fixed_string.hpp index dd2a17f..480529d 100644 --- a/include/boost/fixed_string/impl/fixed_string.hpp +++ b/include/boost/fixed_string/impl/fixed_string.hpp @@ -73,7 +73,7 @@ fixed_string(CharT const* s) BOOST_FIXED_STRING_THROW(std::length_error{ "count > max_size()"}); n_ = count; - Traits::copy(&s_[0], s, n_ + 1); + Traits::copy(s_, s, n_ + 1); } template @@ -146,7 +146,7 @@ assign( BOOST_FIXED_STRING_THROW(std::length_error{ "count > max_size()"}); n_ = count; - Traits::assign(&s_[0], n_, ch); + Traits::assign(s_, n_, ch); term(); return *this; } @@ -164,7 +164,7 @@ assign( auto const n = n_ + 1; // VFALCO This informs the static analyzer //BOOST_BEAST_ASSUME(n != 0); - Traits::copy(&s_[0], &s.s_[0], n); + Traits::copy(s_, &s.s_[0], n); return *this; } @@ -195,10 +195,10 @@ assign( "count > max_size()"}); n_ = count; // check for overlap, then move if needed - if (s <= &s_[size()] && s >= &s_[0]) - Traits::move(&s_[0], s, n_); + if (s <= &s_[size()] && s >= s_) + Traits::move(s_, s, n_); else - Traits::copy(&s_[0], s, n_); + Traits::copy(s_, s, n_); term(); return *this; } @@ -219,7 +219,7 @@ assign( BOOST_FIXED_STRING_THROW(std::length_error{ "n > max_size()"}); n_ = n; - for(auto it = &s_[0]; first != last; ++it, ++first) + for(auto it = s_; first != last; ++it, ++first) Traits::assign(*it, *first); term(); return *this; @@ -319,7 +319,7 @@ insert( if(size() + count > max_size()) BOOST_FIXED_STRING_THROW(std::length_error{ "size() + count > max_size()"}); - const bool inside = s <= &s_[size()] && s >= &s_[0]; + const bool inside = s <= &s_[size()] && s >= s_; if (!inside || (inside && ((s - s_) + count <= index))) { Traits::move(&s_[index + count], &s_[index], size() - index + 1); @@ -327,7 +327,7 @@ insert( } else { - const size_type offset = s - &s_[0]; + const size_type offset = s - s_; Traits::move(&s_[index + count], &s_[index], size() - index + 1); if (offset < index) { @@ -356,7 +356,7 @@ insert( if(size() + count > max_size()) BOOST_FIXED_STRING_THROW(std::length_error{ "size() + count() > max_size()"}); - auto const index = pos - &s_[0]; + auto const index = pos - s_; Traits::move( &s_[index + count], &s_[index], size() - index); n_ += count; @@ -553,9 +553,9 @@ swap(fixed_string& s) { fixed_string tmp(s); s.n_ = n_; - Traits::copy(&s.s_[0], &s_[0], n_ + 1); + Traits::copy(&s.s_[0], s_, n_ + 1); n_ = tmp.n_; - Traits::copy(&s_[0], &tmp.s_[0], n_ + 1); + Traits::copy(s_, &tmp.s_[0], n_ + 1); } template @@ -572,9 +572,9 @@ swap(fixed_string& s) "s.size() > max_size()"}); fixed_string tmp(s); s.n_ = n_; - Traits::copy(&s.s_[0], &s_[0], n_ + 1); + Traits::copy(&s.s_[0], s_, n_ + 1); n_ = tmp.n_; - Traits::copy(&s_[0], &tmp.s_[0], n_ + 1); + Traits::copy(s_, &tmp.s_[0], n_ + 1); } template @@ -594,8 +594,8 @@ replace( "replaced string exceeds max_size()"}); if (pos + n1 >= size()) n1 = size() - pos; - const bool inside = s <= &s_[size()] && s >= &s_[0]; - if (inside && (s - &s_[0]) == pos && n1 == n2) + const bool inside = s <= &s_[size()] && s >= s_; + if (inside && size_type(s - s_) == pos && n1 == n2) return *this; if (!inside || (inside && ((s - s_) + n2 <= pos))) { @@ -606,19 +606,24 @@ replace( else { // source inside - const size_type offset = s - &s_[0]; + const size_type offset = s - s_; if (n2 >= n1) { // grow/unchanged + // shift all right of splice point by n2 - n1 to the right Traits::move(&s_[pos + n2], &s_[pos + n1], size() - pos - n1 + 1); - const size_type diff = ((pos + n1) - offset) > n2 ? n2 : ((pos + n1) - offset); + const size_type diff = offset <= pos + n1 ? (std::min)((pos + n1) - offset, n2) : 0; + // copy all before splice point Traits::move(&s_[pos], &s_[offset], diff); - Traits::move(&s_[pos + diff], &s_[pos + n2], n2 - diff); + // copy all after splice point + Traits::move(&s_[pos + diff], &s_[offset + (n2 - n1) + diff], n2 - diff); } else { // shrink + // copy all elements into place Traits::move(&s_[pos], &s_[offset], n2); + // shift all elements after splice point left Traits::move(&s_[pos + n2], &s_[pos + n1], size() - pos - n1 + 1); } } diff --git a/test/fixed_string.cpp b/test/fixed_string.cpp index b0d05c3..2001957 100644 --- a/test/fixed_string.cpp +++ b/test/fixed_string.cpp @@ -297,6 +297,9 @@ testConstruct() (fixed_string<2>(std::string("12345"), 1, 3)), std::length_error); } + { + BOOST_TEST_THROWS(fixed_string<5>("12345678"), std::length_error); + } } //done @@ -5640,7 +5643,7 @@ testFind() void testReplace() { - // replace(size_type pos1, size_type n1, const charT* s, size_type n2); + // replace(size_type pos1, size_type n1, const charT* s, size_type n2); { fixed_string<20> fs1 = "helloworld"; BOOST_TEST(fs1.replace(5, 2, fs1.data() + 1, 8) == "helloelloworlrld"); @@ -5693,7 +5696,10 @@ testReplace() fixed_string<20> fs1 = "helloworld"; BOOST_TEST(fs1.replace(4, 3, fs1.data() + 1, 3) == "hellellrld"); } - + { + fixed_string<20> fs1 = "helloworld"; + BOOST_TEST_EQ(fs1.replace(0, 1, fs1.data() + 4, 4), fixed_string<20>("oworelloworld")); + } // replace(size_type pos1, size_type n1, const basic_string& str); { fixed_string<20> fs1 = "helloworld";