diff options
author | emsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-16 17:44:48 +0000 |
---|---|---|
committer | emsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-16 17:44:48 +0000 |
commit | 2fd2d470862f7a6aa1dbb6184ed1863202d59e0b (patch) | |
tree | 514d119f9b28a549f0a74a9bf155e1defe856fd4 /libstdc++-v3/include/experimental | |
parent | da78abba75aabb78383a5116a8899e932eb648ba (diff) | |
download | gcc-2fd2d470862f7a6aa1dbb6184ed1863202d59e0b.tar.gz |
2013-11-16 Edward Smith-Rowland <3dw4rd@verizon.net>
Implement N3762 string_view: a non-owning reference to a string.
* include/Makefile.am: Add string_view and string_view.tcc.
* include/Makefile.in: Regenerate.
* include/experimental/string_view: Implement basic_string_view.
* include/experimental/string_view.tcc: Implement basic_string_view.
* testsuite/experimental/string_view/capacity/1.cc: New.
* testsuite/experimental/string_view/cons/char/1.cc: New.
* testsuite/experimental/string_view/cons/char/2.cc: New.
* testsuite/experimental/string_view/cons/char/3.cc: New.
* testsuite/experimental/string_view/cons/wchar_t/1.cc: New.
* testsuite/experimental/string_view/cons/wchar_t/2.cc: New.
* testsuite/experimental/string_view/cons/wchar_t/3.cc: New.
* testsuite/experimental/string_view/element_access/char/1.cc: New.
* testsuite/experimental/string_view/element_access/char/2.cc: New.
* testsuite/experimental/string_view/element_access/char/empty.cc: New.
* testsuite/experimental/string_view/element_access/char/front_back.cc:
New.
* testsuite/experimental/string_view/element_access/wchar_t/1.cc: New.
* testsuite/experimental/string_view/element_access/wchar_t/2.cc: New.
* testsuite/experimental/string_view/element_access/wchar_t/empty.cc:
New.
* testsuite/experimental/string_view/element_access/wchar_t/
front_back.cc: New.
* testsuite/experimental/string_view/include.cc: New.
* testsuite/experimental/string_view/inserters/char/1.cc: New.
* testsuite/experimental/string_view/inserters/char/2.cc: New.
* testsuite/experimental/string_view/inserters/char/3.cc: New.
* testsuite/experimental/string_view/inserters/pod/10081-out.cc: New.
* testsuite/experimental/string_view/inserters/wchar_t/1.cc: New.
* testsuite/experimental/string_view/inserters/wchar_t/2.cc: New.
* testsuite/experimental/string_view/inserters/wchar_t/3.cc: New.
* testsuite/experimental/string_view/literals/types.cc: New.
* testsuite/experimental/string_view/literals/values.cc: New.
* testsuite/experimental/string_view/modifiers/remove_prefix/char/1.cc:
New.
* testsuite/experimental/string_view/modifiers/remove_prefix/wchar_t/
1.cc: New.
* testsuite/experimental/string_view/modifiers/remove_suffix/char/1.cc:
New.
* testsuite/experimental/string_view/modifiers/remove_suffix/wchar_t/
1.cc: New.
* testsuite/experimental/string_view/operations/compare/char/1.cc: New.
* testsuite/experimental/string_view/operations/compare/char/13650.cc:
New.
* testsuite/experimental/string_view/operations/compare/wchar_t/1.cc:
New.
* testsuite/experimental/string_view/operations/compare/wchar_t/
13650.cc: New.
* testsuite/experimental/string_view/operations/data/char/1.cc: New.
* testsuite/experimental/string_view/operations/data/wchar_t/1.cc: New.
* testsuite/experimental/string_view/operations/find/char/1.cc: New.
* testsuite/experimental/string_view/operations/find/char/2.cc: New.
* testsuite/experimental/string_view/operations/find/char/3.cc: New.
* testsuite/experimental/string_view/operations/find/char/4.cc: New.
* testsuite/experimental/string_view/operations/find/wchar_t/1.cc: New.
* testsuite/experimental/string_view/operations/find/wchar_t/2.cc: New.
* testsuite/experimental/string_view/operations/find/wchar_t/3.cc: New.
* testsuite/experimental/string_view/operations/find/wchar_t/4.cc: New.
* testsuite/experimental/string_view/operations/rfind/char/1.cc: New.
* testsuite/experimental/string_view/operations/rfind/char/2.cc: New.
* testsuite/experimental/string_view/operations/rfind/char/3.cc: New.
* testsuite/experimental/string_view/operations/rfind/wchar_t/1.cc: New.
* testsuite/experimental/string_view/operations/rfind/wchar_t/2.cc: New.
* testsuite/experimental/string_view/operations/rfind/wchar_t/3.cc: New.
* testsuite/experimental/string_view/operations/substr/char/1.cc: New.
* testsuite/experimental/string_view/operations/substr/wchar_t/1.cc:
New.
* testsuite/experimental/string_view/operators/char/2.cc: New.
* testsuite/experimental/string_view/operators/wchar_t/2.cc: New.
* testsuite/experimental/string_view/range_access/char/1.cc: New.
* testsuite/experimental/string_view/range_access/wchar_t/1.cc: New.
* testsuite/experimental/string_view/requirements/
explicit_instantiation/1.cc: New.
* testsuite/experimental/string_view/requirements/
explicit_instantiation/char/1.cc: New.
* testsuite/experimental/string_view/requirements/
explicit_instantiation/char16_t/1.cc: New.
* testsuite/experimental/string_view/requirements/
explicit_instantiation/char32_t/1.cc: New.
* testsuite/experimental/string_view/requirements/
explicit_instantiation/wchar_t/1.cc: New.
* testsuite/experimental/string_view/requirements/typedefs.cc: New.
* testsuite/experimental/string_view/types/1.cc: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204902 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/experimental')
-rw-r--r-- | libstdc++-v3/include/experimental/string_view | 697 | ||||
-rw-r--r-- | libstdc++-v3/include/experimental/string_view.tcc | 230 |
2 files changed, 927 insertions, 0 deletions
diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view new file mode 100644 index 00000000000..d2cb7cfbb66 --- /dev/null +++ b/libstdc++-v3/include/experimental/string_view @@ -0,0 +1,697 @@ +// Components for manipulating non-owning sequences of characters -*- C++ -*- + +// Copyright (C) 2013 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file experimental/string_view + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 21 Strings library +// + +#ifndef _GLIBCXX_EXPERIMENTAL_STRING_VIEW +#define _GLIBCXX_EXPERIMENTAL_STRING_VIEW 1 + +#pragma GCC system_header + +#if __cplusplus <= 201103L +# include <bits/c++14_warning.h> +#else + +#include <debug/debug.h> +#include <string> +#include <limits> + +namespace std //_GLIBCXX_VISIBILITY(default) +{ +namespace experimental +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @class basic_string_view <string_view> + * @brief A non-owning reference to a string. + * + * @ingroup strings + * @ingroup sequences + * + * @tparam _CharT Type of character + * @tparam _Traits Traits for character type, defaults to + * char_traits<_CharT>. + * + * A basic_string_view looks like this: + * + * @code + * _CharT* _M_str + * size_t _M_len + * @endcode + */ + template<typename _CharT, typename _Traits = char_traits<_CharT>> + class basic_string_view + { + + public: + + // types + using traits_type = _Traits; + using value_type = _CharT; + using pointer = const _CharT*; + using const_pointer = const _CharT*; + using reference = const _CharT&; + using const_reference = const _CharT&; + using const_iterator = const _CharT*; + using iterator = const_iterator; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + using reverse_iterator = const_reverse_iterator; + using size_type = size_t; + using difference_type = ptrdiff_t; + static constexpr size_type npos = size_type(-1); + + // [string.view.cons], construct/copy + + constexpr + basic_string_view() noexcept + : _M_len{0}, _M_str{nullptr} + { } + + constexpr basic_string_view(const basic_string_view&) noexcept = default; + + template<typename _Allocator> + basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& __str) noexcept + : _M_len{__str.length()}, _M_str{__str.data()} + { } + + constexpr basic_string_view(const _CharT* __str) + : _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} + { } + + basic_string_view& + operator=(const basic_string_view&) noexcept = default; + + // [string.view.iterators], iterators + + constexpr const_iterator + begin() const noexcept + { return this->_M_str; } + + constexpr const_iterator + end() const noexcept + { return this->_M_str + this->_M_len; } + + constexpr const_iterator + cbegin() const noexcept + { return this->_M_str; } + + constexpr const_iterator + cend() const noexcept + { return this->_M_str + this->_M_len; } + + const_reverse_iterator + rbegin() const noexcept + { return std::reverse_iterator<const_iterator>(this->end()); } + + const_reverse_iterator + rend() const noexcept + { return std::reverse_iterator<const_iterator>(this->begin()); } + + const_reverse_iterator + crbegin() const noexcept + { return std::reverse_iterator<const_iterator>(this->end()); } + + const_reverse_iterator + crend() const noexcept + { return std::reverse_iterator<const_iterator>(this->begin()); } + + // [string.view.capacity], capacity + + constexpr size_type + size() const noexcept + { return this->_M_len; } + + constexpr size_type + length() const noexcept + { return _M_len; } + + constexpr size_type + max_size() const noexcept + { return _S_max_size; } + + constexpr bool + empty() const noexcept + { return this->_M_len == 0; } + + // [string.view.access], element access + + constexpr const _CharT& + operator[](size_type __pos) const + { + _GLIBCXX_DEBUG_ASSERT(__pos <= this->_M_len); + return *(this->_M_str + __pos); + } + + 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()), + *static_cast<pointer>(nullptr)); + } + + constexpr const _CharT& + front() const + { + _GLIBCXX_DEBUG_ASSERT(this->_M_len > 0); + return *this->_M_str; + } + + constexpr const _CharT& + back() const + { + _GLIBCXX_DEBUG_ASSERT(this->_M_len > 0); + return *(this->_M_str + this->_M_len - 1); + } + + constexpr const _CharT* + data() const noexcept + { return this->_M_str; } + + // [string.view.modifiers], modifiers: + void + clear() noexcept + { + this->_M_len = 0; + this->_M_str = nullptr; + } + + void + remove_prefix(size_type __n) + { + _GLIBCXX_DEBUG_ASSERT(this->_M_len >= __n); + this->_M_str += __n; + this->_M_len -= __n; + } + + void + remove_suffix(size_type __n) + { this->_M_len -= __n; } + + void + swap(basic_string_view& __sv) noexcept + { + std::swap(this->_M_len, __sv._M_len); + std::swap(this->_M_str, __sv._M_str); + } + + + // [string.view.ops], string operations: + + template<typename _Allocator> + explicit operator basic_string<_CharT, _Traits, _Allocator>() const + { + return basic_string<_CharT, _Traits, _Allocator> + (this->_M_len, this->_M_str); + } + + size_type + 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::at: __pos " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __pos, this->size()); + size_type __rlen{std::min(__n, size_type{this->_M_len - __pos})}; + for (auto __begin = this->_M_str + __pos, + __end = this->_M_str + __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 + { + 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::at: __pos " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __pos, this->size()), basic_string_view{}); + } + + 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)); + if (__ret == 0) + __ret = _S_compare(this->_M_len, __str._M_len); + return __ret; + } + + int + compare(size_type __pos1, size_type __n1, basic_string_view __str) const + { return this->substr(__pos1, __n1).compare(__str); } + + 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 + compare(const _CharT* __str) const noexcept + { return this->compare(basic_string_view{__str}); } + + int + compare(size_type __pos1, size_type __n1, const _CharT* __str) const + { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); } + + int + compare(size_type __pos1, size_type __n1, + const _CharT* __str, size_type __n2) const + { + return this->substr(__pos1, __n1) + .compare(basic_string_view(__str, __n2)); + } + + 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 + find(_CharT __c, size_type __pos=0) const noexcept; + + size_type + find(const _CharT* __str, size_type __pos, size_type __n) const; + + size_type + find(const _CharT* __str, size_type __pos=0) const noexcept + { return this->find(__str, __pos, traits_type::length(__str)); } + + 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 + rfind(_CharT __c, size_type __pos = npos) const noexcept; + + size_type + rfind(const _CharT* __str, size_type __pos, size_type __n) const; + + size_type + rfind(const _CharT* __str, size_type __pos = npos) const noexcept + { return this->rfind(__str, __pos, traits_type::length(__str)); } + + 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 + find_first_of(_CharT __c, size_type __pos = 0) const noexcept + { return this->find(__c, __pos); } + + size_type + find_first_of(const _CharT* __str, size_type __pos, size_type __n) const; + + 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 + 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 + find_last_of(_CharT __c, size_type __pos=npos) const noexcept + { return this->rfind(__c, __pos); } + + size_type + find_last_of(const _CharT* __str, size_type __pos, size_type __n) const; + + 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 + 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 + find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept; + + size_type + find_first_not_of(const _CharT* __str, + size_type __pos, size_type __n) const; + + 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 + 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 + find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept; + + size_type + find_last_not_of(const _CharT* __str, + size_type __pos, size_type __n) const; + + size_type + find_last_not_of(const _CharT* __str, + size_type __pos = npos) const noexcept + { + return this->find_last_not_of(__str, __pos, + traits_type::length(__str)); + } + + private: + + // Compute max_size similarly to how string does it. + static const size_type _S_max_size = (npos + - sizeof(size_type) - sizeof(void*)) + / sizeof(value_type) / 4; + + static constexpr const 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}); + } + + size_t _M_len; + const _CharT* _M_str; + }; + + + // [string.view.comparison], non-member basic_string_view comparison functions + + namespace __detail + { + // Identity transform to make ADL work with just one argument. + // See n3766.html. + template<typename _Tp = void> + struct __identity + { typedef _Tp type; }; + + template<> + struct __identity<void>; + + template<typename _Tp> + using __idt = typename __identity<_Tp>::type; + } + + template<typename _CharT, typename _Traits> + 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> + 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> + 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> + bool + operator!=(basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return !(__x == __y); } + + template<typename _CharT, typename _Traits> + 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> + 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> + 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> + 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> + 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> + 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> + 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> + 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> + 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> + 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> + 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> + 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> + 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> + bool + operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) >= 0; } + + // [string.view.comparison], sufficient additional overloads of comparison functions + + // [string.view.nonmem], other non-member basic_string_view functions + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Allocator = allocator<_CharT>> + basic_string<_CharT, _Traits, _Allocator> + to_string(basic_string_view<_CharT, _Traits> __str, + const _Allocator& __alloc = _Allocator()) + { + return basic_string<_CharT, _Traits, _Allocator> + (__str.begin(), __str.end(), __alloc); + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + basic_string_view<_CharT,_Traits> __str) + { return __ostream_insert(__os, __str.data(), __str.size()); } + + + // basic_string_view typedef names + + using string_view = basic_string_view<char>; +#ifdef _GLIBCXX_USE_WCHAR_T + using wstring_view = basic_string_view<wchar_t>; +#endif +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + using u16string_view = basic_string_view<char16_t>; + using u32string_view = basic_string_view<char32_t>; +#endif + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace experimental + + + // [string.view.hash], hash support: + +_GLIBCXX_BEGIN_NAMESPACE_VERSION + template<typename _Tp> + struct hash; + + template<> + struct hash<experimental::string_view> + : public __hash_base<size_t, experimental::string_view> + { + size_t + operator()(const experimental::string_view& __str) const noexcept + { return std::_Hash_impl::hash(__str.data(), __str.length()); } + }; + + template<> + struct __is_fast_hash<hash<experimental::string_view>> : std::false_type + { }; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + struct hash<experimental::wstring_view> + : public __hash_base<size_t, wstring> + { + size_t + operator()(const experimental::wstring_view& __s) const noexcept + { return std::_Hash_impl::hash(__s.data(), + __s.length() * sizeof(wchar_t)); } + }; + + template<> + struct __is_fast_hash<hash<experimental::wstring_view>> : std::false_type + { }; +#endif + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + template<> + struct hash<experimental::u16string_view> + : public __hash_base<size_t, experimental::u16string_view> + { + size_t + operator()(const experimental::u16string_view& __s) const noexcept + { return std::_Hash_impl::hash(__s.data(), + __s.length() * sizeof(char16_t)); } + }; + + template<> + struct __is_fast_hash<hash<experimental::u16string_view>> : std::false_type + { }; + + template<> + struct hash<experimental::u32string_view> + : public __hash_base<size_t, experimental::u32string_view> + { + size_t + operator()(const experimental::u32string_view& __s) const noexcept + { return std::_Hash_impl::hash(__s.data(), + __s.length() * sizeof(char32_t)); } + }; + + template<> + struct __is_fast_hash<hash<experimental::u32string_view>> : std::false_type + { }; +#endif +_GLIBCXX_END_NAMESPACE_VERSION + +namespace experimental +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // I added these EMSR. + inline namespace literals + { + inline namespace string_view_literals + { + + inline basic_string_view<char> + operator""sv(const char* __str, size_t __len) + { return basic_string_view<char>{__str, __len}; } + +#ifdef _GLIBCXX_USE_WCHAR_T + inline basic_string_view<wchar_t> + operator""sv(const wchar_t* __str, size_t __len) + { return basic_string_view<wchar_t>{__str, __len}; } +#endif + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + inline basic_string_view<char16_t> + operator""sv(const char16_t* __str, size_t __len) + { return basic_string_view<char16_t>{__str, __len}; } + + inline basic_string_view<char32_t> + operator""sv(const char32_t* __str, size_t __len) + { return basic_string_view<char32_t>{__str, __len}; } +#endif + + } + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace experimental +} // namespace std + +#include <experimental/string_view.tcc> + +#endif // __cplusplus <= 201103L + +#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW diff --git a/libstdc++-v3/include/experimental/string_view.tcc b/libstdc++-v3/include/experimental/string_view.tcc new file mode 100644 index 00000000000..78cbe99e80f --- /dev/null +++ b/libstdc++-v3/include/experimental/string_view.tcc @@ -0,0 +1,230 @@ +// Components for manipulating non-owning sequences of characters -*- C++ -*- + +// Copyright (C) 2013 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file experimental/string_view.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{string_view} + */ + +// +// ISO C++ 14882: 21 Strings library +// + +#ifndef _GLIBCXX_EXPERIMENTAL_STRING_VIEW_TCC +#define _GLIBCXX_EXPERIMENTAL_STRING_VIEW_TCC 1 + +#pragma GCC system_header + +#if __cplusplus <= 201103L +# include <bits/c++14_warning.h> +#else + +namespace std //_GLIBCXX_VISIBILITY(default) +{ +namespace experimental +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template<typename _CharT, typename _Traits> + 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 + { + __glibcxx_requires_string_len(__str, __n); + + if (__n == 0) + return __pos <= this->_M_len ? __pos : npos; + + if (__n <= this->_M_len) + { + for (; __pos <= this->_M_len - __n; ++__pos) + if (traits_type::eq(this->_M_str[__pos], __str[0]) + && traits_type::compare(this->_M_str + __pos + 1, + __str + 1, __n - 1) == 0) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits> + typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find(_CharT __c, size_type __pos) const noexcept + { + size_type __ret = npos; + if (__pos < this->_M_len) + { + const size_type __n = this->_M_len - __pos; + const _CharT* __p = traits_type::find(this->_M_str + __pos, __n, __c); + if (__p) + __ret = __p - this->_M_str; + } + return __ret; + } + + template<typename _CharT, typename _Traits> + 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 + { + __glibcxx_requires_string_len(__str, __n); + + if (__n <= this->_M_len) + { + __pos = std::min(size_type(this->_M_len - __n), __pos); + do + { + if (traits_type::compare(this->_M_str + __pos, __str, __n) == 0) + return __pos; + } + while (__pos-- > 0); + } + return npos; + } + + template<typename _CharT, typename _Traits> + typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + rfind(_CharT __c, size_type __pos) const noexcept + { + size_type __size = this->_M_len; + if (__size > 0) + { + if (--__size > __pos) + __size = __pos; + for (++__size; __size-- > 0; ) + if (traits_type::eq(this->_M_str[__size], __c)) + return __size; + } + return npos; + } + + template<typename _CharT, typename _Traits> + 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 + { + __glibcxx_requires_string_len(__str, __n); + for (; __n && __pos < this->_M_len; ++__pos) + { + const _CharT* __p = traits_type::find(__str, __n, + this->_M_str[__pos]); + if (__p) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits> + 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 + { + __glibcxx_requires_string_len(__str, __n); + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + if (traits_type::find(__str, __n, this->_M_str[__size])) + return __size; + } + while (__size-- != 0); + } + return npos; + } + + template<typename _CharT, typename _Traits> + 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 + { + __glibcxx_requires_string_len(__str, __n); + for (; __pos < this->_M_len; ++__pos) + if (!traits_type::find(__str, __n, this->_M_str[__pos])) + return __pos; + return npos; + } + + template<typename _CharT, typename _Traits> + typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_first_not_of(_CharT __c, size_type __pos) const noexcept + { + for (; __pos < this->_M_len; ++__pos) + if (!traits_type::eq(this->_M_str[__pos], __c)) + return __pos; + return npos; + } + + template<typename _CharT, typename _Traits> + 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 + { + __glibcxx_requires_string_len(__str, __n); + size_type __size = this->_M_len; + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::find(__str, __n, this->_M_str[__size])) + return __size; + } + while (__size--); + } + return npos; + } + + template<typename _CharT, typename _Traits> + typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_last_not_of(_CharT __c, size_type __pos) const noexcept + { + size_type __size = this->_M_len; + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::eq(this->_M_str[__size], __c)) + return __size; + } + while (__size--); + } + return npos; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace experimental +} // namespace std + +#endif // __cplusplus <= 201103L + +#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW_TCC |