forked from boostorg/static_string
Fixed exception checks for ranges, less repetition
This commit is contained in:
@ -317,30 +317,7 @@ insert(
|
||||
const auto curr_data = data();
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
index > curr_size, std::out_of_range{"index > size()"});
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
count > max_size() - curr_size, std::length_error{"count > max_size() - size()"});
|
||||
const bool inside = s <= &curr_data[curr_size] && s >= curr_data;
|
||||
if (!inside || (inside && ((s - curr_data) + count <= index)))
|
||||
{
|
||||
Traits::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1);
|
||||
Traits::copy(&curr_data[index], s, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_type offset = s - curr_data;
|
||||
Traits::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1);
|
||||
if (offset < index)
|
||||
{
|
||||
const size_type diff = index - offset;
|
||||
Traits::copy(&curr_data[index], &curr_data[offset], diff);
|
||||
Traits::copy(&curr_data[index + diff], &curr_data[index + count], count - diff);
|
||||
}
|
||||
else
|
||||
{
|
||||
Traits::copy(&curr_data[index], &curr_data[offset + count], count);
|
||||
}
|
||||
}
|
||||
this->set_size(curr_size + count);
|
||||
insert(curr_data + index, s, s + count);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -384,8 +361,6 @@ insert(
|
||||
const auto count = detail::distance(first, last);
|
||||
const auto index = pos - curr_data;
|
||||
const auto s = &*first;
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
index > curr_size, std::out_of_range{"index > size()"});
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
count > max_size() - curr_size, std::length_error{"count > max_size() - size()"});
|
||||
const bool inside = s <= &curr_data[curr_size] && s >= curr_data;
|
||||
@ -410,7 +385,7 @@ insert(
|
||||
}
|
||||
}
|
||||
this->set_size(curr_size + count);
|
||||
return begin() + index;
|
||||
return curr_data + index;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits>
|
||||
@ -649,52 +624,16 @@ replace(
|
||||
size_type pos,
|
||||
size_type n1,
|
||||
const CharT* s,
|
||||
size_type n2) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string<N, CharT, Traits>&
|
||||
size_type n2) BOOST_STATIC_STRING_COND_NOEXCEPT ->
|
||||
basic_static_string<N, CharT, Traits>&
|
||||
{
|
||||
const auto curr_size = size();
|
||||
const auto curr_data = data();
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
pos > curr_size, std::out_of_range{"pos > size()"});
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2,
|
||||
std::length_error{"replaced string exceeds max_size()"});
|
||||
if (pos + n1 >= curr_size)
|
||||
n1 = curr_size - pos;
|
||||
const bool inside = s <= &curr_data[curr_size] && s >= curr_data;
|
||||
if (inside && size_type(s - curr_data) == pos && n1 == n2)
|
||||
return *this;
|
||||
if (!inside || (inside && ((s - curr_data) + n2 <= pos)))
|
||||
{
|
||||
// source outside
|
||||
Traits::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
|
||||
Traits::copy(&curr_data[pos], s, n2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// source inside
|
||||
const size_type offset = s - curr_data;
|
||||
if (n2 >= n1)
|
||||
{
|
||||
// grow/unchanged
|
||||
// shift all right of splice point by n2 - n1 to the right
|
||||
Traits::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
|
||||
const size_type diff = offset <= pos + n1 ? (std::min)((pos + n1) - offset, n2) : 0;
|
||||
// copy all before splice point
|
||||
Traits::move(&curr_data[pos], &curr_data[offset], diff);
|
||||
// copy all after splice point
|
||||
Traits::move(&curr_data[pos + diff], &curr_data[offset + (n2 - n1) + diff], n2 - diff);
|
||||
}
|
||||
else
|
||||
{
|
||||
// shrink
|
||||
// copy all elements into place
|
||||
Traits::move(&curr_data[pos], &curr_data[offset], n2);
|
||||
// shift all elements after splice point left
|
||||
Traits::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
|
||||
}
|
||||
}
|
||||
this->set_size(curr_size + (n2 - n1));
|
||||
return *this;
|
||||
return replace(curr_data + pos, curr_data + pos + n1, s, s + n2);
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits>
|
||||
@ -742,8 +681,6 @@ replace(
|
||||
const std::size_t n2 = detail::distance(j1, j2);
|
||||
const std::size_t pos = i1 - curr_data;
|
||||
const auto s = &*j1;
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
pos > curr_size, std::out_of_range{"pos > size()"});
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2,
|
||||
std::length_error{"replaced string exceeds max_size()"});
|
||||
@ -824,33 +761,6 @@ replace(
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
auto
|
||||
basic_static_string<N, CharT, Traits>::
|
||||
replace(
|
||||
const_iterator i1,
|
||||
const_iterator i2,
|
||||
std::initializer_list<CharT> il) BOOST_STATIC_STRING_COND_NOEXCEPT ->
|
||||
basic_static_string&
|
||||
{
|
||||
const auto curr_size = size();
|
||||
const auto curr_data = data();
|
||||
std::size_t n1 = detail::distance(i1, i2);
|
||||
const std::size_t pos = i1 - curr_data;
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
pos > curr_size, std::out_of_range{"pos > size()"});
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
curr_size - (std::min)(n1, curr_size - pos) >= max_size() - il.size(),
|
||||
std::length_error{"replaced string exceeds max_size()"});
|
||||
if (pos + n1 >= curr_size)
|
||||
n1 = curr_size - pos;
|
||||
Traits::move(&curr_data[pos + il.size()], &curr_data[pos + n1], curr_size - pos - n1 + 1);
|
||||
detail::copy_with_traits<Traits>(il.begin(), il.end(), &curr_data[pos]);
|
||||
this->set_size(curr_size + (il.size() - n1));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
auto
|
||||
@ -1014,6 +924,32 @@ read_back(
|
||||
return new_size - size();
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
auto
|
||||
basic_static_string<N, CharT, Traits>::
|
||||
replace_unchecked(
|
||||
size_type pos,
|
||||
size_type n1,
|
||||
const CharT* s,
|
||||
size_type n2) BOOST_STATIC_STRING_COND_NOEXCEPT ->
|
||||
basic_static_string&
|
||||
{
|
||||
const auto curr_data = data();
|
||||
const auto curr_size = size();
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
pos > curr_size, std::out_of_range{"pos > size()"});
|
||||
BOOST_STATIC_STRING_THROW_IF(
|
||||
curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2,
|
||||
std::length_error{"replaced string exceeds max_size()"});
|
||||
if (pos + n1 >= curr_size)
|
||||
n1 = curr_size - pos;
|
||||
Traits::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
|
||||
Traits::copy(&curr_data[pos], s, n2);
|
||||
this->set_size(curr_size + (n2 - n1));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// string
|
||||
|
||||
static_string<std::numeric_limits<int>::digits10 + 1>
|
||||
|
@ -1625,7 +1625,7 @@ public:
|
||||
size_type n1,
|
||||
const basic_static_string<M, CharT, Traits>& str) BOOST_STATIC_STRING_COND_NOEXCEPT
|
||||
{
|
||||
return replace(pos1, n1, str.data(), str.size());
|
||||
return replace_unchecked(pos1, n1, str.data(), str.size());
|
||||
}
|
||||
|
||||
/** Replace a subset of the string.
|
||||
@ -1933,7 +1933,10 @@ public:
|
||||
replace(
|
||||
const_iterator i1,
|
||||
const_iterator i2,
|
||||
std::initializer_list<CharT> il) BOOST_STATIC_STRING_COND_NOEXCEPT;
|
||||
std::initializer_list<CharT> il) BOOST_STATIC_STRING_COND_NOEXCEPT
|
||||
{
|
||||
return replace_unchecked(i1 - begin(), i2 - i1, il.begin(), il.size());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@ -2489,7 +2492,15 @@ private:
|
||||
std::size_t
|
||||
read_back(
|
||||
InputIterator first,
|
||||
InputIterator last);
|
||||
InputIterator last) BOOST_STATIC_STRING_COND_NOEXCEPT;
|
||||
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
basic_static_string&
|
||||
replace_unchecked(
|
||||
size_type pos,
|
||||
size_type n1,
|
||||
const CharT* s,
|
||||
size_type n2) BOOST_STATIC_STRING_COND_NOEXCEPT;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user