PR libstdc++/70483 make std::experimental::string_view fully constexpr
Backport from mainline 2017-09-12 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/70483 * include/experimental/bits/string_view.tcc (basic_string_view::find) (basic_string_view::rfind, basic_string_view::find_first_of) (basic_string_view::find_last_of, basic_string_view::find_first_not_of) (basic_string_view::find_last_not_of): Add constexpr specifier. * include/experimental/string_view (basic_string_view::remove_prefix) (basic_string_view::remove_suffix, basic_string_view::swap) (basic_string_view::compare, basic_string_view::find) (basic_string_view::rfind, basic_string_view::find_first_of) (basic_string_view::find_last_of, basic_string_view::find_first_not_of) (basic_string_view::find_last_not_of, operator==, operator!=) (operator<, operator>, operator<=, operator>=): Likewise. * testsuite/experimental/string_view/operations/compare/char/70483.cc: New. From-SVN: r252032
This commit is contained in:
parent
53e7178da5
commit
e38bde5423
@ -1,5 +1,23 @@
|
||||
2017-09-12 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
Backport from mainline
|
||||
2017-09-12 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/70483
|
||||
* include/experimental/bits/string_view.tcc (basic_string_view::find)
|
||||
(basic_string_view::rfind, basic_string_view::find_first_of)
|
||||
(basic_string_view::find_last_of, basic_string_view::find_first_not_of)
|
||||
(basic_string_view::find_last_not_of): Add constexpr specifier.
|
||||
* include/experimental/string_view (basic_string_view::remove_prefix)
|
||||
(basic_string_view::remove_suffix, basic_string_view::swap)
|
||||
(basic_string_view::compare, basic_string_view::find)
|
||||
(basic_string_view::rfind, basic_string_view::find_first_of)
|
||||
(basic_string_view::find_last_of, basic_string_view::find_first_not_of)
|
||||
(basic_string_view::find_last_not_of, operator==, operator!=)
|
||||
(operator<, operator>, operator<=, operator>=): Likewise.
|
||||
* testsuite/experimental/string_view/operations/compare/char/70483.cc:
|
||||
New.
|
||||
|
||||
Backport from mainline
|
||||
2017-09-11 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
|
@ -49,7 +49,7 @@ inline namespace fundamentals_v1
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
typename basic_string_view<_CharT, _Traits>::size_type
|
||||
constexpr typename basic_string_view<_CharT, _Traits>::size_type
|
||||
basic_string_view<_CharT, _Traits>::
|
||||
find(const _CharT* __str, size_type __pos, size_type __n) const noexcept
|
||||
{
|
||||
@ -70,7 +70,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
typename basic_string_view<_CharT, _Traits>::size_type
|
||||
constexpr typename basic_string_view<_CharT, _Traits>::size_type
|
||||
basic_string_view<_CharT, _Traits>::
|
||||
find(_CharT __c, size_type __pos) const noexcept
|
||||
{
|
||||
@ -86,7 +86,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
typename basic_string_view<_CharT, _Traits>::size_type
|
||||
constexpr typename basic_string_view<_CharT, _Traits>::size_type
|
||||
basic_string_view<_CharT, _Traits>::
|
||||
rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept
|
||||
{
|
||||
@ -106,7 +106,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
typename basic_string_view<_CharT, _Traits>::size_type
|
||||
constexpr typename basic_string_view<_CharT, _Traits>::size_type
|
||||
basic_string_view<_CharT, _Traits>::
|
||||
rfind(_CharT __c, size_type __pos) const noexcept
|
||||
{
|
||||
@ -123,7 +123,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
typename basic_string_view<_CharT, _Traits>::size_type
|
||||
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
|
||||
{
|
||||
@ -139,7 +139,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
typename basic_string_view<_CharT, _Traits>::size_type
|
||||
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
|
||||
{
|
||||
@ -160,7 +160,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
typename basic_string_view<_CharT, _Traits>::size_type
|
||||
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
|
||||
{
|
||||
@ -172,7 +172,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
typename basic_string_view<_CharT, _Traits>::size_type
|
||||
constexpr typename basic_string_view<_CharT, _Traits>::size_type
|
||||
basic_string_view<_CharT, _Traits>::
|
||||
find_first_not_of(_CharT __c, size_type __pos) const noexcept
|
||||
{
|
||||
@ -183,7 +183,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
typename basic_string_view<_CharT, _Traits>::size_type
|
||||
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
|
||||
{
|
||||
@ -204,7 +204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
typename basic_string_view<_CharT, _Traits>::size_type
|
||||
constexpr typename basic_string_view<_CharT, _Traits>::size_type
|
||||
basic_string_view<_CharT, _Traits>::
|
||||
find_last_not_of(_CharT __c, size_type __pos) const noexcept
|
||||
{
|
||||
|
@ -219,7 +219,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
// [string.view.modifiers], modifiers:
|
||||
|
||||
void
|
||||
constexpr void
|
||||
remove_prefix(size_type __n)
|
||||
{
|
||||
__glibcxx_assert(this->_M_len >= __n);
|
||||
@ -227,15 +227,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
this->_M_len -= __n;
|
||||
}
|
||||
|
||||
void
|
||||
constexpr void
|
||||
remove_suffix(size_type __n)
|
||||
{ this->_M_len -= __n; }
|
||||
|
||||
void
|
||||
constexpr void
|
||||
swap(basic_string_view& __sv) noexcept
|
||||
{
|
||||
std::swap(this->_M_len, __sv._M_len);
|
||||
std::swap(this->_M_str, __sv._M_str);
|
||||
auto __tmp = *this;
|
||||
*this = __sv;
|
||||
__sv = __tmp;
|
||||
}
|
||||
|
||||
|
||||
@ -285,7 +286,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__pos, this->size()), basic_string_view{});
|
||||
}
|
||||
|
||||
int
|
||||
constexpr int
|
||||
compare(basic_string_view __str) const noexcept
|
||||
{
|
||||
int __ret = traits_type::compare(this->_M_str, __str._M_str,
|
||||
@ -295,24 +296,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
return __ret;
|
||||
}
|
||||
|
||||
int
|
||||
constexpr int
|
||||
compare(size_type __pos1, size_type __n1, basic_string_view __str) const
|
||||
{ return this->substr(__pos1, __n1).compare(__str); }
|
||||
|
||||
int
|
||||
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)); }
|
||||
|
||||
int
|
||||
constexpr int
|
||||
compare(const _CharT* __str) const noexcept
|
||||
{ return this->compare(basic_string_view{__str}); }
|
||||
|
||||
int
|
||||
constexpr int
|
||||
compare(size_type __pos1, size_type __n1, const _CharT* __str) const
|
||||
{ return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
|
||||
|
||||
int
|
||||
constexpr int
|
||||
compare(size_type __pos1, size_type __n1,
|
||||
const _CharT* __str, size_type __n2) const
|
||||
{
|
||||
@ -320,97 +321,97 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
.compare(basic_string_view(__str, __n2));
|
||||
}
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find(basic_string_view __str, size_type __pos = 0) const noexcept
|
||||
{ return this->find(__str._M_str, __pos, __str._M_len); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find(_CharT __c, size_type __pos=0) const noexcept;
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find(const _CharT* __str, size_type __pos=0) const noexcept
|
||||
{ return this->find(__str, __pos, traits_type::length(__str)); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
rfind(basic_string_view __str, size_type __pos = npos) const noexcept
|
||||
{ return this->rfind(__str._M_str, __pos, __str._M_len); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
rfind(_CharT __c, size_type __pos = npos) const noexcept;
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
rfind(const _CharT* __str, size_type __pos = npos) const noexcept
|
||||
{ return this->rfind(__str, __pos, traits_type::length(__str)); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
|
||||
{ return this->find_first_of(__str._M_str, __pos, __str._M_len); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_first_of(_CharT __c, size_type __pos = 0) const noexcept
|
||||
{ return this->find(__c, __pos); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_first_of(const _CharT* __str, size_type __pos, size_type __n) const;
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
|
||||
{ return this->find_first_of(__str, __pos, traits_type::length(__str)); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_last_of(basic_string_view __str,
|
||||
size_type __pos = npos) const noexcept
|
||||
{ return this->find_last_of(__str._M_str, __pos, __str._M_len); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_last_of(_CharT __c, size_type __pos=npos) const noexcept
|
||||
{ return this->rfind(__c, __pos); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_last_of(const _CharT* __str, size_type __pos, size_type __n) const;
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
|
||||
{ return this->find_last_of(__str, __pos, traits_type::length(__str)); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_first_not_of(basic_string_view __str,
|
||||
size_type __pos = 0) const noexcept
|
||||
{ return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_first_not_of(const _CharT* __str,
|
||||
size_type __pos, size_type __n) const;
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
|
||||
{
|
||||
return this->find_first_not_of(__str, __pos,
|
||||
traits_type::length(__str));
|
||||
}
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_last_not_of(basic_string_view __str,
|
||||
size_type __pos = npos) const noexcept
|
||||
{ return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_last_not_of(const _CharT* __str,
|
||||
size_type __pos, size_type __n) const;
|
||||
|
||||
size_type
|
||||
constexpr size_type
|
||||
find_last_not_of(const _CharT* __str,
|
||||
size_type __pos = npos) const noexcept
|
||||
{
|
||||
@ -452,109 +453,109 @@ _GLIBCXX_END_NAMESPACE_VERSION
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator==(basic_string_view<_CharT, _Traits> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator==(basic_string_view<_CharT, _Traits> __x,
|
||||
__detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
|
||||
{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator!=(basic_string_view<_CharT, _Traits> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return !(__x == __y); }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator!=(basic_string_view<_CharT, _Traits> __x,
|
||||
__detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
|
||||
{ return !(__x == __y); }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return !(__x == __y); }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator< (basic_string_view<_CharT, _Traits> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return __x.compare(__y) < 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator< (basic_string_view<_CharT, _Traits> __x,
|
||||
__detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
|
||||
{ return __x.compare(__y) < 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return __x.compare(__y) < 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator> (basic_string_view<_CharT, _Traits> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return __x.compare(__y) > 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator> (basic_string_view<_CharT, _Traits> __x,
|
||||
__detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
|
||||
{ return __x.compare(__y) > 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return __x.compare(__y) > 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator<=(basic_string_view<_CharT, _Traits> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return __x.compare(__y) <= 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator<=(basic_string_view<_CharT, _Traits> __x,
|
||||
__detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
|
||||
{ return __x.compare(__y) <= 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return __x.compare(__y) <= 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator>=(basic_string_view<_CharT, _Traits> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return __x.compare(__y) >= 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator>=(basic_string_view<_CharT, _Traits> __x,
|
||||
__detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
|
||||
{ return __x.compare(__y) >= 0; }
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
|
||||
basic_string_view<_CharT, _Traits> __y) noexcept
|
||||
{ return __x.compare(__y) >= 0; }
|
||||
|
@ -0,0 +1,68 @@
|
||||
// Copyright (C) 2017 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-do compile { target c++14 } }
|
||||
|
||||
#include <experimental/string_view>
|
||||
|
||||
struct constexpr_char_traits : std::char_traits<char>
|
||||
{
|
||||
static constexpr size_t
|
||||
length(const char* val)
|
||||
{
|
||||
size_t res = 0;
|
||||
for (; val[res] != '\0'; ++res)
|
||||
;
|
||||
return res;
|
||||
}
|
||||
|
||||
static constexpr int
|
||||
compare(const char* lhs, const char* rhs, std::size_t count)
|
||||
{
|
||||
for (size_t pos = 0; pos < count; ++pos)
|
||||
{
|
||||
if (lhs[pos] != rhs[pos])
|
||||
return lhs[pos] - rhs[pos];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static constexpr const char*
|
||||
find(const char* p, std::size_t n, char c)
|
||||
{
|
||||
for (size_t pos = 0; pos < n; ++pos)
|
||||
if (p[pos] == c)
|
||||
return p + pos;
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
using string_view
|
||||
= std::experimental::basic_string_view<char, constexpr_char_traits>;
|
||||
|
||||
constexpr
|
||||
string_view get()
|
||||
{
|
||||
string_view res = "x::";
|
||||
string_view start_pattern = "x";
|
||||
res = res.substr(res.find(start_pattern) + start_pattern.size());
|
||||
res = res.substr(0, res.find_first_of(";]"));
|
||||
res = res.substr(res.rfind("::"));
|
||||
return res;
|
||||
}
|
||||
|
||||
static_assert( get() == get() );
|
Loading…
Reference in New Issue
Block a user