Fixed small bug in replace

This commit is contained in:
Krystian Stasiowski
2019-10-31 16:42:04 -04:00
parent 71804b8acf
commit 1d2fbacc31
3 changed files with 40 additions and 29 deletions

View File

@ -472,14 +472,14 @@ public:
CharT* CharT*
data() noexcept data() noexcept
{ {
return &s_[0]; return s_;
} }
/// Returns a pointer to the first character of a string. /// Returns a pointer to the first character of a string.
CharT const* CharT const*
data() const noexcept data() const noexcept
{ {
return &s_[0]; return s_;
} }
/// Returns a non-modifiable standard C character array version of the string. /// Returns a non-modifiable standard C character array version of the string.
@ -506,21 +506,21 @@ public:
iterator iterator
begin() noexcept begin() noexcept
{ {
return &s_[0]; return s_;
} }
/// Returns an iterator to the beginning. /// Returns an iterator to the beginning.
const_iterator const_iterator
begin() const noexcept begin() const noexcept
{ {
return &s_[0]; return s_;
} }
/// Returns an iterator to the beginning. /// Returns an iterator to the beginning.
const_iterator const_iterator
cbegin() const noexcept cbegin() const noexcept
{ {
return &s_[0]; return s_;
} }
/// Returns an iterator to the end. /// Returns an iterator to the end.
@ -1147,7 +1147,7 @@ public:
fixed_string<M, CharT, Traits> const& s) const fixed_string<M, CharT, Traits> const& s) const
{ {
return detail::lexicographical_compare<CharT, Traits>( return detail::lexicographical_compare<CharT, Traits>(
&s_[0], n_, &s.s_[0], s.n_); s_, n_, &s.s_[0], s.n_);
} }
template<std::size_t M> template<std::size_t M>
@ -1179,7 +1179,7 @@ public:
CharT const* s) const CharT const* s) const
{ {
return detail::lexicographical_compare<CharT, Traits>( return detail::lexicographical_compare<CharT, Traits>(
&s_[0], n_, s, Traits::length(s)); s_, n_, s, Traits::length(s));
} }
int int
@ -1208,7 +1208,7 @@ public:
string_view_type s) const string_view_type s) const
{ {
return detail::lexicographical_compare<CharT, Traits>( return detail::lexicographical_compare<CharT, Traits>(
&s_[0], n_, s.data(), s.size()); s_, n_, s.data(), s.size());
} }
int int

View File

