This applies 'noexcept' more liberally in our std::basic_string_view,
anywhere that can't actually throw (even if it has a narrow contract).

I've also refactored some members to remove complex conditional
expressions, because they're not needed with C++14 constexpr, we can
just write the code as normal.

        * 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.

Tested powerpc64le-linux, committed to trunk.

commit 0b6b569b442ab1837cecd140f07df969599eb51a
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Tue Oct 24 13:50:19 2017 +0100

    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.

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<typename _CharT, typename _Traits>
     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<typename _CharT, typename _Traits>
     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<typename _CharT, typename _Traits>
     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<typename _CharT, typename _Traits>
     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<int>::max()
-            ? std::numeric_limits<int>::max()
-            : difference_type{__n1 - __n2} < std::numeric_limits<int>::min()
-            ? std::numeric_limits<int>::min()
-            : static_cast<int>(difference_type{__n1 - __n2});
+       const difference_type __diff{__n1 - __n2};
+       if (__diff > std::numeric_limits<int>::max())
+         return std::numeric_limits<int>::max();
+       if (__diff < std::numeric_limits<int>::min())
+         return std::numeric_limits<int>::min();
+       return static_cast<int>(__diff);
       }
 
       size_t       _M_len;

Reply via email to