diff --git a/sprout/string.hpp b/sprout/string.hpp index 5a6ed743..60fc8d35 100644 --- a/sprout/string.hpp +++ b/sprout/string.hpp @@ -218,21 +218,70 @@ namespace sprout { SPROUT_CONSTEXPR const_pointer c_str() const SPROUT_NOEXCEPT { return &elems[0]; } - void fill(const_reference value) { - std::fill_n(begin(), size(), value); + template + basic_string& assign(basic_string const& str) { + return assign(str.begin(), str.size()); + } + template + basic_string& assign(basic_string const& str, size_type pos, size_type n) { + if (str.size() < pos + n) { + throw std::out_of_range("basic_string<>: index out of range"); + } + return assign(str.begin() + pos, n); + } + basic_string& assign(value_type const* s, size_type n) { + if (max_size() < n) { + throw std::out_of_range("basic_string<>: index out of range"); + } + for (size_type i = 0; i < n; ++i) { + traits_type::assign(elems[i], s[i]); + } + for (size_type i = n; i < max_size(); ++i) { + traits_type::assign(elems[i], value_type()); + } + len = n; + return *this; + } + basic_string& assign(value_type const* s) { + return assign(s, traits_type::length(s)); + } + basic_string& assign(size_type n, value_type c) { + if (max_size() < n) { + throw std::out_of_range("basic_string<>: index out of range"); + } + traits_type::assign(begin(), n, c); + traits_type::assign(begin() + n, max_size() - n, value_type()); + len = n; + return *this; + } + template + basic_string& assign(Iterator first, Iterator last) { + size_type n = 0; + for (; n < max_size() || first != last; ++n, ++first) { + traits_type::assign(elems[n], *first); + } + for (size_type i = n; i < max_size(); ++i) { + traits_type::assign(elems[i], value_type()); + } + len = n; + return *this; } void swap(basic_string& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::swap(std::declval(), std::declval()))) { - std::swap_ranges(other.begin(), other.end(), begin()); + std::swap_ranges(other.begin(), other.begin() + other.max_size(), begin()); + { + using std::swap; + swap(len, other.len); + } } - template - basic_string& operator=(basic_string const& rhs) { - std::copy(rhs.begin(), rhs.end(), begin()); - return *this; + template + basic_string& operator=(basic_string const& rhs) { + return assign(rhs); } - template - basic_string& operator=(basic_string&& rhs) { - std::move(rhs.begin(), rhs.end(), begin()); - return *this; + basic_string& operator=(value_type const* rhs) { + return assign(rhs); + } + basic_string& operator=(value_type rhs) { + return assign(1, rhs); } template SPROUT_CONSTEXPR int compare(basic_string const& str) const { @@ -347,46 +396,6 @@ namespace sprout { lhs.swap(rhs); } - // - // resize - // - namespace detail { - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sizeof...(Args) != N, - sprout::basic_string - >::type resize_impl( - sprout::basic_string const& str, - typename sprout::basic_string::size_type new_size, - Args const&... args - ) - { - return sprout::detail::resize_impl(str, new_size, args..., sizeof...(Args) < new_size ? str[sizeof...(Args)] : T()); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sizeof...(Args) == N, - sprout::basic_string - >::type resize_impl( - sprout::basic_string const& str, - typename sprout::basic_string::size_type new_size, - Args const&... args - ) - { - return sprout::basic_string{{args...}, new_size}; - } - } // namespace detail - template - SPROUT_CONSTEXPR inline sprout::basic_string resize( - sprout::basic_string const& str, - typename sprout::basic_string::size_type new_size - ) - { - return new_size <= N ? sprout::detail::resize_impl(str, new_size) - : throw "basic_string<>: index out of range" - ; - } - // // rebind_fixed_size // @@ -401,9 +410,6 @@ namespace sprout { }; namespace detail { - // - // make_clone_functor_impl - // template struct make_clone_functor_impl;