@ -73,7 +73,7 @@ fixed_string(CharT const* s)
BOOST_FIXED_STRING_THROW(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"count > max_size()"}); "count > max_size()"});
n_ = count; n_ = count;
Traits::copy(&s_[0], s, n_ + 1); Traits::copy(s_, s, n_ + 1);
} }
template<std::size_t N, typename CharT, typename Traits> template<std::size_t N, typename CharT, typename Traits>
@ -146,7 +146,7 @@ assign(
BOOST_FIXED_STRING_THROW(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"count > max_size()"}); "count > max_size()"});
n_ = count; n_ = count;
Traits::assign(&s_[0], n_, ch); Traits::assign(s_, n_, ch);
term(); term();
return *this; return *this;
} }
@ -164,7 +164,7 @@ assign(
auto const n = n_ + 1; auto const n = n_ + 1;
// VFALCO This informs the static analyzer // VFALCO This informs the static analyzer
//BOOST_BEAST_ASSUME(n != 0); //BOOST_BEAST_ASSUME(n != 0);
Traits::copy(&s_[0], &s.s_[0], n); Traits::copy(s_, &s.s_[0], n);
return *this; return *this;
} }
@ -195,10 +195,10 @@ assign(
"count > max_size()"}); "count > max_size()"});
n_ = count; n_ = count;
// check for overlap, then move if needed // check for overlap, then move if needed
if (s <= &s_[size()] && s >= &s_[0]) if (s <= &s_[size()] && s >= s_)
Traits::move(&s_[0], s, n_); Traits::move(s_, s, n_);
else else
Traits::copy(&s_[0], s, n_); Traits::copy(s_, s, n_);
term(); term();
return *this; return *this;
} }
@ -219,7 +219,7 @@ assign(
BOOST_FIXED_STRING_THROW(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"n > max_size()"}); "n > max_size()"});
n_ = n; n_ = n;
for(auto it = &s_[0]; first != last; ++it, ++first) for(auto it = s_; first != last; ++it, ++first)
Traits::assign(*it, *first); Traits::assign(*it, *first);
term(); term();
return *this; return *this;
@ -319,7 +319,7 @@ insert(
if(size() + count > max_size()) if(size() + count > max_size())
BOOST_FIXED_STRING_THROW(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"size() + count > max_size()"}); "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))) if (!inside || (inside && ((s - s_) + count <= index)))
{ {
Traits::move(&s_[index + count], &s_[index], size() - index + 1); Traits::move(&s_[index + count], &s_[index], size() - index + 1);
@ -327,7 +327,7 @@ insert(
} }
else else
{ {
const size_type offset = s - &s_[0]; const size_type offset = s - s_;
Traits::move(&s_[index + count], &s_[index], size() - index + 1); Traits::move(&s_[index + count], &s_[index], size() - index + 1);
if (offset < index) if (offset < index)
{ {
@ -356,7 +356,7 @@ insert(
if(size() + count > max_size()) if(size() + count > max_size())
BOOST_FIXED_STRING_THROW(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"size() + count() > max_size()"}); "size() + count() > max_size()"});
auto const index = pos - &s_[0]; auto const index = pos - s_;
Traits::move( Traits::move(
&s_[index + count], &s_[index], size() - index); &s_[index + count], &s_[index], size() - index);
n_ += count; n_ += count;
@ -553,9 +553,9 @@ swap(fixed_string& s)
{ {
fixed_string tmp(s); fixed_string tmp(s);
s.n_ = n_; s.n_ = n_;
Traits::copy(&s.s_[0], &s_[0], n_ + 1); Traits::copy(&s.s_[0], s_, n_ + 1);
n_ = tmp.n_; n_ = tmp.n_;
Traits::copy(&s_[0], &tmp.s_[0], n_ + 1); Traits::copy(s_, &tmp.s_[0], n_ + 1);
} }
template<std::size_t N, typename CharT, typename Traits> template<std::size_t N, typename CharT, typename Traits>
@ -572,9 +572,9 @@ swap(fixed_string<M, CharT, Traits>& s)
"s.size() > max_size()"}); "s.size() > max_size()"});
fixed_string tmp(s); fixed_string tmp(s);
s.n_ = n_; s.n_ = n_;
Traits::copy(&s.s_[0], &s_[0], n_ + 1); Traits::copy(&s.s_[0], s_, n_ + 1);
n_ = tmp.n_; n_ = tmp.n_;
Traits::copy(&s_[0], &tmp.s_[0], n_ + 1); Traits::copy(s_, &tmp.s_[0], n_ + 1);
} }
template<std::size_t N, typename CharT, typename Traits> template<std::size_t N, typename CharT, typename Traits>
@ -594,8 +594,8 @@ replace(
"replaced string exceeds max_size()"}); "replaced string exceeds max_size()"});
if (pos + n1 >= size()) if (pos + n1 >= size())
n1 = size() - pos; n1 = size() - pos;
const bool inside = s <= &s_[size()] && s >= &s_[0]; const bool inside = s <= &s_[size()] && s >= s_;
if (inside && (s - &s_[0]) == pos && n1 == n2) if (inside && size_type(s - s_) == pos && n1 == n2)
return *this; return *this;
if (!inside || (inside && ((s - s_) + n2 <= pos))) if (!inside || (inside && ((s - s_) + n2 <= pos)))
{ {
@ -606,19 +606,24 @@ replace(
else else
{ {
// source inside // source inside
const size_type offset = s - &s_[0]; const size_type offset = s - s_;
if (n2 >= n1) if (n2 >= n1)
{ {
// grow/unchanged // 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); 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], &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 else
{ {
// shrink // shrink
// copy all elements into place
Traits::move(&s_[pos], &s_[offset], n2); 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); Traits::move(&s_[pos + n2], &s_[pos + n1], size() - pos - n1 + 1);
} }
} }

View File

@ -297,6 +297,9 @@ testConstruct()
(fixed_string<2>(std::string("12345"), 1, 3)), (fixed_string<2>(std::string("12345"), 1, 3)),
std::length_error); std::length_error);
} }
{
BOOST_TEST_THROWS(fixed_string<5>("12345678"), std::length_error);
}
} }
//done //done
@ -5640,7 +5643,7 @@ testFind()
void void
testReplace() 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"; fixed_string<20> fs1 = "helloworld";
BOOST_TEST(fs1.replace(5, 2, fs1.data() + 1, 8) == "helloelloworlrld"); BOOST_TEST(fs1.replace(5, 2, fs1.data() + 1, 8) == "helloelloworlrld");
@ -5693,7 +5696,10 @@ testReplace()
fixed_string<20> fs1 = "helloworld"; fixed_string<20> fs1 = "helloworld";
BOOST_TEST(fs1.replace(4, 3, fs1.data() + 1, 3) == "hellellrld"); 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); // replace(size_type pos1, size_type n1, const basic_string& str);
{ {
fixed_string<20> fs1 = "helloworld"; fixed_string<20> fs1 = "helloworld";