[libcxx] r295393 - [libc++] Fix PR 31938 - std::basic_string constructors use non-deductible parameter types.

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 16 17:17:10 PST 2017


Author: ericwf
Date: Thu Feb 16 19:17:10 2017
New Revision: 295393

URL: http://llvm.org/viewvc/llvm-project?rev=295393&view=rev
Log:
[libc++] Fix PR 31938 - std::basic_string constructors use non-deductible parameter types.

Summary:
This patch fixes http://llvm.org/PR31938. The description below is copy/pasted from the bug:

The standard says:

template<class charT, class traits = char_traits<charT>,
         class Allocator = allocator<charT>>
class basic_string {
  using value_type = typename traits::char_type;
  // ...
  basic_string(const charT* s, const Allocator& a = Allocator());
};

libc++ actually chooses to declare the constructor as

  basic_string(const value_type* s, const Allocator& a = Allocator());

The implicit deduction guides from class template argument deduction make what was previously an implementation detail visible:

std::basic_string s = "foo"; // error, can't deduce charT.

The constructor in question is in the libc++ DSO, but fortunately it looks like fixing this will not result in an ABI break.


@rsmith How does this look? I did more than just the constructors mentioned in the PR, but IDK how far to take it.


Reviewers: mclow.lists, rsmith

Reviewed By: rsmith

Subscribers: cfe-commits, rsmith

Differential Revision: https://reviews.llvm.org/D29863

Added:
    libcxx/trunk/test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp
Modified:
    libcxx/trunk/include/string
    libcxx/trunk/test/support/constexpr_char_traits.hpp
    libcxx/trunk/utils/libcxx/test/config.py

Modified: libcxx/trunk/include/string
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/string?rev=295393&r1=295392&r2=295393&view=diff
==============================================================================
--- libcxx/trunk/include/string (original)
+++ libcxx/trunk/include/string Thu Feb 16 19:17:10 2017
@@ -775,30 +775,30 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     basic_string(basic_string&& __str, const allocator_type& __a);
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s);
+    _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(const value_type* __s, const allocator_type& __a);
+    basic_string(const _CharT* __s, const _Allocator& __a);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(const value_type* __s, size_type __n);
+    basic_string(const _CharT* __s, size_type __n);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(const value_type* __s, size_type __n, const allocator_type& __a);
+    basic_string(const _CharT* __s, size_type __n, const _Allocator& __a);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(size_type __n, value_type __c);
+    basic_string(size_type __n, _CharT __c);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(size_type __n, value_type __c, const allocator_type& __a);
+    basic_string(size_type __n, _CharT __c, const _Allocator& __a);
     basic_string(const basic_string& __str, size_type __pos, size_type __n,
-                 const allocator_type& __a = allocator_type());
+                 const _Allocator& __a = _Allocator());
     _LIBCPP_INLINE_VISIBILITY
     basic_string(const basic_string& __str, size_type __pos,
-                 const allocator_type& __a = allocator_type());
+                 const _Allocator& __a = _Allocator());
     template<class _Tp>
