<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Jun 11, 2014 at 9:44 AM, Marshall Clow <span dir="ltr"><<a href="mailto:mclow.lists@gmail.com" target="_blank">mclow.lists@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: marshall<br>
Date: Wed Jun 11 11:44:55 2014<br>
New Revision: 210659<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=210659&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=210659&view=rev</a><br>
Log:<br>
Implement string_view from the library fundamentals TS (n4023). Also works in C++11 and 03, with reduced functionality (mostly in the area of constexpr)<br></blockquote><div> [...]</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Added: libcxx/trunk/include/experimental/string_view<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/string_view?rev=210659&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/string_view?rev=210659&view=auto</a><br>

==============================================================================<br>
--- libcxx/trunk/include/experimental/string_view (added)<br>
+++ libcxx/trunk/include/experimental/string_view Wed Jun 11 11:44:55 2014<br>
@@ -0,0 +1,813 @@<br>
+// -*- C++ -*-<br>
+//===------------------------ string_view ---------------------------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef _LIBCPP_LFTS_STRING_VIEW<br>
+#define _LIBCPP_LFTS_STRING_VIEW<br>
+<br>
+/*<br>
+string_view synopsis<br>
+<br>
+namespace std {<br>
+ namespace experimental {<br>
+  inline namespace library_fundamentals_v1 {<br>
+<br>
+    // 7.2, Class template basic_string_view<br>
+    template<class charT, class traits = char_traits<charT>><br>
+        class basic_string_view;<br>
+<br>
+    // 7.9, basic_string_view non-member comparison functions<br>
+    template<class charT, class traits><br>
+    constexpr bool operator==(basic_string_view<charT, traits> x,<br>
+                              basic_string_view<charT, traits> y) noexcept;<br>
+    template<class charT, class traits><br>
+    constexpr bool operator!=(basic_string_view<charT, traits> x,<br>
+                              basic_string_view<charT, traits> y) noexcept;<br>
+    template<class charT, class traits><br>
+    constexpr bool operator< (basic_string_view<charT, traits> x,<br>
+                                 basic_string_view<charT, traits> y) noexcept;<br>
+    template<class charT, class traits><br>
+    constexpr bool operator> (basic_string_view<charT, traits> x,<br>
+                              basic_string_view<charT, traits> y) noexcept;<br>
+    template<class charT, class traits><br>
+    constexpr bool operator<=(basic_string_view<charT, traits> x,<br>
+                                 basic_string_view<charT, traits> y) noexcept;<br>
+    template<class charT, class traits><br>
+    constexpr bool operator>=(basic_string_view<charT, traits> x,<br>
+                              basic_string_view<charT, traits> y) noexcept;<br>
+    // see below, sufficient additional overloads of comparison functions<br>
+<br>
+    // 7.10, Inserters and extractors<br>
+    template<class charT, class traits><br>
+      basic_ostream<charT, traits>&<br>
+        operator<<(basic_ostream<charT, traits>& os,<br>
+                   basic_string_view<charT, traits> str);<br>
+<br>
+    // basic_string_view typedef names<br>
+    typedef basic_string_view<char> string_view;<br>
+    typedef basic_string_view<char16_t> u16string_view;<br>
+    typedef basic_string_view<char32_t> u32string_view;<br>
+    typedef basic_string_view<wchar_t> wstring_view;<br>
+<br>
+  }  // namespace fundamentals_v1<br>
+ }  // namespace experimental<br>
+<br>
+  // 7.11, Hash support<br>
+  template <class T> struct hash;<br>
+  template <> struct hash<experimental::string_view>;<br>
+  template <> struct hash<experimental::u16string_view>;<br>
+  template <> struct hash<experimental::u32string_view>;<br>
+  template <> struct hash<experimental::wstring_view>;<br>
+<br>
+}  // namespace std<br>
+<br>
+<br>
+template<class charT, class traits = char_traits<charT>><br>
+class basic_string_view {<br></blockquote><div><br></div><div>[Nit: missing std::experimental::library_fundamentals_v1 here. Also, I think we usually put this part of the comment inside the first declaration rather than splitting it out like the standard does.]</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+  public:<br>
+  // types<br>
+  typedef traits traits_type;<br>
+  typedef charT value_type;<br>
+  typedef charT* pointer;<br>
+  typedef const charT* const_pointer;<br>
+  typedef charT& reference;<br>
+  typedef const charT& const_reference;<br>
+  typedef implementation-defined const_iterator; // See 7.4<br></blockquote><div><br></div><div>Should this comment be here?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+  typedef const_iterator iterator;22) Because basic_string_view refers to a constant sequence, iterator and const_iterator are the same type.<br></blockquote><div><br></div><div>Should this footnote be here?</div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+  typedef reverse_iterator<const_iterator> const_reverse_iterator;<br>
+  typedef const_reverse_iterator reverse_iterator;<br>
+  typedef size_t size_type;<br>
+  typedef ptrdiff_t difference_type;<br>
+  static constexpr size_type npos = size_type(-1);<br>
+<br>
+  // 7.3, basic_string_view constructors and assignment operators<br>
+  constexpr basic_string_view() noexcept;<br>
+  constexpr basic_string_view(const basic_string_view&) noexcept = default;<br>
+  basic_string_view& operator=(const basic_string_view&) noexcept = default;<br>
+  template<class Allocator><br>
+  basic_string_view(const basic_string<charT, traits, Allocator>& str) noexcept;<br>
+  constexpr basic_string_view(const charT* str);<br>
+  constexpr basic_string_view(const charT* str, size_type len);<br>
+<br>
+  // 7.4, basic_string_view iterator support<br>
+  constexpr const_iterator begin() const noexcept;<br>
+  constexpr const_iterator end() const noexcept;<br>
+  constexpr const_iterator cbegin() const noexcept;<br>
+  constexpr const_iterator cend() const noexcept;<br>
+  const_reverse_iterator rbegin() const noexcept;<br>
+  const_reverse_iterator rend() const noexcept;<br>
+  const_reverse_iterator crbegin() const noexcept;<br>
+  const_reverse_iterator crend() const noexcept;<br>
+<br>
+  // 7.5, basic_string_view capacity<br>
+  constexpr size_type size() const noexcept;<br>
+  constexpr size_type length() const noexcept;<br>
+  constexpr size_type max_size() const noexcept;<br>
+  constexpr bool empty() const noexcept;<br>
+<br>
+  // 7.6, basic_string_view element access<br>
+  constexpr const_reference operator[](size_type pos) const;<br>
+  constexpr const_reference at(size_type pos) const;<br>
+  constexpr const_reference front() const;<br>
+  constexpr const_reference back() const;<br>
+  constexpr const_pointer data() const noexcept;<br>
+<br>
+  // 7.7, basic_string_view modifiers<br>
+  constexpr void clear() noexcept;<br>
+  constexpr void remove_prefix(size_type n);<br>
+  constexpr void remove_suffix(size_type n);<br>
+  constexpr void swap(basic_string_view& s) noexcept;<br>
+<br>
+  // 7.8, basic_string_view string operations<br>
+  template<class Allocator><br>
+  explicit operator basic_string<charT, traits, Allocator>() const;<br>
+  template<class Allocator = allocator<charT>><br>
+  basic_string<charT, traits, Allocator> to_string(<br>
+    const Allocator& a = Allocator()) const;<br>
+<br>
+  size_type copy(charT* s, size_type n, size_type pos = 0) const;<br>
+<br>
+  constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;<br>
+  constexpr int compare(basic_string_view s) const noexcept;<br>
+  constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;<br>
+  constexpr int compare(size_type pos1, size_type n1,<br>
+                        basic_string_view s, size_type pos2, size_type n2) const;<br>
+  constexpr int compare(const charT* s) const;<br>
+  constexpr int compare(size_type pos1, size_type n1, const charT* s) const;<br>
+  constexpr int compare(size_type pos1, size_type n1,<br>
+                        const charT* s, size_type n2) const;<br>
+  constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;<br>
+  constexpr size_type find(charT c, size_type pos = 0) const noexcept;<br>
+  constexpr size_type find(const charT* s, size_type pos, size_type n) const;<br>
+  constexpr size_type find(const charT* s, size_type pos = 0) const;<br>
+  constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;<br>
+  constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;<br>
+  constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;<br>
+  constexpr size_type rfind(const charT* s, size_type pos = npos) const;<br>
+  constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;<br>
+  constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;<br>
+  constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;<br>
+  constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;<br>
+  constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;<br>
+  constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;<br>
+  constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;<br>
+  constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;<br>
+  constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;<br>
+  constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;<br>
+  constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;<br>
+  constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;<br>
+  constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;<br>
+  constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;<br>
+  constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;<br>
+  constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;<br>
+<br>
+ private:<br>
+  const_pointer data_;  // exposition only<br>
+  size_type     size_;  // exposition only<br>
+};<br>
+<br>
+<br>
+*/<br>
+<br>
+#include <__config><br>
+<br>
+#include <string><br>
+#include <algorithm><br>
+#include <iterator><br>
+#include <ostream><br>
+#include <iomanip><br>
+<br>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)<br>
+#pragma GCC system_header<br>
+#endif<br>
+<br>
+namespace std {<br>
+ namespace experimental {<br>
+  inline namespace library_fundamentals_v1 {<br>
+<br>
+    template<class _CharT, class _Traits = _VSTD::char_traits<_CharT> ><br>
+    class _LIBCPP_TYPE_VIS_ONLY basic_string_view {<br>
+    public:<br>
+        // types<br>
+        typedef _Traits                                    traits_type;<br>
+        typedef _CharT                                     value_type;<br>
+        typedef const _CharT*                              pointer;<br>
+        typedef const _CharT*                              const_pointer;<br>
+        typedef const _CharT&                              reference;<br>
+        typedef const _CharT&                              const_reference;<br>
+        typedef const_pointer                              const_iterator; // See [string.view.iterators]<br>
+        typedef const_iterator                             iterator;<br>
+        typedef _VSTD::reverse_iterator<const_iterator>    const_reverse_iterator;<br>
+        typedef const_reverse_iterator                     reverse_iterator;<br>
+        typedef size_t                                     size_type;<br>
+        typedef ptrdiff_t                                  difference_type;<br>
+        static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);<br>
+<br>
+        // [string.view.cons], construct/copy<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        basic_string_view(const basic_string_view&) _NOEXCEPT = default;<br>
+<br>
+        _LIBCPP_INLINE_VISIBILITY<br>
+        basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;<br>
+<br>
+        template<class _Allocator><br>
+        _LIBCPP_INLINE_VISIBILITY<br>
+        basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& __str) _NOEXCEPT<br>
+            : __data (__str.data()), __size(__str.size()) {}<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        basic_string_view(const _CharT* __s, size_type __len)<br>
+            : __data(__s), __size(__len)<br>
+        {<br>
+            _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): recieved nullptr");<br></blockquote><div><br></div><div>You could make this constexpr even in C++11 by moving this check into one of the member initializers. I think this is an important function to make constexpr.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        basic_string_view(const _CharT* __s)<br>
+            : __data(__s), __size(_Traits::length(__s)) {}<br>
+<br>
+        // [string.view.iterators], iterators<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        const_iterator begin()  const _NOEXCEPT { return cbegin(); }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        const_iterator end()    const _NOEXCEPT { return cend(); }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        const_iterator cbegin() const _NOEXCEPT { return __data; }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        const_iterator cend()   const _NOEXCEPT { return __data + __size; }<br>
+<br>
+        _LIBCPP_INLINE_VISIBILITY<br>
+        const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }<br>
+<br>
+        _LIBCPP_INLINE_VISIBILITY<br>
+        const_reverse_iterator rend()     const _NOEXCEPT { return const_reverse_iterator(cbegin()); }<br>
+<br>
+        _LIBCPP_INLINE_VISIBILITY<br>
+        const_reverse_iterator crbegin()  const _NOEXCEPT { return const_reverse_iterator(cend()); }<br>
+<br>
+        _LIBCPP_INLINE_VISIBILITY<br>
+        const_reverse_iterator crend()    const _NOEXCEPT { return const_reverse_iterator(cbegin()); }<br>
+<br>
+        // [string.view.capacity], capacity<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        size_type size()     const _NOEXCEPT { return __size; }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        size_type length()   const _NOEXCEPT { return __size; }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        size_type max_size() const _NOEXCEPT { return _VSTD::numeric_limits<size_type>::max(); }<br>
+<br>
+        _LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY<br>
+        empty()         const _NOEXCEPT { return __size == 0; }<br>
+<br>
+        // [string.view.access], element access<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        const_reference operator[](size_type __pos) const { return __data[__pos]; }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        const_reference at(size_type __pos) const<br>
+        {<br>
+            if (__pos >= size())<br>
+                throw out_of_range("string_view::at");<br>
+            return __data[__pos];<br></blockquote><div><br></div><div>You can make this one constexpr in c++11 with</div><div><br></div><div>  return __data[__pos >= size() ? throw out_of_range(...) : __pos];</div><div>
<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        const_reference front() const<br>
+        {<br>
+            _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty");<br>
+            return __data[0];<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        const_reference back() const<br>
+        {<br>
+            _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty");<br>
+            return __data[__size-1];<br>
+        }<br></blockquote><div><br></div><div>You can do similar things here.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        const_pointer data() const _NOEXCEPT { return __data; }<br>
+<br>
+        // [string.view.modifiers], modifiers:<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        void clear() _NOEXCEPT<br>
+        {<br>
+            __data = nullptr;<br>
+            __size = 0;<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        void remove_prefix(size_type __n) _NOEXCEPT<br>
+        {<br>
+            if (__n > __size)<br>
+                __n = __size;<br>
+            __data += __n;<br>
+            __size -= __n;<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        void remove_suffix(size_type __n) _NOEXCEPT<br>
+        {<br>
+            if (__n > __size)<br>
+                __n = __size;<br>
+            __size -= __n;<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        void swap(basic_string_view& __other) _NOEXCEPT<br>
+        {<br>
+               const value_type *__p = __data;<br>
+               __data = __other.__data;<br>
+               __other.__data = __p;<br>
+<br>
+               size_type __sz = __size;<br>
+               __size = __other.__size;<br>
+               __other.__size = __sz;<br>
+//             _VSTD::swap( __data, __other.__data );<br>
+//             _VSTD::swap( __size, __other.__size );<br>
+        }<br></blockquote><div><br></div><div>Would it make sense to provide a _LIBCPP_CONSTEXPR_AFTER_CXX11 _VSTD::__swap for use in places like this?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+        // [string.view.ops], string operations:<br>
+        template<class _Allocator><br>
+        _LIBCPP_INLINE_VISIBILITY<br>
+        _LIBCPP_EXPLICIT operator basic_string<_CharT, _Traits, _Allocator>() const<br>
+        { return basic_string<_CharT, _Traits, _Allocator>( begin(), end()); }<br>
+<br>
+        template<class _Allocator = allocator<_CharT> ><br>
+        _LIBCPP_INLINE_VISIBILITY<br>
+        basic_string<_CharT, _Traits, _Allocator> to_string( const _Allocator& __a = _Allocator())<br>
+        { return basic_string<_CharT, _Traits, _Allocator> ( begin(), end(), __a ); }<br>
+<br>
+        size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const<br>
+        {<br>
+            if ( __pos > size())<br>
+                throw out_of_range("string_view::copy");<br>
+            size_type __rlen = _VSTD::min( __n, size() - __pos );<br>
+            _VSTD::copy_n(begin() + __pos, __rlen, __s );<br>
+            return __rlen;<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 basic_string_view substr(size_type __pos = 0, size_type __n = npos) const<br>
+        {<br>
+            if (__pos > size())<br>
+                throw out_of_range("string_view::substr");<br>
+            size_type __rlen = _VSTD::min( __n, size() - __pos );<br>
+            return basic_string_view(data() + __pos, __rlen);<br>
+        }<br></blockquote><div><br></div><div>It also seems like it would be worth making this work in C++11.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+        _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT<br>
+        {<br>
+            size_type __rlen = _VSTD::min( size(), __sv.size());<br>
+            int __retval = _Traits::compare(data(), __sv.data(), __rlen);<br>
+            if ( __retval == 0 ) // first __rlen chars matched<br>
+                __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );<br>
+            return __retval;<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const<br>
+        {<br>
+            return substr(__pos1, __n1).compare(__sv);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        int compare(                       size_type __pos1, size_type __n1,<br>
+                    basic_string_view _sv, size_type __pos2, size_type __n2) const<br>
+        {<br>
+            return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2));<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        int compare(const _CharT* __s) const<br>
+        {<br>
+            return compare(basic_string_view(__s));<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        int compare(size_type __pos1, size_type __n1, const _CharT* __s) const<br>
+        {<br>
+            return substr(__pos1, __n1).compare(basic_string_view(__s));<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY<br>
+        int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const<br>
+        {<br>
+            return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));<br>
+        }<br>
</blockquote><div><br></div><div>The preceding 5 functions should be CONSTEXPR_AFTER_CXX11, since they can never be used in constant expressions in C++11 (they unconditionally call the first 'compare', which is not constexpr in C++11). This code is ill-formed, no diagnostic required.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        // find<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT<br>
+        {<br>
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr");<br>
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s.data(), __pos, __s.size());<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT<br>
+        {<br>
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __c, __pos);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find(const _CharT* __s, size_type __pos, size_type __n) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): recieved nullptr");<br>
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, __n);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find(const _CharT* __s, size_type __pos = 0) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): recieved nullptr");<br>
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, traits_type::length(__s));<br>
+        }<br>
+<br>
+        // rfind<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT<br>
+        {<br>
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr");<br>
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s.data(), __pos, __s.size());<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT<br>
+        {<br>
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __c, __pos);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): recieved nullptr");<br>
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, __n);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type rfind(const _CharT* __s, size_type __pos=npos) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): recieved nullptr");<br>
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, traits_type::length(__s));<br>
+        }<br>
+<br>
+        // find_first_of<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT<br>
+        {<br>
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s.data(), __pos, __s.size());<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT<br>
+        { return find(__c, __pos); }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, __n);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_first_of(const _CharT* __s, size_type __pos=0) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, traits_type::length(__s));<br>
+        }<br>
+<br>
+        // find_last_of<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT<br>
+        {<br>
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s.data(), __pos, __s.size());<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT<br>
+        { return rfind(__c, __pos); }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, __n);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_last_of(const _CharT* __s, size_type __pos=npos) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, traits_type::length(__s));<br>
+        }<br>
+<br>
+        // find_first_not_of<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT<br>
+        {<br>
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s.data(), __pos, __s.size());<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT<br>
+        {<br>
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __c, __pos);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, __n);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, traits_type::length(__s));<br>
+        }<br>
+<br>
+        // find_last_not_of<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT<br>
+        {<br>
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s.data(), __pos, __s.size());<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT<br>
+        {<br>
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __c, __pos);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, __n);<br>
+        }<br>
+<br>
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+        size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const<br>
+        {<br>
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): recieved nullptr");<br>
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos><br>
+                (data(), size(), __s, __pos, traits_type::length(__s));<br>
+        }<br>
+<br>
+    private:<br>
+        const   value_type* __data;<br>
+        size_type           __size;<br>
+    };<br>
+<br>
+<br>
+    // [string.view.comparison]<br>
+    // operator ==<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator==(basic_string_view<_CharT, _Traits> __lhs,<br>
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        if ( __lhs.size() != __rhs.size()) return false;<br>
+        return __lhs.compare(__rhs) == 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator==(basic_string_view<_CharT, _Traits> __lhs,<br>
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT<br></blockquote><div><br></div><div>Seems weird that we use common_type, not identity, here. Is there some subtly to this, beyond merely creating a non-deduced context?</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    {<br>
+        if ( __lhs.size() != __rhs.size()) return false;<br>
+        return __lhs.compare(__rhs) == 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator==(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,<br>
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        if ( __lhs.size() != __rhs.size()) return false;<br>
+        return __lhs.compare(__rhs) == 0;<br>
+    }<br>
+<br>
+<br>
+    // operator !=<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        if ( __lhs.size() != __rhs.size())<br>
+            return true;<br>
+        return __lhs.compare(__rhs) != 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator!=(basic_string_view<_CharT, _Traits> __lhs,<br>
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT<br>
+    {<br>
+        if ( __lhs.size() != __rhs.size())<br>
+            return true;<br>
+        return __lhs.compare(__rhs) != 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator!=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,<br>
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        if ( __lhs.size() != __rhs.size())<br>
+            return true;<br>
+        return __lhs.compare(__rhs) != 0;<br>
+    }<br>
+<br>
+<br>
+    // operator <<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) < 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator<(basic_string_view<_CharT, _Traits> __lhs,<br>
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) < 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator<(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,<br>
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) < 0;<br>
+    }<br>
+<br>
+<br>
+    // operator ><br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) > 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator>(basic_string_view<_CharT, _Traits> __lhs,<br>
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) > 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator>(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,<br>
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) > 0;<br>
+    }<br>
+<br>
+<br>
+    // operator <=<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) <= 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator<=(basic_string_view<_CharT, _Traits> __lhs,<br>
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) <= 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator<=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,<br>
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) <= 0;<br>
+    }<br>
+<br>
+<br>
+    // operator >=<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) >= 0;<br>
+    }<br>
+<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator>=(basic_string_view<_CharT, _Traits> __lhs,<br>
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) >= 0;<br>
+    }<br>
+<br>
+    template<class _CharT, class _Traits><br>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY<br>
+    bool operator>=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,<br>
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT<br>
+    {<br>
+        return __lhs.compare(__rhs) >= 0;<br>
+    }<br>
+<br>
+<br>
+    // [<a href="http://string.view.io" target="_blank">string.view.io</a>]<br>
+    template<class _CharT, class _Traits><br>
+    basic_ostream<_CharT, _Traits>&<br>
+    operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv)<br>
+    {<br>
+        return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size());<br>
+    }<br>
+<br>
+  typedef basic_string_view<char>     string_view;<br>
+  typedef basic_string_view<char16_t> u16string_view;<br>
+  typedef basic_string_view<char32_t> u32string_view;<br>
+  typedef basic_string_view<wchar_t>  wstring_view;<br>
+<br>
+}}}  // close std::experimental::library_fundamentals_v1<br>
+<br>
+_LIBCPP_BEGIN_NAMESPACE_STD<br>
+<br>
+// [string.view.hash]<br>
+// Shamelessly stolen from <string><br>
+template<class _CharT, class _Traits><br>
+struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::basic_string_view<_CharT, _Traits> ><br>
+    : public unary_function<std::experimental::basic_string_view<_CharT, _Traits>, size_t><br>
+{<br>
+    size_t operator()(const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT;<br>
+};<br>
+<br>
+template<class _CharT, class _Traits><br>
+size_t<br>
+hash<std::experimental::basic_string_view<_CharT, _Traits> >::operator()(<br>
+        const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT<br>
+{<br>
+    return __do_string_hash(__val.data(), __val.data() + __val.size());<br>
+}<br>
+<br>
+#if _LIBCPP_STD_VER > 11<br>
+template <class _CharT, class _Traits><br>
+__quoted_output_proxy<_CharT, const _CharT *, _Traits><br>
+quoted ( std::experimental::basic_string_view <_CharT, _Traits> __sv,<br>
+             _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))<br>
+{<br>
+    return __quoted_output_proxy<_CharT, const _CharT *, _Traits><br>
+         ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape );<br>
+}<br>
+#endif<br>
+<br>
+_LIBCPP_END_NAMESPACE_STD<br>
+<br>
+#endif // _LIBCPP_LFTS_STRING_VIEW<br></blockquote></div></div></div>