Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // Components for manipulating non-owning sequences of characters -*- C++ -*-
  2.  
  3. // Copyright (C) 2013-2015 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 <= 201103L
  39. # include <bits/c++14_warning.h>
  40. #else
  41.  
  42. #include <string>
  43. #include <limits>
  44.  
  45. namespace std _GLIBCXX_VISIBILITY(default)
  46. {
  47. namespace experimental
  48. {
  49. inline namespace fundamentals_v1
  50. {
  51. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  52.  
  53. #define __cpp_lib_experimental_string_view 201411
  54.  
  55.   /**
  56.    *  @class basic_string_view <experimental/string_view>
  57.    *  @brief  A non-owning reference to a string.
  58.    *
  59.    *  @ingroup strings
  60.    *  @ingroup sequences
  61.    *  @ingroup experimental
  62.    *
  63.    *  @tparam _CharT  Type of character
  64.    *  @tparam _Traits  Traits for character type, defaults to
  65.    *                   char_traits<_CharT>.
  66.    *
  67.    *  A basic_string_view looks like this:
  68.    *
  69.    *  @code
  70.    *    _CharT*    _M_str
  71.    *    size_t     _M_len
  72.    *  @endcode
  73.    */
  74.   template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
  75.     class basic_string_view
  76.     {
  77.     public:
  78.  
  79.       // types
  80.       using traits_type = _Traits;
  81.       using value_type = _CharT;
  82.       using pointer = const _CharT*;
  83.       using const_pointer = const _CharT*;
  84.       using reference = const _CharT&;
  85.       using const_reference = const _CharT&;
  86.       using const_iterator = const _CharT*;
  87.       using iterator = const_iterator;
  88.       using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  89.       using reverse_iterator = const_reverse_iterator;
  90.       using size_type = size_t;
  91.       using difference_type = ptrdiff_t;
  92.       static constexpr size_type npos = size_type(-1);
  93.  
  94.       // [string.view.cons], construct/copy
  95.  
  96.       constexpr
  97.       basic_string_view() noexcept
  98.       : _M_len{0}, _M_str{nullptr}
  99.       { }
  100.  
  101.       constexpr basic_string_view(const basic_string_view&) noexcept = default;
  102.  
  103.       template<typename _Allocator>
  104.         basic_string_view(const basic_string<_CharT, _Traits,
  105.                           _Allocator>& __str) noexcept
  106.         : _M_len{__str.length()}, _M_str{__str.data()}
  107.         { }
  108.  
  109.       constexpr basic_string_view(const _CharT* __str)
  110.       : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
  111.         _M_str{__str}
  112.       { }
  113.  
  114.       constexpr basic_string_view(const _CharT* __str, size_type __len)
  115.       : _M_len{__len},
  116.         _M_str{__str}
  117.       { }
  118.  
  119.       basic_string_view&
  120.       operator=(const basic_string_view&) noexcept = default;
  121.  
  122.       // [string.view.iterators], iterators
  123.  
  124.       constexpr const_iterator
  125.       begin() const noexcept
  126.       { return this->_M_str; }
  127.  
  128.       constexpr const_iterator
  129.       end() const noexcept
  130.       { return this->_M_str + this->_M_len; }
  131.  
  132.       constexpr const_iterator
  133.       cbegin() const noexcept
  134.       { return this->_M_str; }
  135.  
  136.       constexpr const_iterator
  137.       cend() const noexcept
  138.       { return this->_M_str + this->_M_len; }
  139.  
  140.       const_reverse_iterator
  141.       rbegin() const noexcept
  142.       { return const_reverse_iterator(this->end()); }
  143.  
  144.       const_reverse_iterator
  145.       rend() const noexcept
  146.       { return const_reverse_iterator(this->begin()); }
  147.  
  148.       const_reverse_iterator
  149.       crbegin() const noexcept
  150.       { return const_reverse_iterator(this->end()); }
  151.  
  152.       const_reverse_iterator
  153.       crend() const noexcept
  154.       { return const_reverse_iterator(this->begin()); }
  155.  
  156.       // [string.view.capacity], capacity
  157.  
  158.       constexpr size_type
  159.       size() const noexcept
  160.       { return this->_M_len; }
  161.  
  162.       constexpr size_type
  163.       length() const noexcept
  164.       { return _M_len; }
  165.  
  166.       constexpr size_type
  167.       max_size() const noexcept
  168.       {
  169.         return (npos - sizeof(size_type) - sizeof(void*))
  170.                 / sizeof(value_type) / 4;
  171.       }
  172.  
  173.       constexpr bool
  174.       empty() const noexcept
  175.       { return this->_M_len == 0; }
  176.  
  177.       // [string.view.access], element access
  178.  
  179.       constexpr const _CharT&
  180.       operator[](size_type __pos) const
  181.       {
  182.         // TODO: Assert to restore in a way compatible with the constexpr.
  183.         // _GLIBCXX_DEBUG_ASSERT(__pos < this->_M_len);
  184.         return *(this->_M_str + __pos);
  185.       }
  186.  
  187.       constexpr const _CharT&
  188.       at(size_type __pos) const
  189.       {
  190.         return __pos < this->_M_len
  191.              ? *(this->_M_str + __pos)
  192.              : (__throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
  193.                                              "(which is %zu) >= this->size() "
  194.                                              "(which is %zu)"),
  195.                                          __pos, this->size()),
  196.                 *this->_M_str);
  197.       }
  198.  
  199.       constexpr const _CharT&
  200.       front() const
  201.       {
  202.         // TODO: Assert to restore in a way compatible with the constexpr.
  203.         // _GLIBCXX_DEBUG_ASSERT(this->_M_len > 0);
  204.         return *this->_M_str;
  205.       }
  206.  
  207.       constexpr const _CharT&
  208.       back() const
  209.       {
  210.         // TODO: Assert to restore in a way compatible with the constexpr.
  211.         // _GLIBCXX_DEBUG_ASSERT(this->_M_len > 0);
  212.         return *(this->_M_str + this->_M_len - 1);
  213.       }
  214.  
  215.       constexpr const _CharT*
  216.       data() const noexcept
  217.       { return this->_M_str; }
  218.  
  219.       // [string.view.modifiers], modifiers:
  220.  
  221.       void
  222.       remove_prefix(size_type __n)
  223.       {
  224.         _GLIBCXX_DEBUG_ASSERT(this->_M_len >= __n);
  225.         this->_M_str += __n;
  226.         this->_M_len -= __n;
  227.       }
  228.  
  229.       void
  230.       remove_suffix(size_type __n)
  231.       { this->_M_len -= __n; }
  232.  
  233.       void
  234.       swap(basic_string_view& __sv) noexcept
  235.       {
  236.         std::swap(this->_M_len, __sv._M_len);
  237.         std::swap(this->_M_str, __sv._M_str);
  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.       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.       int
  298.       compare(size_type __pos1, size_type __n1, basic_string_view __str) const
  299.       { return this->substr(__pos1, __n1).compare(__str); }
  300.  
  301.       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.       int
  307.       compare(const _CharT* __str) const noexcept
  308.       { return this->compare(basic_string_view{__str}); }
  309.  
  310.       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.       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.       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.       size_type
  327.       find(_CharT __c, size_type __pos=0) const noexcept;
  328.  
  329.       size_type
  330.       find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
  331.  
  332.       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.       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.       size_type
  341.       rfind(_CharT __c, size_type __pos = npos) const noexcept;
  342.  
  343.       size_type
  344.       rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
  345.  
  346.       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.       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.       size_type
  355.       find_first_of(_CharT __c, size_type __pos = 0) const noexcept
  356.       { return this->find(__c, __pos); }
  357.  
  358.       size_type
  359.       find_first_of(const _CharT* __str, size_type __pos, size_type __n) const;
  360.  
  361.       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.       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.       size_type
  371.       find_last_of(_CharT __c, size_type __pos=npos) const noexcept
  372.       { return this->rfind(__c, __pos); }
  373.  
  374.       size_type
  375.       find_last_of(const _CharT* __str, size_type __pos, size_type __n) const;
  376.  
  377.       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.       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.       size_type
  387.       find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
  388.  
  389.       size_type
  390.       find_first_not_of(const _CharT* __str,
  391.                         size_type __pos, size_type __n) const;
  392.  
  393.       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.       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.       size_type
  406.       find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
  407.  
  408.       size_type
  409.       find_last_not_of(const _CharT* __str,
  410.                        size_type __pos, size_type __n) const;
  411.  
  412.       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 const 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.  
  437.   // [string.view.comparison], non-member basic_string_view comparison functions
  438.  
  439.   namespace __detail
  440.   {
  441.     //  Identity transform to make ADL work with just one argument.
  442.     //  See n3766.html.
  443.     template<typename _Tp = void>
  444.       struct __identity
  445.       { typedef _Tp type; };
  446.  
  447.     template<>
  448.       struct __identity<void>;
  449.  
  450.     template<typename _Tp>
  451.       using __idt = typename __identity<_Tp>::type;
  452.   }
  453.  
  454.   template<typename _CharT, typename _Traits>
  455.     inline bool
  456.     operator==(basic_string_view<_CharT, _Traits> __x,
  457.                basic_string_view<_CharT, _Traits> __y) noexcept
  458.     { return __x.compare(__y) == 0; }
  459.  
  460.   template<typename _CharT, typename _Traits>
  461.     inline bool
  462.     operator==(basic_string_view<_CharT, _Traits> __x,
  463.                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
  464.     { return __x.compare(__y) == 0; }
  465.  
  466.   template<typename _CharT, typename _Traits>
  467.     inline bool
  468.     operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
  469.                basic_string_view<_CharT, _Traits> __y) noexcept
  470.     { return __x.compare(__y) == 0; }
  471.  
  472.   template<typename _CharT, typename _Traits>
  473.     inline bool
  474.     operator!=(basic_string_view<_CharT, _Traits> __x,
  475.                basic_string_view<_CharT, _Traits> __y) noexcept
  476.     { return !(__x == __y); }
  477.  
  478.   template<typename _CharT, typename _Traits>
  479.     inline bool
  480.     operator!=(basic_string_view<_CharT, _Traits> __x,
  481.                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
  482.     { return !(__x == __y); }
  483.  
  484.   template<typename _CharT, typename _Traits>
  485.     inline bool
  486.     operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
  487.                basic_string_view<_CharT, _Traits> __y) noexcept
  488.     { return !(__x == __y); }
  489.  
  490.   template<typename _CharT, typename _Traits>
  491.     inline bool
  492.     operator< (basic_string_view<_CharT, _Traits> __x,
  493.                basic_string_view<_CharT, _Traits> __y) noexcept
  494.     { return __x.compare(__y) < 0; }
  495.  
  496.   template<typename _CharT, typename _Traits>
  497.     inline bool
  498.     operator< (basic_string_view<_CharT, _Traits> __x,
  499.                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
  500.     { return __x.compare(__y) < 0; }
  501.  
  502.   template<typename _CharT, typename _Traits>
  503.     inline bool
  504.     operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
  505.                basic_string_view<_CharT, _Traits> __y) noexcept
  506.     { return __x.compare(__y) < 0; }
  507.  
  508.   template<typename _CharT, typename _Traits>
  509.     inline bool
  510.     operator> (basic_string_view<_CharT, _Traits> __x,
  511.                basic_string_view<_CharT, _Traits> __y) noexcept
  512.     { return __x.compare(__y) > 0; }
  513.  
  514.   template<typename _CharT, typename _Traits>
  515.     inline bool
  516.     operator> (basic_string_view<_CharT, _Traits> __x,
  517.                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
  518.     { return __x.compare(__y) > 0; }
  519.  
  520.   template<typename _CharT, typename _Traits>
  521.     inline bool
  522.     operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
  523.                basic_string_view<_CharT, _Traits> __y) noexcept
  524.     { return __x.compare(__y) > 0; }
  525.  
  526.   template<typename _CharT, typename _Traits>
  527.     inline bool
  528.     operator<=(basic_string_view<_CharT, _Traits> __x,
  529.                basic_string_view<_CharT, _Traits> __y) noexcept
  530.     { return __x.compare(__y) <= 0; }
  531.  
  532.   template<typename _CharT, typename _Traits>
  533.     inline bool
  534.     operator<=(basic_string_view<_CharT, _Traits> __x,
  535.                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
  536.     { return __x.compare(__y) <= 0; }
  537.  
  538.   template<typename _CharT, typename _Traits>
  539.     inline bool
  540.     operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
  541.                basic_string_view<_CharT, _Traits> __y) noexcept
  542.     { return __x.compare(__y) <= 0; }
  543.  
  544.   template<typename _CharT, typename _Traits>
  545.     inline bool
  546.     operator>=(basic_string_view<_CharT, _Traits> __x,
  547.                basic_string_view<_CharT, _Traits> __y) noexcept
  548.     { return __x.compare(__y) >= 0; }
  549.  
  550.   template<typename _CharT, typename _Traits>
  551.     inline bool
  552.     operator>=(basic_string_view<_CharT, _Traits> __x,
  553.                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
  554.     { return __x.compare(__y) >= 0; }
  555.  
  556.   template<typename _CharT, typename _Traits>
  557.     inline bool
  558.     operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
  559.                basic_string_view<_CharT, _Traits> __y) noexcept
  560.     { return __x.compare(__y) >= 0; }
  561.  
  562.   // [string.view.io], Inserters and extractors
  563.   template<typename _CharT, typename _Traits>
  564.     inline basic_ostream<_CharT, _Traits>&
  565.     operator<<(basic_ostream<_CharT, _Traits>& __os,
  566.                basic_string_view<_CharT,_Traits> __str)
  567.     { return __ostream_insert(__os, __str.data(), __str.size()); }
  568.  
  569.  
  570.   // basic_string_view typedef names
  571.  
  572.   using string_view = basic_string_view<char>;
  573. #ifdef _GLIBCXX_USE_WCHAR_T
  574.   using wstring_view = basic_string_view<wchar_t>;
  575. #endif
  576. #ifdef _GLIBCXX_USE_C99_STDINT_TR1
  577.   using u16string_view = basic_string_view<char16_t>;
  578.   using u32string_view = basic_string_view<char32_t>;
  579. #endif
  580.  
  581. _GLIBCXX_END_NAMESPACE_VERSION
  582. } // namespace fundamentals_v1
  583. } // namespace experimental
  584.  
  585.  
  586.   // [string.view.hash], hash support:
  587.  
  588. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  589.   template<typename _Tp>
  590.     struct hash;
  591.  
  592.   template<>
  593.     struct hash<experimental::string_view>
  594.     : public __hash_base<size_t, experimental::string_view>
  595.     {
  596.       size_t
  597.       operator()(const experimental::string_view& __str) const noexcept
  598.       { return std::_Hash_impl::hash(__str.data(), __str.length()); }
  599.     };
  600.  
  601.   template<>
  602.     struct __is_fast_hash<hash<experimental::string_view>> : std::false_type
  603.     { };
  604.  
  605. #ifdef _GLIBCXX_USE_WCHAR_T
  606.   template<>
  607.     struct hash<experimental::wstring_view>
  608.     : public __hash_base<size_t, wstring>
  609.     {
  610.       size_t
  611.       operator()(const experimental::wstring_view& __s) const noexcept
  612.       { return std::_Hash_impl::hash(__s.data(),
  613.                                      __s.length() * sizeof(wchar_t)); }
  614.     };
  615.  
  616.   template<>
  617.     struct __is_fast_hash<hash<experimental::wstring_view>> : std::false_type
  618.     { };
  619. #endif
  620.  
  621. #ifdef _GLIBCXX_USE_C99_STDINT_TR1
  622.   template<>
  623.     struct hash<experimental::u16string_view>
  624.     : public __hash_base<size_t, experimental::u16string_view>
  625.     {
  626.       size_t
  627.       operator()(const experimental::u16string_view& __s) const noexcept
  628.       { return std::_Hash_impl::hash(__s.data(),
  629.                                      __s.length() * sizeof(char16_t)); }
  630.     };
  631.  
  632.   template<>
  633.     struct __is_fast_hash<hash<experimental::u16string_view>> : std::false_type
  634.     { };
  635.  
  636.   template<>
  637.     struct hash<experimental::u32string_view>
  638.     : public __hash_base<size_t, experimental::u32string_view>
  639.     {
  640.       size_t
  641.       operator()(const experimental::u32string_view& __s) const noexcept
  642.       { return std::_Hash_impl::hash(__s.data(),
  643.                                      __s.length() * sizeof(char32_t)); }
  644.     };
  645.  
  646.   template<>
  647.     struct __is_fast_hash<hash<experimental::u32string_view>> : std::false_type
  648.     { };
  649. #endif
  650. _GLIBCXX_END_NAMESPACE_VERSION
  651.  
  652. namespace experimental
  653. {
  654. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  655.  
  656.   // I added these EMSR.
  657.   inline namespace literals
  658.   {
  659.   inline namespace string_view_literals
  660.   {
  661.  
  662.     inline constexpr basic_string_view<char>
  663.     operator""sv(const char* __str, size_t __len)
  664.     { return basic_string_view<char>{__str, __len}; }
  665.  
  666. #ifdef _GLIBCXX_USE_WCHAR_T
  667.     inline constexpr basic_string_view<wchar_t>
  668.     operator""sv(const wchar_t* __str, size_t __len)
  669.     { return basic_string_view<wchar_t>{__str, __len}; }
  670. #endif
  671.  
  672. #ifdef _GLIBCXX_USE_C99_STDINT_TR1
  673.     inline constexpr basic_string_view<char16_t>
  674.     operator""sv(const char16_t* __str, size_t __len)
  675.     { return basic_string_view<char16_t>{__str, __len}; }
  676.  
  677.     inline constexpr basic_string_view<char32_t>
  678.     operator""sv(const char32_t* __str, size_t __len)
  679.     { return basic_string_view<char32_t>{__str, __len}; }
  680. #endif
  681.  
  682.   }
  683.   }
  684.  
  685. _GLIBCXX_END_NAMESPACE_VERSION
  686. } // namespace experimental
  687. } // namespace std
  688.  
  689. #include <experimental/string_view.tcc>
  690.  
  691. #endif // __cplusplus <= 201103L
  692.  
  693. #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW
  694.