// // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) // Copyright (c) 2019 Krystian Stasiowski (sdkrystian at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // Official repository: https://github.com/boostorg/static_string // #ifndef BOOST_STATIC_STRING_IMPL_STATIC_STRING_HPP #define BOOST_STATIC_STRING_IMPL_STATIC_STRING_HPP #include #include namespace boost { namespace static_string { //------------------------------------------------------------------------------ // // Construction // //------------------------------------------------------------------------------ template BOOST_STATIC_STRING_CPP11_CONSTEXPR basic_static_string:: basic_static_string() noexcept { #ifdef BOOST_STATIC_STRING_CPP20_CONSTEXPR_USED term(); #endif } template BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string(size_type count, CharT ch) BOOST_STATIC_STRING_COND_NOEXCEPT { assign(count, ch); } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string(basic_static_string const& other, size_type pos) BOOST_STATIC_STRING_COND_NOEXCEPT { assign(other, pos); } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string( basic_static_string const& other, size_type pos, size_type count) BOOST_STATIC_STRING_COND_NOEXCEPT { assign(other, pos, count); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string(CharT const* s, size_type count) BOOST_STATIC_STRING_COND_NOEXCEPT { assign(s, count); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string(CharT const* s) BOOST_STATIC_STRING_COND_NOEXCEPT { auto const count = Traits::length(s); BOOST_STATIC_STRING_THROW_IF(count > max_size(), std::length_error{"count > max_size()"}); Traits::copy(data(), s, count + 1); this->set_size(count); } template template ::value>::type*> BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string( InputIterator first, InputIterator last) BOOST_STATIC_STRING_COND_NOEXCEPT { assign(first, last); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string( basic_static_string const& s) noexcept { assign(s); } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string( basic_static_string const& s) BOOST_STATIC_STRING_COND_NOEXCEPT { assign(s); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string(std::initializer_list init) BOOST_STATIC_STRING_COND_NOEXCEPT { assign(init.begin(), init.end()); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string(string_view_type sv) BOOST_STATIC_STRING_COND_NOEXCEPT { assign(sv); } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR basic_static_string:: basic_static_string(T const& t, size_type pos, size_type n) BOOST_STATIC_STRING_COND_NOEXCEPT { assign(t, pos, n); } //------------------------------------------------------------------------------ // // Assignment // //------------------------------------------------------------------------------ template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: assign( size_type count, CharT ch) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string& { BOOST_STATIC_STRING_THROW_IF(count > max_size(), std::length_error{"count > max_size()"}); this->set_size(count); Traits::assign(data(), size(), ch); term(); return *this; } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: assign( basic_static_string const& s) noexcept -> basic_static_string& { if(this == &s) return *this; this->set_size(s.size()); auto const n = size() + 1; Traits::copy(data(), &s.data()[0], n); return *this; } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: assign( basic_static_string const& s, size_type pos, size_type count) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string& { auto const ss = s.subview(pos, count); return assign(ss.data(), ss.size()); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: assign( CharT const* s, size_type count) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string& { BOOST_STATIC_STRING_THROW_IF(count > max_size(), std::length_error{"count > max_size()"}); this->set_size(count); Traits::move(data(), s, size()); term(); return *this; } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: assign( InputIterator first, InputIterator last) BOOST_STATIC_STRING_COND_NOEXCEPT -> typename std::enable_if< detail::is_input_iterator::value, basic_static_string&>::type { auto ptr = data(); for (std::size_t i = 0; first != last; ++first, ++ptr, ++i) { if (1 > max_size() - i) { this->set_size(i); BOOST_STATIC_STRING_THROW(std::length_error{"n > max_size()"}); } Traits::assign(*ptr, *first); } this->set_size(ptr - data()); term(); return *this; } //------------------------------------------------------------------------------ // // Element access // //------------------------------------------------------------------------------ template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: at(size_type pos) BOOST_STATIC_STRING_COND_NOEXCEPT -> reference { BOOST_STATIC_STRING_THROW_IF( pos >= size(), std::out_of_range{"pos >= size()"}); return data()[pos]; } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: at(size_type pos) const BOOST_STATIC_STRING_COND_NOEXCEPT -> const_reference { BOOST_STATIC_STRING_THROW_IF( pos >= size(), std::out_of_range{"pos >= size()"}); return data()[pos]; } //------------------------------------------------------------------------------ // // Capacity // //------------------------------------------------------------------------------ template BOOST_STATIC_STRING_CPP14_CONSTEXPR void basic_static_string:: reserve(std::size_t n) BOOST_STATIC_STRING_COND_NOEXCEPT { BOOST_STATIC_STRING_THROW_IF( n > max_size(), std::length_error{"n > max_size()"}); } //------------------------------------------------------------------------------ // // Operations // //------------------------------------------------------------------------------ template BOOST_STATIC_STRING_CPP14_CONSTEXPR void basic_static_string:: clear() noexcept { this->set_size(0); term(); } //------------------------------------------------------------------------------ template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: insert( size_type index, CharT const* s, size_type count) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string& { const auto curr_size = size(); const auto curr_data = data(); BOOST_STATIC_STRING_THROW_IF( index > curr_size, std::out_of_range{"index > size()"}); insert(curr_data + index, s, s + count); return *this; } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: insert( const_iterator pos, size_type count, CharT ch) BOOST_STATIC_STRING_COND_NOEXCEPT -> iterator { const auto curr_size = size(); const auto curr_data = data(); BOOST_STATIC_STRING_THROW_IF( count > max_size() - curr_size, std::length_error{"count() > max_size() - size()"}); auto const index = pos - curr_data; Traits::move(&curr_data[index + count], &curr_data[index], curr_size - index); Traits::assign(&curr_data[index], count, ch); this->set_size(curr_size + count); term(); return &curr_data[index]; } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: insert( const_iterator pos, ForwardIterator first, ForwardIterator last) BOOST_STATIC_STRING_COND_NOEXCEPT -> typename std::enable_if< detail::is_forward_iterator< ForwardIterator>::value, iterator>::type { const auto curr_size = size(); const auto curr_data = data(); const auto count = detail::distance(first, last); const auto index = pos - curr_data; const auto s = &*first; BOOST_STATIC_STRING_THROW_IF( count > max_size() - curr_size, std::length_error{"count > max_size() - size()"}); // Makes this more constexpr friendly if we can use is_constant_evaluated const bool inside = #ifdef BOOST_STATIC_STRING_USE_IS_CONST_EVAL std::is_constant_evaluated() ? detail::is_inside(curr_data, curr_data + curr_size, s) : s <= &curr_data[curr_size] && s >= curr_data; #else s <= &curr_data[curr_size] && s >= curr_data; #endif if (!inside || (inside && ((s - curr_data) + count <= index))) { Traits::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1); detail::copy_with_traits(first, last, &curr_data[index]); } 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); return curr_data + index; } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: insert( const_iterator pos, InputIterator first, InputIterator last) BOOST_STATIC_STRING_COND_NOEXCEPT -> typename std::enable_if< detail::is_input_iterator< InputIterator>::value && ! detail::is_forward_iterator< InputIterator>::value, iterator>::type { const auto curr_size = size(); const auto curr_data = data(); const auto count = read_back(first, last); const auto index = pos - curr_data; const auto s = curr_data + curr_size + 1; BOOST_STATIC_STRING_THROW_IF( index > curr_size, std::out_of_range{"index > size()"}); std::rotate(&curr_data[index], &curr_data[curr_size + 1], &curr_data[curr_size + count + 1]); this->set_size(curr_size + count); 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_COND_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 BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: erase( size_type index, size_type count) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string& { const auto curr_size = size(); const auto curr_data = data(); BOOST_STATIC_STRING_THROW_IF( index > curr_size, std::out_of_range{"index > size()"}); auto const n = (std::min)(count, curr_size - index); Traits::move(&curr_data[index], &curr_data[index + n], curr_size - (index + n) + 1); this->set_size(curr_size - n); return *this; } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: erase( const_iterator pos) BOOST_STATIC_STRING_COND_NOEXCEPT -> iterator { erase(pos - begin(), 1); return begin() + (pos - begin()); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: erase( const_iterator first, const_iterator last) BOOST_STATIC_STRING_COND_NOEXCEPT -> iterator { erase(first - begin(), detail::distance(first, last)); return begin() + (first - begin()); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR void basic_static_string:: push_back( CharT ch) BOOST_STATIC_STRING_COND_NOEXCEPT { const auto curr_size = size(); BOOST_STATIC_STRING_THROW_IF( curr_size >= max_size(), std::length_error{"size() >= max_size()"}); Traits::assign(data()[curr_size], ch); this->set_size(curr_size + 1); term(); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: append( CharT const* s, size_type count) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string& { const auto curr_size = size(); BOOST_STATIC_STRING_THROW_IF( count > max_size() - curr_size, std::length_error{"count > max_size() - size()"}); Traits::copy(&data()[curr_size], s, count); this->set_size(curr_size + count); term(); return *this; } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: substr(size_type pos, size_type count) const BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string { BOOST_STATIC_STRING_THROW_IF( pos > size(), std::out_of_range{"pos > size()"}); return {&data()[pos], (std::min)(count, size() - pos)}; } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: subview(size_type pos, size_type count) const BOOST_STATIC_STRING_COND_NOEXCEPT -> string_view_type { BOOST_STATIC_STRING_THROW_IF( pos > size(), std::out_of_range{"pos > size()"}); return {&data()[pos], (std::min)(count, size() - pos)}; } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: copy(CharT* dest, size_type count, size_type pos) const BOOST_STATIC_STRING_COND_NOEXCEPT -> size_type { auto const s = subview(pos, count); Traits::copy(dest, s.data(), s.size()); return s.size(); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR void basic_static_string:: resize(std::size_t n) BOOST_STATIC_STRING_COND_NOEXCEPT { const auto curr_size = size(); BOOST_STATIC_STRING_THROW_IF( n > max_size(), std::length_error{"n > max_size()"}); if(n > curr_size) Traits::assign(&data()[curr_size], n - curr_size, CharT{}); this->set_size(n); term(); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR void basic_static_string:: resize(std::size_t n, CharT c) BOOST_STATIC_STRING_COND_NOEXCEPT { const auto curr_size = size(); BOOST_STATIC_STRING_THROW_IF( n > max_size(), std::length_error{"n > max_size()"}); if(n > curr_size) Traits::assign(&data()[curr_size], n - curr_size, c); this->set_size(n); term(); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR void basic_static_string:: swap(basic_static_string& s) noexcept { const auto curr_size = size(); basic_static_string tmp(s); s.set_size(curr_size); Traits::copy(&s.data()[0], data(), curr_size + 1); this->set_size(tmp.size()); Traits::copy(data(), tmp.data(), size() + 1); } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR void basic_static_string:: swap(basic_static_string& s) BOOST_STATIC_STRING_COND_NOEXCEPT { const auto curr_size = size(); BOOST_STATIC_STRING_THROW_IF( curr_size > s.max_size(), std::length_error{"size() > s.max_size()"}); BOOST_STATIC_STRING_THROW_IF( s.size() > max_size(), std::length_error{"s.size() > max_size()"}); basic_static_string tmp(s); s.set_size(curr_size); Traits::copy(&s.data()[0], data(), curr_size + 1); this->set_size(tmp.size()); Traits::copy(data(), &tmp.data()[0], size() + 1); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: replace( size_type pos, size_type n1, const CharT* s, size_type n2) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string& { const auto curr_size = size(); const auto curr_data = data(); BOOST_STATIC_STRING_THROW_IF( pos > curr_size, std::out_of_range{"pos > size()"}); n1 = (std::min)(n1, curr_size - pos); return replace(curr_data + pos, curr_data + pos + n1, s, s + n2); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: replace( size_type pos, size_type n1, size_type n2, CharT c) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string & { 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()"}); n1 = (std::min)(n1, curr_size - pos); Traits::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1); Traits::assign(&curr_data[pos], n2, c); this->set_size(curr_size + (n2 - n1)); return *this; } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: replace( const_iterator i1, const_iterator i2, ForwardIterator j1, ForwardIterator j2) BOOST_STATIC_STRING_COND_NOEXCEPT -> typename std::enable_if< detail::is_forward_iterator::value, basic_static_string&>::type { const auto curr_size = size(); const auto curr_data = data(); std::size_t n1 = detail::distance(i1, i2); 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( curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2, std::length_error{"replaced string exceeds max_size()"}); n1 = (std::min)(n1, curr_size - pos); // Makes this more constexpr friendly if we can use is_constant_evaluated const bool inside = #ifdef BOOST_STATIC_STRING_USE_IS_CONST_EVAL std::is_constant_evaluated() ? detail::is_inside(curr_data, curr_data + curr_size, s) : s <= &curr_data[curr_size] && s >= curr_data; #else s <= &curr_data[curr_size] && s >= curr_data; #endif 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); detail::copy_with_traits(j1, j2, &curr_data[pos]); } 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; } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: replace( const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2) BOOST_STATIC_STRING_COND_NOEXCEPT -> typename std::enable_if< detail::is_input_iterator< InputIterator>::value && ! detail::is_forward_iterator< InputIterator>::value, basic_static_string&>::type { const auto curr_size = size(); const auto curr_data = data(); std::size_t n1 = detail::distance(i1, i2); const std::size_t n2 = read_back(j1, j2); 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() - n2, std::length_error{"replaced string exceeds max_size()"}); // Rotate to the correct order. [i2, end] will now start with the replaced string, continue to the existing string not being replaced, and end with a null terminator std::rotate(&curr_data[pos], &curr_data[curr_size + 1], &curr_data[curr_size + n2 + 1]); // Cap the size n1 = (std::min)(n1, curr_size - pos); // Move everything from the end of the splice point to the end of the rotated string to the begining of the splice point Traits::move(&curr_data[pos + n2], &curr_data[pos + n2 + n1], (curr_size + (n2 - n1)) - pos); this->set_size(curr_size + (n2 - n1)); return *this; } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: find( const CharT* s, size_type pos, size_type n) const noexcept -> size_type { const auto curr_size = size(); if (pos > curr_size || n > curr_size - pos) return npos; if (!n) return pos; const auto res = detail::search(&data()[pos], &data()[curr_size], s, &s[n], Traits::eq); return res == end() ? npos : detail::distance(data(), res); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: rfind( const CharT* s, size_type pos, size_type n) const noexcept -> size_type { const auto curr_size = size(); const auto curr_data = data(); if (curr_size < n) return npos; if (pos > curr_size - n) pos = curr_size - n; if (!n) return pos; for (auto sub = &curr_data[pos]; sub >= curr_data; --sub) if (!Traits::compare(sub, s, n)) return detail::distance(curr_data, sub); return npos; } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: find_first_of( const CharT* s, size_type pos, size_type n) const noexcept -> size_type { const auto curr_data = data(); if (pos >= size() || !n) return npos; const auto res = detail::find_first_of(&curr_data[pos], &curr_data[size()], s, &s[n], Traits::eq); return res == end() ? npos : detail::distance(curr_data, res); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: find_last_of( const CharT* s, size_type pos, size_type n) const noexcept -> size_type { const auto curr_size = size(); if (!n) return npos; if (pos >= curr_size) pos = 0; else pos = curr_size - (pos + 1); const auto res = detail::find_first_of(rbegin() + pos, rend(), s, &s[n], Traits::eq); return res == rend() ? npos : curr_size - 1 - detail::distance(rbegin(), res); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: find_first_not_of( const CharT* s, size_type pos, size_type n) const noexcept -> size_type { if (pos >= size()) return npos; if (!n) return pos; const auto res = detail::find_not_of(&data()[pos], &data()[size()], s, n); return res == end() ? npos : detail::distance(data(), res); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: find_last_not_of( const CharT* s, size_type pos, size_type n) const noexcept -> size_type { const auto curr_size = size(); if (pos >= curr_size) pos = curr_size - 1; if (!n) return pos; pos = curr_size - (pos + 1); const auto res = detail::find_not_of(rbegin() + pos, rend(), s, n); return res == rend() ? npos : curr_size - 1 - detail::distance(rbegin(), res); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: assign_char(CharT ch, std::true_type) noexcept -> basic_static_string& { this->set_size(1); Traits::assign(data()[0], ch); term(); return *this; } template auto basic_static_string:: assign_char(CharT, std::false_type) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string& { BOOST_STATIC_STRING_THROW(std::length_error{"max_size() == 0"}); return *this; } template template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: read_back( InputIterator first, InputIterator last) -> std::size_t { const auto curr_data = data(); auto new_size = size(); for (; first != last; ++first) { BOOST_STATIC_STRING_THROW_IF( 1 > max_size() - new_size, std::length_error{"count > max_size() - size()"}); Traits::assign(curr_data[++new_size], *first); } return new_size - size(); } template BOOST_STATIC_STRING_CPP14_CONSTEXPR auto basic_static_string:: 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; } // to_static_string static_string::digits10 + 1> inline to_static_string(int value) noexcept { return detail::to_static_string_int_impl< std::numeric_limits::digits10 + 1>(value); } static_string::digits10 + 1> inline to_static_string(long value) noexcept { return detail::to_static_string_int_impl< std::numeric_limits::digits10 + 1>(value); } static_string::digits10 + 1> inline to_static_string(long long value) noexcept { return detail::to_static_string_int_impl< std::numeric_limits::digits10 + 1>(value); } static_string::digits10 + 1> inline to_static_string(unsigned int value) noexcept { return detail::to_static_string_int_impl< std::numeric_limits::digits10 + 1>(value); } static_string::digits10 + 1> inline to_static_string(unsigned long value) noexcept { return detail::to_static_string_int_impl< std::numeric_limits::digits10 + 1>(value); } static_string::digits10 + 1> inline to_static_string(unsigned long long value) noexcept { return detail::to_static_string_int_impl< std::numeric_limits::digits10 + 1>(value); } static_string::max_digits10 + 1> inline to_static_string(float value) noexcept { return detail::to_static_string_float_impl< std::numeric_limits::max_digits10 + 1>(value); } static_string::max_digits10 + 1> inline to_static_string(double value) noexcept { return detail::to_static_string_float_impl< std::numeric_limits::max_digits10 + 1>(value); } static_string::max_digits10 + 1> inline to_static_string(long double value) noexcept { return detail::to_static_string_float_impl< std::numeric_limits::max_digits10 + 1>(value); } // to_static_wstring static_wstring::digits10 + 1> inline to_static_wstring(int value) noexcept { return detail::to_static_wstring_int_impl< std::numeric_limits::digits10 + 1>(value); } static_wstring::digits10 + 1> inline to_static_wstring(long value) noexcept { return detail::to_static_wstring_int_impl< std::numeric_limits::digits10 + 1>(value); } static_wstring::digits10 + 1> inline to_static_wstring(long long value) noexcept { return detail::to_static_wstring_int_impl< std::numeric_limits::digits10 + 1>(value); } static_wstring::digits10 + 1> inline to_static_wstring(unsigned int value) noexcept { return detail::to_static_wstring_int_impl< std::numeric_limits::digits10 + 1>(value); } static_wstring::digits10 + 1> inline to_static_wstring(unsigned long value) noexcept { return detail::to_static_wstring_int_impl< std::numeric_limits::digits10 + 1>(value); } static_wstring::digits10 + 1> inline to_static_wstring(unsigned long long value) noexcept { return detail::to_static_wstring_int_impl< std::numeric_limits::digits10 + 1>(value); } static_wstring::max_digits10 + 1> inline to_static_wstring(float value) noexcept { return detail::to_static_wstring_float_impl< std::numeric_limits::max_digits10 + 1>(value); } static_wstring::max_digits10 + 1> inline to_static_wstring(double value) noexcept { return detail::to_static_wstring_float_impl< std::numeric_limits::max_digits10 + 1>(value); } static_wstring::max_digits10 + 1> inline to_static_wstring(long double value) noexcept { return detail::to_static_wstring_float_impl< std::numeric_limits::max_digits10 + 1>(value); } } // static_string } // boost #endif