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