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:
Jonathan Wakely 2017-09-12 17:27:14 +01:00 committed by Jonathan Wakely
parent 53e7178da5
commit e38bde5423
4 changed files with 150 additions and 63 deletions

View File

@ -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>

View File

@ -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
{

View File

@ -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; }

View File

@ -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() );