forked from boostorg/static_string
Simplified insert for iterators, fixed overlapping copies
This commit is contained in:
@ -19,11 +19,15 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Can we use [[nodiscard]]?
|
// Can we use [[nodiscard]]?
|
||||||
|
#ifdef __has_attribute
|
||||||
#if __has_attribute(nodiscard)
|
#if __has_attribute(nodiscard)
|
||||||
#define BOOST_FIXED_STRING_NODISCARD [[nodiscard]]
|
#define BOOST_FIXED_STRING_NODISCARD [[nodiscard]]
|
||||||
#else
|
#else
|
||||||
#define BOOST_FIXED_STRING_NODISCARD
|
#define BOOST_FIXED_STRING_NODISCARD
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
#define BOOST_FIXED_STRING_NODISCARD
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BOOST_FIXED_STRING_USE_BOOST
|
#ifdef BOOST_FIXED_STRING_USE_BOOST
|
||||||
#include <boost/utility/string_view.hpp>
|
#include <boost/utility/string_view.hpp>
|
||||||
|
@ -194,7 +194,11 @@ 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::copy(&s_[0], s, n_);
|
// check for overlap, then move if needed
|
||||||
|
if (s <= &s_[size()] && s >= &s_[0])
|
||||||
|
Traits::move(&s_[0], s, n_);
|
||||||
|
else
|
||||||
|
Traits::copy(&s_[0], s, n_);
|
||||||
term();
|
term();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -373,20 +377,8 @@ insert(
|
|||||||
detail::is_input_iterator<
|
detail::is_input_iterator<
|
||||||
InputIt>::value, iterator>::type
|
InputIt>::value, iterator>::type
|
||||||
{
|
{
|
||||||
std::size_t const count = std::distance(first, last);
|
const size_type index = pos - begin();
|
||||||
if(size() + count > max_size())
|
return insert(index, &*first, std::distance(first, last)).begin() + index;
|
||||||
BOOST_FIXED_STRING_THROW(std::length_error{
|
|
||||||
"size() + count > max_size()"});
|
|
||||||
std::size_t const index = pos - begin();
|
|
||||||
if (&*first <= &s_[size()] && &*first >= &s_[0])
|
|
||||||
return insert(index, &*first, count).begin() + index;
|
|
||||||
Traits::move(&s_[index + count], &s_[index], size() - index);
|
|
||||||
for(auto it = begin() + index;
|
|
||||||
first != last; ++it, ++first)
|
|
||||||
Traits::assign(*it, *first);
|
|
||||||
n_ += count;
|
|
||||||
term();
|
|
||||||
return begin() + index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
@ -607,14 +599,17 @@ replace(
|
|||||||
return *this;
|
return *this;
|
||||||
if (!inside || (inside && (&s[n2 - 1] < &s_[pos])))
|
if (!inside || (inside && (&s[n2 - 1] < &s_[pos])))
|
||||||
{
|
{
|
||||||
|
// source outside
|
||||||
Traits::move(&s_[pos + n2], &s_[pos + n1], size() - pos - n1 + 1);
|
Traits::move(&s_[pos + n2], &s_[pos + n1], size() - pos - n1 + 1);
|
||||||
Traits::copy(&s_[pos], s, n2);
|
Traits::copy(&s_[pos], s, n2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// source inside
|
||||||
const size_type offset = s - &s_[0];
|
const size_type offset = s - &s_[0];
|
||||||
if (n2 >= n1)
|
if (n2 >= n1)
|
||||||
{
|
{
|
||||||
|
// grow/unchanged
|
||||||
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 = ((pos + n1) - offset) > n2 ? n2 : ((pos + n1) - offset);
|
||||||
Traits::move(&s_[pos], &s_[offset], diff);
|
Traits::move(&s_[pos], &s_[offset], diff);
|
||||||
@ -622,8 +617,9 @@ replace(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// shrink
|
||||||
Traits::move(&s_[pos], &s_[offset], n2);
|
Traits::move(&s_[pos], &s_[offset], n2);
|
||||||
Traits::copy(&s_[pos + n2], &s_[pos + n1], size() - pos - n1 + 1);
|
Traits::move(&s_[pos + n2], &s_[pos + n1], size() - pos - n1 + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n_ += (n2 - n1);
|
n_ += (n2 - n1);
|
||||||
|
Reference in New Issue
Block a user