EricWF updated this revision to Diff 88088.
EricWF added a comment.

- Fix the initializer list constructors.
- Add tests for almost every constructor.

The following two examples still do not work:

  std::basic_string s1("hello world", 2); // deduces Allocator = int
  std::basic_string s2("hello world", 0, 2); // deduces Allocator = int

This is because the `Allocator` argument is not normally deduced, and
therefore would not normally accept an integer argument.


https://reviews.llvm.org/D29863

Files:
  include/string
  test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp

Index: test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp
===================================================================
--- /dev/null
+++ test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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
+
+// Clang does not implement deduction guides yet.
+// XFAIL: clang, apple-clang
+
+// <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 "constexpr_char_traits.hpp"
+
+
+template <class T, class Alloc = std::allocator<T>>
+using BStr = std::basic_string<T, std::char_traits<T>, Alloc>;
+
+
+int main()
+{
+  {
+    std::basic_string s = "hello world";
+    std::basic_string w(L"hello world");
+
+    ASSERT_SAME_TYPE(decltype(s), std::basic_string<char>);
+    ASSERT_SAME_TYPE(decltype(w), std::basic_string<wchar_t>);
+  }
+  {
+    std::basic_string s("hello world", test_allocator<char>{});
+    ASSERT_SAME_TYPE(decltype(s), BStr<char, test_allocator<char>>);
+  }
+  {
+    std::basic_string s("hello world", 2ull, test_allocator<char>{});
+    std::basic_string w(L"hello world", 2ull, test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(s), BStr<char,test_allocator<char>>);
+    ASSERT_SAME_TYPE(decltype(w), BStr<wchar_t, test_allocator<wchar_t>>);
+
+  }
+  {
+    std::basic_string s(6ull, 'a');
+    std::basic_string w(2ull, L'b');
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "aaaaaa");
+    ASSERT_SAME_TYPE(decltype(w), std::wstring);
+    assert(w == L"bb");
+  }
+  {
+    std::basic_string s(6ull, 'a', test_allocator<char>{});
+    std::basic_string w(2ull, L'b', test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(s), BStr<char,test_allocator<char>>);
+    assert(s == "aaaaaa");
+    ASSERT_SAME_TYPE(decltype(w), BStr<wchar_t, test_allocator<wchar_t>>);
+    assert(w == L"bb");
+  }
+  {
+    std::string const s1;
+    std::basic_string s(s1);
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+
+    std::basic_string w = std::wstring{};
+    ASSERT_SAME_TYPE(decltype(w), std::wstring);
+  }
+  {
+    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");
+  }
+  {
+    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");
+  }
+  {
+    std::string_view sv("abc");
+    std::basic_string s(sv);
+    ASSERT_SAME_TYPE(decltype(s), std::string);
+    assert(s == "abc");
+
+    using CT = constexpr_char_traits<wchar_t>;
+    std::basic_string_view<wchar_t, CT> wsv(L"def");
+    std::basic_string w(wsv, test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w),
+                     std::basic_string<wchar_t, CT, test_allocator<wchar_t>>);
+  }
+  {
+    // FIXME: The third argument deduces as the allocator.
+    // std::string s1("abcd");
+    //std::basic_string s(s1, 1ull, 3ull);
+    //ASSERT_SAME_TYPE(decltype(s), std::string);
+
+    const BStr<wchar_t, test_allocator<wchar_t>> w1(L"abcd");
+    std::basic_string w(w1, 1u, 3u, test_allocator<wchar_t>{});
+    ASSERT_SAME_TYPE(decltype(w), BStr<wchar_t, test_allocator<wchar_t>>);
+  }
+}
Index: include/string
===================================================================
--- include/string
+++ include/string
@@ -775,41 +775,41 @@
     _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);
     _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, 
                      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);
     template<class _InputIterator>
         _LIBCPP_INLINE_VISIBILITY
         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 @@
 
 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 @@
 
 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");
@@ -1591,7 +1591,7 @@
 
 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 @@
 }
 
 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 @@
 
 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 @@
 
 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 @@
 }
 
 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 @@
 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();
@@ -1768,7 +1770,7 @@
 
 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 @@
 
 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 @@
 
 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());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to