Index: include/string =================================================================== --- include/string +++ include/string @@ -775,22 +775,22 @@ _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 basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type(), @@ -798,7 +798,7 @@ _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 _LIBCPP_INLINE_VISIBILITY basic_string(_InputIterator __first, _InputIterator __last); @@ -807,9 +807,9 @@ basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY - basic_string(initializer_list __il); + basic_string(initializer_list<_CharT> __il); _LIBCPP_INLINE_VISIBILITY - basic_string(initializer_list __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 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 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 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 -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 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 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 -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 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 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 inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list __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 inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list __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()); 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 + +// + +// Test that the constructors offered by std::basic_string are formulated +// so they're compatible with implicit deduction guides. + +#include +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" +#include "constexpr_char_traits.hpp" + + +template > +using BStr = std::basic_string, Alloc>; + + +int main() +{ + { + std::basic_string s = "hello world"; + std::basic_string w(L"hello world"); + + ASSERT_SAME_TYPE(decltype(s), std::basic_string); + ASSERT_SAME_TYPE(decltype(w), std::basic_string); + } + { + std::basic_string s("hello world", test_allocator{}); + ASSERT_SAME_TYPE(decltype(s), BStr>); + } + { + std::basic_string s("hello world", 2ull, test_allocator{}); + std::basic_string w(L"hello world", 2ull, test_allocator{}); + ASSERT_SAME_TYPE(decltype(s), BStr>); + ASSERT_SAME_TYPE(decltype(w), BStr>); + + } + { + 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{}); + std::basic_string w(2ull, L'b', test_allocator{}); + ASSERT_SAME_TYPE(decltype(s), BStr>); + assert(s == "aaaaaa"); + ASSERT_SAME_TYPE(decltype(w), BStr>); + 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{}); + ASSERT_SAME_TYPE(decltype(s), BStr>); + assert(s == "abc"); + + std::basic_string w({L'a', L'b', L'c'}, test_allocator{}); + ASSERT_SAME_TYPE(decltype(w), BStr>); + 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; + std::basic_string_view wsv(L"def"); + std::basic_string w(wsv, test_allocator{}); + ASSERT_SAME_TYPE(decltype(w), + std::basic_string>); + } + { + // 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> w1(L"abcd"); + std::basic_string w(w1, 1u, 3u, test_allocator{}); + ASSERT_SAME_TYPE(decltype(w), BStr>); + } +}