diff --git a/include/boost/static_string/impl/static_string.hpp b/include/boost/static_string/impl/static_string.hpp index eb94172..1cc9509 100644 --- a/include/boost/static_string/impl/static_string.hpp +++ b/include/boost/static_string/impl/static_string.hpp @@ -423,28 +423,6 @@ insert( return curr_data + index; } -template -BOOST_STATIC_STRING_CPP14_CONSTEXPR -auto -basic_static_string:: -insert( - const_iterator pos, - std::initializer_list ilist) BOOST_STATIC_STRING_NO_EXCEPTIONS_NOEXCEPT -> - iterator -{ - const auto curr_size = size(); - const auto curr_data = data(); - const auto index = pos - curr_data; - BOOST_STATIC_STRING_THROW_IF( - index > curr_size, std::out_of_range{"index > size()"}); - BOOST_STATIC_STRING_THROW_IF( - ilist.size() > max_size() - curr_size, std::length_error{"count > max_size() - size()"}); - Traits::move(&curr_data[index + ilist.size()], &curr_data[index], curr_size - index + 1); - detail::copy_with_traits(ilist.begin(), ilist.end(), &curr_data[index]); - this->set_size(curr_size + ilist.size()); - return curr_data + index; -} - //------------------------------------------------------------------------------ template @@ -962,6 +940,29 @@ replace_unchecked( return *this; } +template +BOOST_STATIC_STRING_CPP14_CONSTEXPR +auto +basic_static_string:: +insert_unchecked( + size_type index, + const CharT* s, + size_type count) BOOST_STATIC_STRING_NO_EXCEPTIONS_NOEXCEPT -> + basic_static_string& +{ + const auto curr_data = data(); + const auto curr_size = size(); + BOOST_STATIC_STRING_THROW_IF( + index > curr_size, std::out_of_range{"index > size()"}); + BOOST_STATIC_STRING_THROW_IF( + count > max_size() - size(), + std::length_error{"count > max_size() - size()"}); + Traits::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1); + Traits::copy(&curr_data[index], s, count); + this->set_size(curr_size + count); + return *this; +} + // to_static_string static_string::digits10 + 1> diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 037ac15..23ec7d1 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -893,6 +893,10 @@ public: Strong guarantee. + @note + The insertion is done unchecked, as the source cannot be + within the destination. + @note All references, pointers, or iterators referring to contained elements are invalidated. Any past-the-end iterators are also invalidated. @@ -913,6 +917,36 @@ public: insert( size_type index, const basic_static_string& str) BOOST_STATIC_STRING_NO_EXCEPTIONS_NOEXCEPT + { + return insert_unchecked(index, str.data(), str.size()); + } + + /** Insert a string. + + Inserts the string `str` + at the position `index`. + + @par Exception Safety + + Strong guarantee. + + @note All references, pointers, or iterators + referring to contained elements are invalidated. Any + past-the-end iterators are also invalidated. + + @return `*this` + + @param index The index to insert at. + @param str The string to insert. + + @throw std::length_error `size() + str.size() > max_size()` + @throw std::out_of_range `index > size()` + */ + BOOST_STATIC_STRING_CPP14_CONSTEXPR + basic_static_string& + insert( + size_type index, + const basic_static_string& str) BOOST_STATIC_STRING_NO_EXCEPTIONS_NOEXCEPT { return insert(index, str.data(), str.size()); } @@ -926,6 +960,10 @@ public: Strong guarantee. + @note + The insertion is done unchecked, as the source cannot be + within the destination. + @note All references, pointers, or iterators referring to contained elements are invalidated. Any past-the-end iterators are also invalidated. @@ -952,6 +990,45 @@ public: const basic_static_string& str, size_type index_str, size_type count = npos) BOOST_STATIC_STRING_NO_EXCEPTIONS_NOEXCEPT + { + BOOST_STATIC_STRING_THROW_IF( + index_str > str.size(), std::out_of_range{"index_str > str.size()"} + ); + return insert_unchecked(index, str.data() + index_str, (std::min)(count, str.size() - index_str)); + } + + /** Insert a string. + + Inserts a string, obtained by `str.substr(index_str, count)` + at the position `index`. + + @par Exception Safety + + Strong guarantee. + + @note All references, pointers, or iterators + referring to contained elements are invalidated. Any + past-the-end iterators are also invalidated. + + @return `*this` + + @param index The index to insert at. + @param str The string from which to insert. + @param index_str The index in `str` to start inserting from. + @param count The number of characters to insert. + The default argument for this parameter is @ref npos. + + @throw std::length_error `size() + str.substr(index_str, count).size() > max_size()` + @throw std::out_of_range `index > size()` + @throw std::out_of_range `index_str > str.size()` + */ + BOOST_STATIC_STRING_CPP14_CONSTEXPR + basic_static_string& + insert( + size_type index, + const basic_static_string& str, + size_type index_str, + size_type count = npos) BOOST_STATIC_STRING_NO_EXCEPTIONS_NOEXCEPT { BOOST_STATIC_STRING_THROW_IF( index_str > str.size(), std::out_of_range{"index_str > str.size()"} @@ -1152,7 +1229,11 @@ public: iterator insert( const_iterator pos, - std::initializer_list ilist) BOOST_STATIC_STRING_NO_EXCEPTIONS_NOEXCEPT; + std::initializer_list ilist) BOOST_STATIC_STRING_NO_EXCEPTIONS_NOEXCEPT + { + const auto offset = pos - begin(); + return insert_unchecked(offset, ilist.begin(), ilist.size()).begin() + offset; + } /** Insert characters from an object convertible to `string_view_type`. @@ -3546,6 +3627,13 @@ private: size_type n1, const CharT* s, size_type n2) BOOST_STATIC_STRING_NO_EXCEPTIONS_NOEXCEPT; + + BOOST_STATIC_STRING_CPP14_CONSTEXPR + basic_static_string& + insert_unchecked( + size_type index, + const CharT* s, + size_type count) BOOST_STATIC_STRING_NO_EXCEPTIONS_NOEXCEPT; }; //------------------------------------------------------------------------------