-        basic_string(const _Tp& __t, size_type __pos, size_type __n, 
+        basic_string(const _Tp& __t, size_type __pos, size_type __n,
                      const allocator_type& __a = allocator_type(),
                      typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0);
     _LIBCPP_INLINE_VISIBILITY explicit
     basic_string(__self_view __sv);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(__self_view __sv, const allocator_type& __a);
+    basic_string(__self_view __sv, const _Allocator& __a);
     template<class _InputIterator>
         _LIBCPP_INLINE_VISIBILITY
         basic_string(_InputIterator __first, _InputIterator __last);
@@ -807,9 +807,9 @@ public:
         basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(initializer_list<value_type> __il);
+    basic_string(initializer_list<_CharT> __il);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(initializer_list<value_type> __il, const allocator_type& __a);
+    basic_string(initializer_list<_CharT> __il, const _Allocator& __a);
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
     inline ~basic_string();
@@ -1557,7 +1557,7 @@ basic_string<_CharT, _Traits, _Allocator
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s)
 {
     _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
     __init(__s, traits_type::length(__s));
@@ -1568,7 +1568,7 @@ basic_string<_CharT, _Traits, _Allocator
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
     : __r_(__a)
 {
     _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
@@ -1580,7 +1580,7 @@ basic_string<_CharT, _Traits, _Allocator
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n)
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
     __init(__s, __n);
@@ -1591,7 +1591,7 @@ basic_string<_CharT, _Traits, _Allocator
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
     : __r_(__a)
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
@@ -1615,7 +1615,8 @@ basic_string<_CharT, _Traits, _Allocator
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, const allocator_type& __a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(
+    const basic_string& __str, const allocator_type& __a)
     : __r_(__a)
 {
     if (!__str.__is_long())
@@ -1694,7 +1695,7 @@ basic_string<_CharT, _Traits, _Allocator
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c)
 {
     __init(__n, __c);
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1704,7 +1705,7 @@ basic_string<_CharT, _Traits, _Allocator
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
     : __r_(__a)
 {
     __init(__n, __c);
@@ -1714,8 +1715,9 @@ basic_string<_CharT, _Traits, _Allocator
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n,
-                                                        const allocator_type& __a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
+                                                        size_type __pos, size_type __n,
+                                                        const _Allocator& __a)
     : __r_(__a)
 {
     size_type __str_sz = __str.size();
@@ -1730,7 +1732,7 @@ basic_string<_CharT, _Traits, _Allocator
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
-                                                        const allocator_type& __a)
+                                                        const _Allocator& __a)
     : __r_(__a)
 {
     size_type __str_sz = __str.size();
@@ -1753,7 +1755,7 @@ basic_string<_CharT, _Traits, _Allocator
     __init(__sv.data(), __sv.size());
 #if _LIBCPP_DEBUG_LEVEL >= 2
     __get_db()->__insert_c(this);
-#endif	
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1768,7 +1770,7 @@ basic_string<_CharT, _Traits, _Allocator
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const allocator_type& __a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const _Allocator& __a)
     : __r_(__a)
 {
     __init(__sv.data(), __sv.size());
@@ -1863,7 +1865,8 @@ basic_string<_CharT, _Traits, _Allocator
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(
+    initializer_list<_CharT> __il)
 {
     __init(__il.begin(), __il.end());
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1873,7 +1876,9 @@ basic_string<_CharT, _Traits, _Allocator
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(
+    initializer_list<_CharT> __il, const _Allocator& __a)
+
     : __r_(__a)
 {
     __init(__il.begin(), __il.end());

Added: libcxx/trunk/test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp?rev=295393&view=auto
==============================================================================
--- libcxx/trunk/test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp (added)
+++ libcxx/trunk/test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp Thu Feb 16 19:17:10 2017
@@ -0,0 +1,300 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// <string>
+
+// Test that the constructors offered by std::basic_string are formulated
+// so they're compatible with implicit deduction guides.
+
+#include <string>
+#include <string_view>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "test_iterators.h"
+#include "constexpr_char_traits.hpp"
+
+template <class T, class Alloc = std::allocator<T>>
+using BStr = std::basic_string<T, std::char_traits<T>, Alloc>;
+
+// Overloads
+//  using A = Allocator;
+//  using BS = basic_string
+//  using BSV = basic_string_view
+// ---------------
+// (1)  basic_string() - NOT TESTED
+// (2)  basic_string(A const&) - BROKEN
+// (3)  basic_string(size_type, CharT, const A& = A())
+// (4)  basic_string(BS const&, size_type, A const& = A())
+// (5)  basic_string(BS const&, size_type, size_type, A const& = A()) - PARTIALLY BROKEN
+// (6)  basic_string(const CharT*, size_type, A const& = A())
+// (7)  basic_string(const CharT*, A const& = A())
+// (8)  basic_string(InputIt, InputIt, A const& = A()) - BROKEN
+// (9)  basic_string(BS const&)
+// (10) basic_string(BS const&, A const&)
+// (11) basic_string(BS&&)
+// (12) basic_string(BS&&, A const&)
+// (13) basic_string(initializer_list<CharT>, A const& = A())
+// (14) basic_string(BSV, A const& = A())
+// (15) basic_string(const T&, size_type, size_type, A const& = A()) - BROKEN
+int main()
+{
+  using TestSizeT = test_allocator<char>::size_type;
+  { // Testing (1)
+    // Nothing TODO. Cannot deduce without any arguments.
+  }
+  { // Testing (2)
+    // This overload isn't compatible with implicit deduction guides as
+    // specified in the standard.
+    // const test_allocator<char> alloc{};
+    // std::basic_string s(alloc);
+  }
+  { // Testing (3) w/o allocator
+    std::basic_string s(6ull, 'a');
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "aaaaaa");
+
+    std::basic_string w(2ull, L'b');
+    ASSERT_SAME_TYPE(decltype(w), std::wstring);
+    assert(w == L"bb");
+  }
+  { // Testing (3) w/ allocator
+    std::basic_string s(6ull, 'a', test_allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), BStr<char,test_allocator<char>>);
+    assert(s == "aaaaaa");
+
+    std::basic_string w(2ull, L'b', test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w), BStr<wchar_t, test_allocator<wchar_t>>);
+    assert(w == L"bb");
+  }
+  { // Testing (4) w/o allocator
+    const std::string sin("abc");
+    std::basic_string s(sin, (size_t)1);
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "bc");
+
+    using WStr = std::basic_string<wchar_t,
+                                  constexpr_char_traits<wchar_t>,
+                                  test_allocator<wchar_t>>;
+    const WStr win(L"abcdef");
+    std::basic_string w(win, (TestSizeT)3);
+    ASSERT_SAME_TYPE(decltype(w), WStr);
+    assert(w == L"def");
+  }
+  { // Testing (4) w/ allocator
+    const std::string sin("abc");
+    std::basic_string s(sin, (size_t)1, std::allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "bc");
+
+    using WStr = std::basic_string<wchar_t,
+                                  constexpr_char_traits<wchar_t>,
+                                  test_allocator<wchar_t>>;
+    const WStr win(L"abcdef");
+    std::basic_string w(win, (TestSizeT)3, test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w), WStr);
+    assert(w == L"def");
+  }
+  { // Testing (5) w/o allocator
+#if 0 // FIXME: This doesn't work
+    const std::string sin("abc");
+    std::basic_string s(sin, (size_t)1, (size_t)3);
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "bc");
+
+    using WStr = std::basic_string<wchar_t,
+                                  constexpr_char_traits<wchar_t>,
+                                  test_allocator<wchar_t>>;
+    const WStr win(L"abcdef");
+    std::basic_string w(win, (TestSizeT)2, (TestSizeT)3);
+    ASSERT_SAME_TYPE(decltype(w), WStr);
+    assert(w == L"cde");
+#endif
+  }
+  { // Testing (5) w/ allocator
+    const std::string sin("abc");
+    std::basic_string s(sin, (size_t)1, (size_t)3, std::allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "bc");
+
+    using WStr = std::basic_string<wchar_t,
+                                  constexpr_char_traits<wchar_t>,
+                                  test_allocator<wchar_t>>;
+    const WStr win(L"abcdef");
+    std::basic_string w(win, (TestSizeT)2, (TestSizeT)3, test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w), WStr);
+    assert(w == L"cde");
+  }
+  { // Testing (6) w/o allocator
+    std::basic_string s("abc", (size_t)2);
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "ab");
+
+    std::basic_string w(L"abcdef", (size_t)3);
+    ASSERT_SAME_TYPE(decltype(w), std::wstring);
+    assert(w == L"abc");
+  }
+  { // Testing (6) w/ allocator
+    std::basic_string s("abc", (size_t)2, std::allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "ab");
+
+    using WStr = std::basic_string<wchar_t,
+                                  std::char_traits<wchar_t>,
+                                  test_allocator<wchar_t>>;
+    std::basic_string w(L"abcdef", (TestSizeT)3, test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w), WStr);
+    assert(w == L"abc");
+  }
+  { // Testing (7) w/o allocator
+    std::basic_string s("abc");
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "abc");
+
+    std::basic_string w(L"abcdef");
+    ASSERT_SAME_TYPE(decltype(w), std::wstring);
+    assert(w == L"abcdef");
+  }
+  { // Testing (7) w/ allocator
+    std::basic_string s("abc", std::allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "abc");
+
+    using WStr = std::basic_string<wchar_t,
+                                  std::char_traits<wchar_t>,
+                                  test_allocator<wchar_t>>;
+    std::basic_string w(L"abcdef", test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w), WStr);
+    assert(w == L"abcdef");
+  }
+  { // (8) w/o allocator
+    // This overload isn't compatible with implicit deduction guides as
+    // specified in the standard.
+    // FIXME: Propose adding an explicit guide to the standard?
+  }
+  { // (8) w/ allocator
+    // This overload isn't compatible with implicit deduction guides as
+    // specified in the standard.
+    // FIXME: Propose adding an explicit guide to the standard?
+#if 0
+    using It = input_iterator<const char*>;
+    const char* input = "abcdef";
+    std::basic_string s(It(input), It(input + 3), std::allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+#endif
+  }
+  { // Testing (9)
+    const std::string sin("abc");
+    std::basic_string s(sin);
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "abc");
+
+    using WStr = std::basic_string<wchar_t,
+                                  constexpr_char_traits<wchar_t>,
+                                  test_allocator<wchar_t>>;
+    const WStr win(L"abcdef");
+    std::basic_string w(win);
+    ASSERT_SAME_TYPE(decltype(w), WStr);
+    assert(w == L"abcdef");
+  }
+  { // Testing (10)
+    const std::string sin("abc");
+    std::basic_string s(sin, std::allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "abc");
+
+    using WStr = std::basic_string<wchar_t,
+                                  constexpr_char_traits<wchar_t>,
+                                  test_allocator<wchar_t>>;
+    const WStr win(L"abcdef");
+    std::basic_string w(win, test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w), WStr);
+    assert(w == L"abcdef");
+  }
+  { // Testing (11)
+    std::string sin("abc");
+    std::basic_string s(std::move(sin));
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "abc");
+
+    using WStr = std::basic_string<wchar_t,
+                                  constexpr_char_traits<wchar_t>,
+                                  test_allocator<wchar_t>>;
+    WStr win(L"abcdef");
+    std::basic_string w(std::move(win));
+    ASSERT_SAME_TYPE(decltype(w), WStr);
+    assert(w == L"abcdef");
+  }
+  { // Testing (12)
+    std::string sin("abc");
+    std::basic_string s(std::move(sin), std::allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "abc");
+
+    using WStr = std::basic_string<wchar_t,
+                                  constexpr_char_traits<wchar_t>,
+                                  test_allocator<wchar_t>>;
+    WStr win(L"abcdef");
+    std::basic_string w(std::move(win), test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w), WStr);
+    assert(w == L"abcdef");
+  }
+  { // Testing (13) w/o allocator
+    std::basic_string s({'a', 'b', 'c'});
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "abc");
+
+    std::basic_string w({L'a', L'b', L'c'});
+    ASSERT_SAME_TYPE(decltype(w), std::wstring);
+    assert(w == L"abc");
+  }
+  { // Testing (13) w/ allocator
+    std::basic_string s({'a', 'b', 'c'}, test_allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), BStr<char, test_allocator<char>>);
+    assert(s == "abc");
+
+    std::basic_string w({L'a', L'b', L'c'}, test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w), BStr<wchar_t, test_allocator<wchar_t>>);
+    assert(w == L"abc");
+  }
+  { // Testing (14) w/o allocator
+    std::string_view sv("abc");
+    std::basic_string s(sv);
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "abc");
+
+    using Expect = std::basic_string<wchar_t, constexpr_char_traits<wchar_t>>;
+    std::basic_string_view<wchar_t, constexpr_char_traits<wchar_t>> BSV(L"abcdef");
+    std::basic_string w(BSV);
+    ASSERT_SAME_TYPE(decltype(w), Expect);
+    assert(w == L"abcdef");
+  }
+  { // Testing (14) w/ allocator
+    using ExpectS = std::basic_string<char, std::char_traits<char>, test_allocator<char>>;
+    std::string_view sv("abc");
+    std::basic_string s(sv, test_allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), ExpectS);
+    assert(s == "abc");
+
+    using ExpectW = std::basic_string<wchar_t, constexpr_char_traits<wchar_t>,
+                                      test_allocator<wchar_t>>;
+    std::basic_string_view<wchar_t, constexpr_char_traits<wchar_t>> BSV(L"abcdef");
+    std::basic_string w(BSV, test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w), ExpectW);
+    assert(w == L"abcdef");
+  }
+  { // Testing (15)
+    // This overload isn't compatible with implicit deduction guides as
+    // specified in the standard.
+  }
+}

