From 02e2a7d8ef8aaeca05aba0e8ca15ba40ec1f3a53 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 24 Oct 2017 14:18:52 +0100 Subject: [PATCH] Refactor std::basic_string_view members and add noexcept * include/bits/string_view.tcc (find_first_of, find_last_of) (find_first_not_of, find_last_not_of): Add noexcept. * include/std/string_view (basic_string_view(const _CharT*)) (basic_string_view(const _CharT*, size_type)) (front, back, remove_prefix, remove_suffix, find, rfind) (find_first_of, find_first_not_of): Add noexcept. (at(size_type), _S_compare(size_type, size_type)): Replace conditional expressions with if statements. (copy(_CharT*, size_type, size_type), substr(size_type, size_type)): Use _M_check for length checks. (compare(basic_string_view)): Reformat. (_M_check(size_type, const char)): Add noexcept(false). (_M_limit(size_type, size_type)): Use noexcept not _GLIBCXX_NOEXCEPT. From-SVN: r254044 --- libstdc++-v3/ChangeLog | 14 ++++ libstdc++-v3/include/bits/string_view.tcc | 12 ++-- libstdc++-v3/include/std/string_view | 87 ++++++++++------------- 3 files changed, 61 insertions(+), 52 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index aad03d37659..cbb4f8c96c8 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,19 @@ 2017-10-24 Jonathan Wakely + * include/bits/string_view.tcc (find_first_of, find_last_of) + (find_first_not_of, find_last_not_of): Add noexcept. + * include/std/string_view (basic_string_view(const _CharT*)) + (basic_string_view(const _CharT*, size_type)) + (front, back, remove_prefix, remove_suffix, find, rfind) + (find_first_of, find_first_not_of): Add noexcept. + (at(size_type), _S_compare(size_type, size_type)): Replace conditional + expressions with if statements. + (copy(_CharT*, size_type, size_type), substr(size_type, size_type)): + Use _M_check for length checks. + (compare(basic_string_view)): Reformat. + (_M_check(size_type, const char)): Add noexcept(false). + (_M_limit(size_type, size_type)): Use noexcept not _GLIBCXX_NOEXCEPT. + PR libstdc++/82685 * include/experimental/string_view (operator""sv): Add noexcept. * include/std/string_view (operator""sv): Likewise. diff --git a/libstdc++-v3/include/bits/string_view.tcc b/libstdc++-v3/include/bits/string_view.tcc index 4d98f8668a0..5c53c584381 100644 --- a/libstdc++-v3/include/bits/string_view.tcc +++ b/libstdc++-v3/include/bits/string_view.tcc @@ -119,7 +119,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: - find_first_of(const _CharT* __str, size_type __pos, size_type __n) const + find_first_of(const _CharT* __str, size_type __pos, + size_type __n) const noexcept { __glibcxx_requires_string_len(__str, __n); for (; __n && __pos < this->_M_len; ++__pos) @@ -135,7 +136,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: - find_last_of(const _CharT* __str, size_type __pos, size_type __n) const + find_last_of(const _CharT* __str, size_type __pos, + size_type __n) const noexcept { __glibcxx_requires_string_len(__str, __n); size_type __size = this->size(); @@ -156,7 +158,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: - find_first_not_of(const _CharT* __str, size_type __pos, size_type __n) const + find_first_not_of(const _CharT* __str, size_type __pos, + size_type __n) const noexcept { __glibcxx_requires_string_len(__str, __n); for (; __pos < this->_M_len; ++__pos) @@ -179,7 +182,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: - find_last_not_of(const _CharT* __str, size_type __pos, size_type __n) const + find_last_not_of(const _CharT* __str, size_type __pos, + size_type __n) const noexcept { __glibcxx_requires_string_len(__str, __n); size_type __size = this->_M_len; diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view index 110a235a4c0..1900b867841 100644 --- a/libstdc++-v3/include/std/string_view +++ b/libstdc++-v3/include/std/string_view @@ -96,14 +96,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr basic_string_view(const basic_string_view&) noexcept = default; - constexpr basic_string_view(const _CharT* __str) + constexpr basic_string_view(const _CharT* __str) noexcept : _M_len{__str == nullptr ? 0 : traits_type::length(__str)}, _M_str{__str} { } - constexpr basic_string_view(const _CharT* __str, size_type __len) - : _M_len{__len}, - _M_str{__str} + constexpr + basic_string_view(const _CharT* __str, size_type __len) noexcept + : _M_len{__len}, _M_str{__str} { } constexpr basic_string_view& @@ -177,17 +177,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr const _CharT& at(size_type __pos) const { - return __pos < this->_M_len - ? *(this->_M_str + __pos) - : (__throw_out_of_range_fmt(__N("basic_string_view::at: __pos " - "(which is %zu) >= this->size() " - "(which is %zu)"), - __pos, this->size()), - *this->_M_str); + if (__pos >= _M_len) + __throw_out_of_range_fmt(__N("basic_string_view::at: __pos " + "(which is %zu) >= this->size() " + "(which is %zu)"), __pos, this->size()); + return *(this->_M_str + __pos); } constexpr const _CharT& - front() const + front() const noexcept { // TODO: Assert to restore in a way compatible with the constexpr. // __glibcxx_assert(this->_M_len > 0); @@ -195,7 +193,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } constexpr const _CharT& - back() const + back() const noexcept { // TODO: Assert to restore in a way compatible with the constexpr. // __glibcxx_assert(this->_M_len > 0); @@ -209,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // [string.view.modifiers], modifiers: constexpr void - remove_prefix(size_type __n) + remove_prefix(size_type __n) noexcept { __glibcxx_assert(this->_M_len >= __n); this->_M_str += __n; @@ -217,7 +215,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } constexpr void - remove_suffix(size_type __n) + remove_suffix(size_type __n) noexcept { this->_M_len -= __n; } constexpr void @@ -235,38 +233,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION copy(_CharT* __str, size_type __n, size_type __pos = 0) const { __glibcxx_requires_string_len(__str, __n); - if (__pos > this->_M_len) - __throw_out_of_range_fmt(__N("basic_string_view::copy: __pos " - "(which is %zu) > this->size() " - "(which is %zu)"), - __pos, this->size()); - size_type __rlen{std::min(__n, size_type{this->_M_len - __pos})}; + __pos = _M_check(__pos, "basic_string_view::copy"); + const size_type __rlen = std::min(__n, _M_len - __pos); for (auto __begin = this->_M_str + __pos, __end = __begin + __rlen; __begin != __end;) *__str++ = *__begin++; return __rlen; } - - // [string.view.ops], string operations: - constexpr basic_string_view - substr(size_type __pos, size_type __n=npos) const + substr(size_type __pos, size_type __n = npos) const noexcept(false) { - return __pos <= this->_M_len - ? basic_string_view{this->_M_str + __pos, - std::min(__n, size_type{this->_M_len - __pos})} - : (__throw_out_of_range_fmt(__N("basic_string_view::substr: __pos " - "(which is %zu) > this->size() " - "(which is %zu)"), - __pos, this->size()), basic_string_view{}); + __pos = _M_check(__pos, "basic_string_view::substr"); + const size_type __rlen = std::min(__n, _M_len - __pos); + return basic_string_view{_M_str + __pos, __rlen}; } constexpr int compare(basic_string_view __str) const noexcept { - int __ret = traits_type::compare(this->_M_str, __str._M_str, - std::min(this->_M_len, __str._M_len)); + const size_type __rlen = std::min(this->_M_len, __str._M_len); + int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen); if (__ret == 0) __ret = _S_compare(this->_M_len, __str._M_len); return __ret; @@ -279,7 +266,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr int compare(size_type __pos1, size_type __n1, basic_string_view __str, size_type __pos2, size_type __n2) const - { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); } + { + return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); + } constexpr int compare(const _CharT* __str) const noexcept @@ -291,7 +280,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr int compare(size_type __pos1, size_type __n1, - const _CharT* __str, size_type __n2) const + const _CharT* __str, size_type __n2) const noexcept(false) { return this->substr(__pos1, __n1) .compare(basic_string_view(__str, __n2)); @@ -302,13 +291,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return this->find(__str._M_str, __pos, __str._M_len); } constexpr size_type - find(_CharT __c, size_type __pos=0) const noexcept; + find(_CharT __c, size_type __pos = 0) const noexcept; constexpr size_type find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type - find(const _CharT* __str, size_type __pos=0) const noexcept + find(const _CharT* __str, size_type __pos = 0) const noexcept { return this->find(__str, __pos, traits_type::length(__str)); } constexpr size_type @@ -350,7 +339,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return this->rfind(__c, __pos); } constexpr size_type - find_last_of(const _CharT* __str, size_type __pos, size_type __n) const; + find_last_of(const _CharT* __str, size_type __pos, + size_type __n) const noexcept; constexpr size_type find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept @@ -366,7 +356,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr size_type find_first_not_of(const _CharT* __str, - size_type __pos, size_type __n) const; + size_type __pos, size_type __n) const noexcept; constexpr size_type find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept @@ -385,7 +375,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr size_type find_last_not_of(const _CharT* __str, - size_type __pos, size_type __n) const; + size_type __pos, size_type __n) const noexcept; constexpr size_type find_last_not_of(const _CharT* __str, @@ -396,7 +386,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } constexpr size_type - _M_check(size_type __pos, const char* __s) const + _M_check(size_type __pos, const char* __s) const noexcept(false) { if (__pos > this->size()) __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > " @@ -407,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // NB: _M_limit doesn't check for a bad __pos value. constexpr size_type - _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT + _M_limit(size_type __pos, size_type __off) const noexcept { const bool __testoff = __off < this->size() - __pos; return __testoff ? __off : this->size() - __pos; @@ -418,11 +408,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static constexpr int _S_compare(size_type __n1, size_type __n2) noexcept { - return difference_type{__n1 - __n2} > std::numeric_limits::max() - ? std::numeric_limits::max() - : difference_type{__n1 - __n2} < std::numeric_limits::min() - ? std::numeric_limits::min() - : static_cast(difference_type{__n1 - __n2}); + const difference_type __diff{__n1 - __n2}; + if (__diff > std::numeric_limits::max()) + return std::numeric_limits::max(); + if (__diff < std::numeric_limits::min()) + return std::numeric_limits::min(); + return static_cast(__diff); } size_t _M_len;