// // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco 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/beast // #ifndef BOOST_BEAST_IMPL_STATIC_STRING_HPP #define BOOST_BEAST_IMPL_STATIC_STRING_HPP #include #include namespace boost { namespace beast { // // (constructor) // template static_string:: static_string() { n_ = 0; term(); } template static_string:: static_string(size_type count, CharT ch) { assign(count, ch); } template template static_string:: static_string(static_string const& other, size_type pos) { assign(other, pos); } template template static_string:: static_string(static_string const& other, size_type pos, size_type count) { assign(other, pos, count); } template static_string:: static_string(CharT const* s, size_type count) { assign(s, count); } template static_string:: static_string(CharT const* s) { auto const count = Traits::length(s); if(count > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "count > max_size()"}); n_ = count; Traits::copy(&s_[0], s, n_ + 1); } template template static_string:: static_string(InputIt first, InputIt last) { assign(first, last); } template static_string:: static_string(static_string const& s) { assign(s); } template template static_string:: static_string(static_string const& s) { assign(s); } template static_string:: static_string(std::initializer_list init) { assign(init.begin(), init.end()); } template static_string:: static_string(string_view_type sv) { assign(sv); } template template static_string:: static_string(T const& t, size_type pos, size_type n) { assign(t, pos, n); } // // (assignment) // template auto static_string:: operator=(CharT const* s) -> static_string& { auto const count = Traits::length(s); if(count > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "count > max_size()"}); n_ = count; Traits::copy(&s_[0], s, n_ + 1); return *this; } template auto static_string:: assign(size_type count, CharT ch) -> static_string& { if(count > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "count > max_size()"}); n_ = count; Traits::assign(&s_[0], n_, ch); term(); return *this; } template auto static_string:: assign(static_string const& str) -> static_string& { n_ = str.n_; auto const n = n_ + 1; BOOST_BEAST_ASSUME(n != 0); Traits::copy(&s_[0], &str.s_[0], n); return *this; } template template auto static_string:: assign(static_string const& str, size_type pos, size_type count) -> static_string& { auto const ss = str.substr(pos, count); return assign(ss.data(), ss.size()); } template auto static_string:: assign(CharT const* s, size_type count) -> static_string& { if(count > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "count > max_size()"}); n_ = count; Traits::copy(&s_[0], s, n_); term(); return *this; } template template auto static_string:: assign(InputIt first, InputIt last) -> static_string& { std::size_t const n = std::distance(first, last); if(n > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "n > max_size()"}); n_ = n; for(auto it = &s_[0]; first != last; ++it, ++first) Traits::assign(*it, *first); term(); return *this; } template template auto static_string:: assign(T const& t, size_type pos, size_type count) -> typename std::enable_if::value, static_string&>::type { auto const sv = string_view_type(t).substr(pos, count); if(sv.size() > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "sv.size() > max_size()"}); n_ = sv.size(); Traits::copy(&s_[0], &sv[0], n_); term(); return *this; } // // Element access // template auto static_string:: at(size_type pos) -> reference { if(pos >= size()) BOOST_THROW_EXCEPTION(std::out_of_range{ "pos >= size()"}); return s_[pos]; } template auto static_string:: at(size_type pos) const -> const_reference { if(pos >= size()) BOOST_THROW_EXCEPTION(std::out_of_range{ "pos >= size()"}); return s_[pos]; } // // Capacity // template void static_string:: reserve(std::size_t n) { if(n > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "n > max_size()"}); } // // Operations // template void static_string:: clear() { n_ = 0; term(); } template auto static_string:: insert(size_type index, size_type count, CharT ch) -> static_string& { if(index > size()) BOOST_THROW_EXCEPTION(std::out_of_range{ "index > size()"}); insert(begin() + index, count, ch); return *this; } template auto static_string:: insert(size_type index, CharT const* s, size_type count) -> static_string& { if(index > size()) BOOST_THROW_EXCEPTION(std::out_of_range{ "index > size()"}); if(size() + count > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "size() + count > max_size()"}); Traits::move( &s_[index + count], &s_[index], size() - index); n_ += count; Traits::copy(&s_[index], s, count); term(); return *this; } template template auto static_string:: insert(size_type index, static_string const& str, size_type index_str, size_type count) -> static_string& { auto const ss = str.substr(index_str, count); return insert(index, ss.data(), ss.size()); } template auto static_string:: insert(const_iterator pos, size_type count, CharT ch) -> iterator { if(size() + count > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "size() + count() > max_size()"}); auto const index = pos - &s_[0]; Traits::move( &s_[index + count], &s_[index], size() - index); n_ += count; Traits::assign(&s_[index], count, ch); term(); return &s_[index]; } template template auto static_string:: insert(const_iterator pos, InputIt first, InputIt last) -> typename std::enable_if< detail::is_input_iterator::value, iterator>::type { std::size_t const count = std::distance(first, last); if(size() + count > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "size() + count > max_size()"}); std::size_t const index = pos - begin(); Traits::move( &s_[index + count], &s_[index], size() - index); n_ += count; for(auto it = begin() + index; first != last; ++it, ++first) Traits::assign(*it, *first); term(); return begin() + index; } template template auto static_string:: insert(size_type index, const T& t, size_type index_str, size_type count) -> typename std::enable_if::value && ! std::is_convertible::value, static_string&>::type { auto const str = string_view_type(t).substr(index_str, count); return insert(index, str.data(), str.size()); } template auto static_string:: erase(size_type index, size_type count) -> static_string& { if(index > size()) BOOST_THROW_EXCEPTION(std::out_of_range{ "index > size()"}); auto const n = (std::min)(count, size() - index); Traits::move( &s_[index], &s_[index + n], size() - (index + n) + 1); n_ -= n; return *this; } template auto static_string:: erase(const_iterator pos) -> iterator { erase(pos - begin(), 1); return begin() + (pos - begin()); } template auto static_string:: erase(const_iterator first, const_iterator last) -> iterator { erase(first - begin(), std::distance(first, last)); return begin() + (first - begin()); } template void static_string:: push_back(CharT ch) { if(size() >= max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "size() >= max_size()"}); Traits::assign(s_[n_++], ch); term(); } template template auto static_string:: append(static_string const& str, size_type pos, size_type count) -> static_string& { // Valid range is [0, size) if(pos >= str.size()) BOOST_THROW_EXCEPTION(std::out_of_range{ "pos > str.size()"}); string_view_type const ss{&str.s_[pos], (std::min)(count, str.size() - pos)}; insert(size(), ss.data(), ss.size()); return *this; } template auto static_string:: substr(size_type pos, size_type count) const -> string_view_type { if(pos > size()) BOOST_THROW_EXCEPTION(std::out_of_range{ "pos > size()"}); return{&s_[pos], (std::min)(count, size() - pos)}; } template auto static_string:: copy(CharT* dest, size_type count, size_type pos) const -> size_type { auto const str = substr(pos, count); Traits::copy(dest, str.data(), str.size()); return str.size(); } template void static_string:: resize(std::size_t n) { if(n > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "n > max_size()"}); if(n > n_) Traits::assign(&s_[n_], n - n_, CharT{}); n_ = n; term(); } template void static_string:: resize(std::size_t n, CharT c) { if(n > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "n > max_size()"}); if(n > n_) Traits::assign(&s_[n_], n - n_, c); n_ = n; term(); } template void static_string:: swap(static_string& str) { static_string tmp(str); str.n_ = n_; Traits::copy(&str.s_[0], &s_[0], n_ + 1); n_ = tmp.n_; Traits::copy(&s_[0], &tmp.s_[0], n_ + 1); } template template void static_string:: swap(static_string& str) { if(size() > str.max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "size() > str.max_size()"}); if(str.size() > max_size()) BOOST_THROW_EXCEPTION(std::length_error{ "str.size() > max_size()"}); static_string tmp(str); str.n_ = n_; Traits::copy(&str.s_[0], &s_[0], n_ + 1); n_ = tmp.n_; Traits::copy(&s_[0], &tmp.s_[0], n_ + 1); } template auto static_string:: assign_char(CharT ch, std::true_type) -> static_string& { n_ = 1; Traits::assign(s_[0], ch); term(); return *this; } template auto static_string:: assign_char(CharT, std::false_type) -> static_string& { BOOST_THROW_EXCEPTION(std::length_error{ "max_size() == 0"}); } template static_string to_static_string(Integer x) { using CharT = char; using Traits = std::char_traits; BOOST_STATIC_ASSERT(std::is_integral::value); char buf[detail::max_digits(sizeof(Integer))]; auto last = buf + sizeof(buf); auto it = detail::raw_to_string< CharT, Integer, Traits>(last, sizeof(buf), x); static_string s; s.resize(static_cast(last - it)); auto p = s.data(); while(it < last) Traits::assign(*p++, *it++); return s; } } // beast } // boost #endif