1    	// Components for manipulating non-owning sequences of characters -*- C++ -*-
2    	
3    	// Copyright (C) 2013-2017 Free Software Foundation, Inc.
4    	//
5    	// This file is part of the GNU ISO C++ Library.  This library is free
6    	// software; you can redistribute it and/or modify it under the
7    	// terms of the GNU General Public License as published by the
8    	// Free Software Foundation; either version 3, or (at your option)
9    	// any later version.
10   	
11   	// This library is distributed in the hope that it will be useful,
12   	// but WITHOUT ANY WARRANTY; without even the implied warranty of
13   	// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   	// GNU General Public License for more details.
15   	
16   	// Under Section 7 of GPL version 3, you are granted additional
17   	// permissions described in the GCC Runtime Library Exception, version
18   	// 3.1, as published by the Free Software Foundation.
19   	
20   	// You should have received a copy of the GNU General Public License and
21   	// a copy of the GCC Runtime Library Exception along with this program;
22   	// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23   	// <http://www.gnu.org/licenses/>.
24   	
25   	/** @file experimental/string_view
26   	 *  This is a TS C++ Library header.
27   	 */
28   	
29   	//
30   	// N3762 basic_string_view library
31   	//
32   	
33   	#ifndef _GLIBCXX_EXPERIMENTAL_STRING_VIEW
34   	#define _GLIBCXX_EXPERIMENTAL_STRING_VIEW 1
35   	
36   	#pragma GCC system_header
37   	
38   	#if __cplusplus >= 201402L
39   	
40   	#include <string>
41   	#include <limits>
42   	#include <experimental/bits/lfts_config.h>
43   	
44   	namespace std _GLIBCXX_VISIBILITY(default)
45   	{
46   	namespace experimental
47   	{
48   	inline namespace fundamentals_v1
49   	{
50   	_GLIBCXX_BEGIN_NAMESPACE_VERSION
51   	
52   	#define __cpp_lib_experimental_string_view 201411
53   	
54   	  /**
55   	   *  @class basic_string_view <experimental/string_view>
56   	   *  @brief  A non-owning reference to a string.
57   	   *
58   	   *  @ingroup strings
59   	   *  @ingroup sequences
60   	   *  @ingroup experimental
61   	   *
62   	   *  @tparam _CharT  Type of character
63   	   *  @tparam _Traits  Traits for character type, defaults to
64   	   *                   char_traits<_CharT>.
65   	   *
66   	   *  A basic_string_view looks like this:
67   	   *
68   	   *  @code
69   	   *    _CharT*    _M_str
70   	   *    size_t     _M_len
71   	   *  @endcode
72   	   */
73   	  template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
74   	    class basic_string_view
75   	    {
76   	    public:
77   	
78   	      // types
79   	      using traits_type = _Traits;
80   	      using value_type = _CharT;
81   	      using pointer = const _CharT*;
82   	      using const_pointer = const _CharT*;
83   	      using reference = const _CharT&;
84   	      using const_reference = const _CharT&;
85   	      using const_iterator = const _CharT*;
86   	      using iterator = const_iterator;
87   	      using const_reverse_iterator = std::reverse_iterator<const_iterator>;
88   	      using reverse_iterator = const_reverse_iterator;
89   	      using size_type = size_t;
90   	      using difference_type = ptrdiff_t;
91   	      static constexpr size_type npos = size_type(-1);
92   	
93   	      // [string.view.cons], construct/copy
94   	
95   	      constexpr
96   	      basic_string_view() noexcept
97   	      : _M_len{0}, _M_str{nullptr}
98   	      { }
99   	
100  	      constexpr basic_string_view(const basic_string_view&) noexcept = default;
101  	
102  	      template<typename _Allocator>
103  	        basic_string_view(const basic_string<_CharT, _Traits,
104  				  _Allocator>& __str) noexcept
105  	        : _M_len{__str.length()}, _M_str{__str.data()}
106  	        { }
107  	
108  	      constexpr basic_string_view(const _CharT* __str)
109  	      : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
110  		_M_str{__str}
111  	      { }
112  	
113  	      constexpr basic_string_view(const _CharT* __str, size_type __len)
114  	      : _M_len{__len},
115  	        _M_str{__str}
116  	      { }
117  	
118  	      basic_string_view&
119  	      operator=(const basic_string_view&) noexcept = default;
120  	
121  	      // [string.view.iterators], iterators
122  	
123  	      constexpr const_iterator
124  	      begin() const noexcept
125  	      { return this->_M_str; }
126  	
127  	      constexpr const_iterator
128  	      end() const noexcept
129  	      { return this->_M_str + this->_M_len; }
130  	
131  	      constexpr const_iterator
132  	      cbegin() const noexcept
133  	      { return this->_M_str; }
134  	
135  	      constexpr const_iterator
136  	      cend() const noexcept
137  	      { return this->_M_str + this->_M_len; }
138  	
139  	      const_reverse_iterator
140  	      rbegin() const noexcept
141  	      { return const_reverse_iterator(this->end()); }
142  	
143  	      const_reverse_iterator
144  	      rend() const noexcept
145  	      { return const_reverse_iterator(this->begin()); }
146  	
147  	      const_reverse_iterator
148  	      crbegin() const noexcept
149  	      { return const_reverse_iterator(this->end()); }
150  	
151  	      const_reverse_iterator
152  	      crend() const noexcept
153  	      { return const_reverse_iterator(this->begin()); }
154  	
155  	      // [string.view.capacity], capacity
156  	
157  	      constexpr size_type
158  	      size() const noexcept
159  	      { return this->_M_len; }
160  	
161  	      constexpr size_type
162  	      length() const noexcept
163  	      { return _M_len; }
164  	
165  	      constexpr size_type
166  	      max_size() const noexcept
167  	      {
168  		return (npos - sizeof(size_type) - sizeof(void*))
169  			/ sizeof(value_type) / 4;
170  	      }
171  	
172  	      constexpr bool
173  	      empty() const noexcept
174  	      { return this->_M_len == 0; }
175  	
176  	      // [string.view.access], element access
177  	
178  	      constexpr const _CharT&
179  	      operator[](size_type __pos) const
180  	      {
181  		// TODO: Assert to restore in a way compatible with the constexpr.
182  		// __glibcxx_assert(__pos < this->_M_len);
183  		return *(this->_M_str + __pos);
184  	      }
185  	
186  	      constexpr const _CharT&
187  	      at(size_type __pos) const
188  	      {
189  		return __pos < this->_M_len
190  		     ? *(this->_M_str + __pos)
191  		     : (__throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
192  						     "(which is %zu) >= this->size() "
193  						     "(which is %zu)"),
194  						 __pos, this->size()),
195  			*this->_M_str);
196  	      }
197  	
198  	      constexpr const _CharT&
199  	      front() const
200  	      {
201  		// TODO: Assert to restore in a way compatible with the constexpr.
202  		// __glibcxx_assert(this->_M_len > 0);
203  		return *this->_M_str;
204  	      }
205  	
206  	      constexpr const _CharT&
207  	      back() const
208  	      {
209  		// TODO: Assert to restore in a way compatible with the constexpr.
210  		// __glibcxx_assert(this->_M_len > 0);
211  		return *(this->_M_str + this->_M_len - 1);
212  	      }
213  	
214  	      constexpr const _CharT*
215  	      data() const noexcept
216  	      { return this->_M_str; }
217  	
218  	      // [string.view.modifiers], modifiers:
219  	
220  	      constexpr void
221  	      remove_prefix(size_type __n)
222  	      {
223  		__glibcxx_assert(this->_M_len >= __n);
224  		this->_M_str += __n;
225  		this->_M_len -= __n;
226  	      }
227  	
228  	      constexpr void
229  	      remove_suffix(size_type __n)
230  	      { this->_M_len -= __n; }
231  	
232  	      constexpr void
233  	      swap(basic_string_view& __sv) noexcept
234  	      {
235  		auto __tmp = *this;
236  		*this = __sv;
237  		__sv = __tmp;
238  	      }
239  	
240  	
241  	      // [string.view.ops], string operations:
242  	
243  	      template<typename _Allocator>
244  	        explicit operator basic_string<_CharT, _Traits, _Allocator>() const
245  	        {
246  		  return { this->_M_str, this->_M_len };
247  		}
248  	
249  	      template<typename _Allocator = std::allocator<_CharT>>
250  		basic_string<_CharT, _Traits, _Allocator>
251  		to_string(const _Allocator& __alloc = _Allocator()) const
252  		{
253  		  return { this->_M_str, this->_M_len, __alloc };
254  		}
255  	
256  	      size_type
257  	      copy(_CharT* __str, size_type __n, size_type __pos = 0) const
258  	      {
259  		__glibcxx_requires_string_len(__str, __n);
260  		if (__pos > this->_M_len)
261  		  __throw_out_of_range_fmt(__N("basic_string_view::copy: __pos "
262  					       "(which is %zu) > this->size() "
263  					       "(which is %zu)"),
264  					   __pos, this->size());
265  		size_type __rlen{std::min(__n, size_type{this->_M_len  - __pos})};
266  		for (auto __begin = this->_M_str + __pos,
267  		     __end = __begin + __rlen; __begin != __end;)
268  		  *__str++ = *__begin++;
269  		return __rlen;
270  	      }
271  	
272  	
273  	      // [string.view.ops], string operations:
274  	
275  	      constexpr basic_string_view
276  	      substr(size_type __pos, size_type __n=npos) const
277  	      {
278  		return __pos <= this->_M_len
279  		     ? basic_string_view{this->_M_str + __pos,
280  					std::min(__n, size_type{this->_M_len  - __pos})}
281  		     : (__throw_out_of_range_fmt(__N("basic_string_view::substr: __pos "
282  						     "(which is %zu) > this->size() "
283  						     "(which is %zu)"),
284  					     __pos, this->size()), basic_string_view{});
285  	      }
286  	
287  	      constexpr int
288  	      compare(basic_string_view __str) const noexcept
289  	      {
290  		int __ret = traits_type::compare(this->_M_str, __str._M_str,
291  						 std::min(this->_M_len, __str._M_len));
292  		if (__ret == 0)
293  		  __ret = _S_compare(this->_M_len, __str._M_len);
294  		return __ret;
295  	      }
296  	
297  	      constexpr int
298  	      compare(size_type __pos1, size_type __n1, basic_string_view __str) const
299  	      { return this->substr(__pos1, __n1).compare(__str); }
300  	
301  	      constexpr int
302  	      compare(size_type __pos1, size_type __n1,
303  		      basic_string_view __str, size_type __pos2, size_type __n2) const
304  	      { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); }
305  	
306  	      constexpr int
307  	      compare(const _CharT* __str) const noexcept
308  	      { return this->compare(basic_string_view{__str}); }
309  	
310  	      constexpr int
311  	      compare(size_type __pos1, size_type __n1, const _CharT* __str) const
312  	      { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
313  	
314  	      constexpr int
315  	      compare(size_type __pos1, size_type __n1,
316  		      const _CharT* __str, size_type __n2) const
317  	      {
318  		return this->substr(__pos1, __n1)
319  			   .compare(basic_string_view(__str, __n2));
320  	      }
321  	
322  	      constexpr size_type
323  	      find(basic_string_view __str, size_type __pos = 0) const noexcept
324  	      { return this->find(__str._M_str, __pos, __str._M_len); }
325  	
326  	      constexpr size_type
327  	      find(_CharT __c, size_type __pos=0) const noexcept;
328  	
329  	      constexpr size_type
330  	      find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
331  	
332  	      constexpr size_type
333  	      find(const _CharT* __str, size_type __pos=0) const noexcept
334  	      { return this->find(__str, __pos, traits_type::length(__str)); }
335  	
336  	      constexpr size_type
337  	      rfind(basic_string_view __str, size_type __pos = npos) const noexcept
338  	      { return this->rfind(__str._M_str, __pos, __str._M_len); }
339  	
340  	      constexpr size_type
341  	      rfind(_CharT __c, size_type __pos = npos) const noexcept;
342  	
343  	      constexpr size_type
344  	      rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
345  	
346  	      constexpr size_type
347  	      rfind(const _CharT* __str, size_type __pos = npos) const noexcept
348  	      { return this->rfind(__str, __pos, traits_type::length(__str)); }
349  	
350  	      constexpr size_type
351  	      find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
352  	      { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
353  	
354  	      constexpr size_type
355  	      find_first_of(_CharT __c, size_type __pos = 0) const noexcept
356  	      { return this->find(__c, __pos); }
357  	
358  	      constexpr size_type
359  	      find_first_of(const _CharT* __str, size_type __pos, size_type __n) const;
360  	
361  	      constexpr size_type
362  	      find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
363  	      { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
364  	
365  	      constexpr size_type
366  	      find_last_of(basic_string_view __str,
367  			   size_type __pos = npos) const noexcept
368  	      { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
369  	
370  	      constexpr size_type
371  	      find_last_of(_CharT __c, size_type __pos=npos) const noexcept
372  	      { return this->rfind(__c, __pos); }
373  	
374  	      constexpr size_type
375  	      find_last_of(const _CharT* __str, size_type __pos, size_type __n) const;
376  	
377  	      constexpr size_type
378  	      find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
379  	      { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
380  	
381  	      constexpr size_type
382  	      find_first_not_of(basic_string_view __str,
383  				size_type __pos = 0) const noexcept
384  	      { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
385  	
386  	      constexpr size_type
387  	      find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
388  	
389  	      constexpr size_type
390  	      find_first_not_of(const _CharT* __str,
391  				size_type __pos, size_type __n) const;
392  	
393  	      constexpr size_type
394  	      find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
395  	      {
396  		return this->find_first_not_of(__str, __pos,
397  					       traits_type::length(__str));
398  	      }
399  	
400  	      constexpr size_type
401  	      find_last_not_of(basic_string_view __str,
402  			       size_type __pos = npos) const noexcept
403  	      { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
404  	
405  	      constexpr size_type
406  	      find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
407  	
408  	      constexpr size_type
409  	      find_last_not_of(const _CharT* __str,
410  			       size_type __pos, size_type __n) const;
411  	
412  	      constexpr size_type
413  	      find_last_not_of(const _CharT* __str,
414  			       size_type __pos = npos) const noexcept
415  	      {
416  		return this->find_last_not_of(__str, __pos,
417  					      traits_type::length(__str));
418  	      }
419  	
420  	    private:
421  	
422  	      static constexpr int
423  	      _S_compare(size_type __n1, size_type __n2) noexcept
424  	      {
425  		return difference_type{__n1 - __n2} > std::numeric_limits<int>::max()
426  		     ? std::numeric_limits<int>::max()
427  		     : difference_type{__n1 - __n2} < std::numeric_limits<int>::min()
428  		     ? std::numeric_limits<int>::min()
429  		     : static_cast<int>(difference_type{__n1 - __n2});
430  	      }
431  	
432  	      size_t	    _M_len;
433  	      const _CharT* _M_str;
434  	    };
435  	
436  	_GLIBCXX_END_NAMESPACE_VERSION
437  	
438  	  // [string.view.comparison], non-member basic_string_view comparison functions
439  	
440  	  namespace __detail
441  	  {
442  	_GLIBCXX_BEGIN_NAMESPACE_VERSION
443  	    // Identity transform to create a non-deduced context, so that only one
444  	    // argument participates in template argument deduction and the other
445  	    // argument gets implicitly converted to the deduced type. See n3766.html.
446  	    template<typename _Tp>
447  	      using __idt = common_type_t<_Tp>;
448  	_GLIBCXX_END_NAMESPACE_VERSION
449  	  }
450  	
451  	_GLIBCXX_BEGIN_NAMESPACE_VERSION
452  	
453  	  template<typename _CharT, typename _Traits>
454  	    constexpr bool
455  	    operator==(basic_string_view<_CharT, _Traits> __x,
456  	               basic_string_view<_CharT, _Traits> __y) noexcept
457  	    { return __x.size() == __y.size() && __x.compare(__y) == 0; }
458  	
459  	  template<typename _CharT, typename _Traits>
460  	    constexpr bool
461  	    operator==(basic_string_view<_CharT, _Traits> __x,
462  	               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
463  	    { return __x.size() == __y.size() && __x.compare(__y) == 0; }
464  	
465  	  template<typename _CharT, typename _Traits>
466  	    constexpr bool
467  	    operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
468  	               basic_string_view<_CharT, _Traits> __y) noexcept
469  	    { return __x.size() == __y.size() && __x.compare(__y) == 0; }
470  	
471  	  template<typename _CharT, typename _Traits>
472  	    constexpr bool
473  	    operator!=(basic_string_view<_CharT, _Traits> __x,
474  	               basic_string_view<_CharT, _Traits> __y) noexcept
475  	    { return !(__x == __y); }
476  	
477  	  template<typename _CharT, typename _Traits>
478  	    constexpr bool
479  	    operator!=(basic_string_view<_CharT, _Traits> __x,
480  	               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
481  	    { return !(__x == __y); }
482  	
483  	  template<typename _CharT, typename _Traits>
484  	    constexpr bool
485  	    operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
486  	               basic_string_view<_CharT, _Traits> __y) noexcept
487  	    { return !(__x == __y); }
488  	
489  	  template<typename _CharT, typename _Traits>
490  	    constexpr bool
491  	    operator< (basic_string_view<_CharT, _Traits> __x,
492  	               basic_string_view<_CharT, _Traits> __y) noexcept
493  	    { return __x.compare(__y) < 0; }
494  	
495  	  template<typename _CharT, typename _Traits>
496  	    constexpr bool
497  	    operator< (basic_string_view<_CharT, _Traits> __x,
498  	               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
499  	    { return __x.compare(__y) < 0; }
500  	
501  	  template<typename _CharT, typename _Traits>
502  	    constexpr bool
503  	    operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
504  	               basic_string_view<_CharT, _Traits> __y) noexcept
505  	    { return __x.compare(__y) < 0; }
506  	
507  	  template<typename _CharT, typename _Traits>
508  	    constexpr bool
509  	    operator> (basic_string_view<_CharT, _Traits> __x,
510  	               basic_string_view<_CharT, _Traits> __y) noexcept
511  	    { return __x.compare(__y) > 0; }
512  	
513  	  template<typename _CharT, typename _Traits>
514  	    constexpr bool
515  	    operator> (basic_string_view<_CharT, _Traits> __x,
516  	               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
517  	    { return __x.compare(__y) > 0; }
518  	
519  	  template<typename _CharT, typename _Traits>
520  	    constexpr bool
521  	    operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
522  	               basic_string_view<_CharT, _Traits> __y) noexcept
523  	    { return __x.compare(__y) > 0; }
524  	
525  	  template<typename _CharT, typename _Traits>
526  	    constexpr bool
527  	    operator<=(basic_string_view<_CharT, _Traits> __x,
528  	               basic_string_view<_CharT, _Traits> __y) noexcept
529  	    { return __x.compare(__y) <= 0; }
530  	
531  	  template<typename _CharT, typename _Traits>
532  	    constexpr bool
533  	    operator<=(basic_string_view<_CharT, _Traits> __x,
534  	               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
535  	    { return __x.compare(__y) <= 0; }
536  	
537  	  template<typename _CharT, typename _Traits>
538  	    constexpr bool
539  	    operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
540  	               basic_string_view<_CharT, _Traits> __y) noexcept
541  	    { return __x.compare(__y) <= 0; }
542  	
543  	  template<typename _CharT, typename _Traits>
544  	    constexpr bool
545  	    operator>=(basic_string_view<_CharT, _Traits> __x,
546  	               basic_string_view<_CharT, _Traits> __y) noexcept
547  	    { return __x.compare(__y) >= 0; }
548  	
549  	  template<typename _CharT, typename _Traits>
550  	    constexpr bool
551  	    operator>=(basic_string_view<_CharT, _Traits> __x,
552  	               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
553  	    { return __x.compare(__y) >= 0; }
554  	
555  	  template<typename _CharT, typename _Traits>
556  	    constexpr bool
557  	    operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
558  	               basic_string_view<_CharT, _Traits> __y) noexcept
559  	    { return __x.compare(__y) >= 0; }
560  	
561  	  // [string.view.io], Inserters and extractors
562  	  template<typename _CharT, typename _Traits>
563  	    inline basic_ostream<_CharT, _Traits>&
564  	    operator<<(basic_ostream<_CharT, _Traits>& __os,
565  		       basic_string_view<_CharT,_Traits> __str)
566  	    { return __ostream_insert(__os, __str.data(), __str.size()); }
567  	
568  	
569  	  // basic_string_view typedef names
570  	
571  	  using string_view = basic_string_view<char>;
572  	#ifdef _GLIBCXX_USE_WCHAR_T
573  	  using wstring_view = basic_string_view<wchar_t>;
574  	#endif
575  	#ifdef _GLIBCXX_USE_C99_STDINT_TR1
576  	  using u16string_view = basic_string_view<char16_t>;
577  	  using u32string_view = basic_string_view<char32_t>;
578  	#endif
579  	
580  	_GLIBCXX_END_NAMESPACE_VERSION
581  	} // namespace fundamentals_v1
582  	} // namespace experimental
583  	
584  	
585  	  // [string.view.hash], hash support:
586  	
587  	_GLIBCXX_BEGIN_NAMESPACE_VERSION
588  	  template<typename _Tp>
589  	    struct hash;
590  	
591  	  template<>
592  	    struct hash<experimental::string_view>
593  	    : public __hash_base<size_t, experimental::string_view>
594  	    {
595  	      size_t
596  	      operator()(const experimental::string_view& __str) const noexcept
597  	      { return std::_Hash_impl::hash(__str.data(), __str.length()); }
598  	    };
599  	
600  	  template<>
601  	    struct __is_fast_hash<hash<experimental::string_view>> : std::false_type
602  	    { };
603  	
604  	#ifdef _GLIBCXX_USE_WCHAR_T
605  	  template<>
606  	    struct hash<experimental::wstring_view>
607  	    : public __hash_base<size_t, wstring>
608  	    {
609  	      size_t
610  	      operator()(const experimental::wstring_view& __s) const noexcept
611  	      { return std::_Hash_impl::hash(__s.data(),
612  	                                     __s.length() * sizeof(wchar_t)); }
613  	    };
614  	
615  	  template<>
616  	    struct __is_fast_hash<hash<experimental::wstring_view>> : std::false_type
617  	    { };
618  	#endif
619  	
620  	#ifdef _GLIBCXX_USE_C99_STDINT_TR1
621  	  template<>
622  	    struct hash<experimental::u16string_view>
623  	    : public __hash_base<size_t, experimental::u16string_view>
624  	    {
625  	      size_t
626  	      operator()(const experimental::u16string_view& __s) const noexcept
627  	      { return std::_Hash_impl::hash(__s.data(),
628  	                                     __s.length() * sizeof(char16_t)); }
629  	    };
630  	
631  	  template<>
632  	    struct __is_fast_hash<hash<experimental::u16string_view>> : std::false_type
633  	    { };
634  	
635  	  template<>
636  	    struct hash<experimental::u32string_view>
637  	    : public __hash_base<size_t, experimental::u32string_view>
638  	    {
639  	      size_t
640  	      operator()(const experimental::u32string_view& __s) const noexcept
641  	      { return std::_Hash_impl::hash(__s.data(),
642  	                                     __s.length() * sizeof(char32_t)); }
643  	    };
644  	
645  	  template<>
646  	    struct __is_fast_hash<hash<experimental::u32string_view>> : std::false_type
647  	    { };
648  	#endif
649  	_GLIBCXX_END_NAMESPACE_VERSION
650  	
651  	namespace experimental
652  	{
653  	  // I added these EMSR.
654  	  inline namespace literals
655  	  {
656  	  inline namespace string_view_literals
657  	  {
658  	  _GLIBCXX_BEGIN_NAMESPACE_VERSION
659  	
660  	    inline constexpr basic_string_view<char>
661  	    operator""sv(const char* __str, size_t __len) noexcept
662  	    { return basic_string_view<char>{__str, __len}; }
663  	
664  	#ifdef _GLIBCXX_USE_WCHAR_T
665  	    inline constexpr basic_string_view<wchar_t>
666  	    operator""sv(const wchar_t* __str, size_t __len) noexcept
667  	    { return basic_string_view<wchar_t>{__str, __len}; }
668  	#endif
669  	
670  	#ifdef _GLIBCXX_USE_C99_STDINT_TR1
671  	    inline constexpr basic_string_view<char16_t>
672  	    operator""sv(const char16_t* __str, size_t __len) noexcept
673  	    { return basic_string_view<char16_t>{__str, __len}; }
674  	
675  	    inline constexpr basic_string_view<char32_t>
676  	    operator""sv(const char32_t* __str, size_t __len) noexcept
677  	    { return basic_string_view<char32_t>{__str, __len}; }
678  	#endif
679  	
680  	  _GLIBCXX_END_NAMESPACE_VERSION
681  	  } // namespace string_literals
682  	  } // namespace literals
683  	} // namespace experimental
684  	} // namespace std
685  	
686  	#include <experimental/bits/string_view.tcc>
687  	
688  	#endif // __cplusplus <= 201103L
689  	
690  	#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW
691