Modified: libcxx/trunk/test/support/constexpr_char_traits.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/constexpr_char_traits.hpp?rev=295393&r1=295392&r2=295393&view=diff
==============================================================================
--- libcxx/trunk/test/support/constexpr_char_traits.hpp (original)
+++ libcxx/trunk/test/support/constexpr_char_traits.hpp Thu Feb 16 19:17:10 2017
@@ -12,6 +12,7 @@
 #define _CONSTEXPR_CHAR_TRAITS
 
 #include <string>
+#include <cassert>
 
 #include "test_macros.h"
 
@@ -118,7 +119,7 @@ template <class _CharT>
 TEST_CONSTEXPR_CXX14 _CharT*
 constexpr_char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 {
-    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+    assert(__s2 < __s1 || __s2 >= __s1+__n);
     char_type* __r = __s1;
     for (; __n; --__n, ++__s1, ++__s2)
         assign(*__s1, *__s2);

Modified: libcxx/trunk/utils/libcxx/test/config.py
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/libcxx/test/config.py?rev=295393&r1=295392&r2=295393&view=diff
==============================================================================
--- libcxx/trunk/utils/libcxx/test/config.py (original)
+++ libcxx/trunk/utils/libcxx/test/config.py Thu Feb 16 19:17:10 2017
@@ -397,6 +397,9 @@ class Configuration(object):
         if '__cpp_structured_bindings' not in macros:
             self.config.available_features.add('libcpp-no-structured-bindings')
 
+        if '__cpp_deduction_guides' not in macros:
+            self.config.available_features.add('libcpp-no-deduction-guides')
+
         if self.is_windows:
             self.config.available_features.add('windows')
 




More information about the cfe-commits mailing list