[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 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@295393 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -775,22 +775,22 @@ public:
|
|||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
basic_string(basic_string&& __str, const allocator_type& __a);
|
basic_string(basic_string&& __str, const allocator_type& __a);
|
||||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
#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
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
basic_string(const value_type* __s, const allocator_type& __a);
|
basic_string(const _CharT* __s, const _Allocator& __a);
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
basic_string(const value_type* __s, size_type __n);
|
basic_string(const _CharT* __s, size_type __n);
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_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
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
basic_string(size_type __n, value_type __c);
|
basic_string(size_type __n, _CharT __c);
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_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,
|
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
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
basic_string(const basic_string& __str, size_type __pos,
|
basic_string(const basic_string& __str, size_type __pos,
|
||||||
const allocator_type& __a = allocator_type());
|
const _Allocator& __a = _Allocator());
|
||||||
template<class _Tp>
|
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(),
|
const allocator_type& __a = allocator_type(),
|
||||||
@@ -798,7 +798,7 @@ public:
|
|||||||
_LIBCPP_INLINE_VISIBILITY explicit
|
_LIBCPP_INLINE_VISIBILITY explicit
|
||||||
basic_string(__self_view __sv);
|
basic_string(__self_view __sv);
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
basic_string(__self_view __sv, const allocator_type& __a);
|
basic_string(__self_view __sv, const _Allocator& __a);
|
||||||
template<class _InputIterator>
|
template<class _InputIterator>
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
basic_string(_InputIterator __first, _InputIterator __last);
|
basic_string(_InputIterator __first, _InputIterator __last);
|
||||||
@@ -807,9 +807,9 @@ public:
|
|||||||
basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
|
basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
|
||||||
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
|
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
basic_string(initializer_list<value_type> __il);
|
basic_string(initializer_list<_CharT> __il);
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_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
|
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
|
||||||
|
|
||||||
inline ~basic_string();
|
inline ~basic_string();
|
||||||
@@ -1557,7 +1557,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
|
|||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
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");
|
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
|
||||||
__init(__s, traits_type::length(__s));
|
__init(__s, traits_type::length(__s));
|
||||||
@@ -1568,7 +1568,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
|
|||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
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)
|
: __r_(__a)
|
||||||
{
|
{
|
||||||
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
|
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
|
||||||
@@ -1580,7 +1580,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, c
|
|||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
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");
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
|
||||||
__init(__s, __n);
|
__init(__s, __n);
|
||||||
@@ -1591,7 +1591,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, s
|
|||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
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)
|
: __r_(__a)
|
||||||
{
|
{
|
||||||
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
|
||||||
@@ -1615,7 +1615,8 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class _CharT, class _Traits, class _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)
|
: __r_(__a)
|
||||||
{
|
{
|
||||||
if (!__str.__is_long())
|
if (!__str.__is_long())
|
||||||
@@ -1694,7 +1695,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
|
|||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
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);
|
__init(__n, __c);
|
||||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||||
@@ -1704,7 +1705,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_typ
|
|||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
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)
|
: __r_(__a)
|
||||||
{
|
{
|
||||||
__init(__n, __c);
|
__init(__n, __c);
|
||||||
@@ -1714,8 +1715,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class _CharT, class _Traits, class _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,
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
|
||||||
const allocator_type& __a)
|
size_type __pos, size_type __n,
|
||||||
|
const _Allocator& __a)
|
||||||
: __r_(__a)
|
: __r_(__a)
|
||||||
{
|
{
|
||||||
size_type __str_sz = __str.size();
|
size_type __str_sz = __str.size();
|
||||||
@@ -1730,7 +1732,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
|
|||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
|
||||||
const allocator_type& __a)
|
const _Allocator& __a)
|
||||||
: __r_(__a)
|
: __r_(__a)
|
||||||
{
|
{
|
||||||
size_type __str_sz = __str.size();
|
size_type __str_sz = __str.size();
|
||||||
@@ -1768,7 +1770,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv)
|
|||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
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)
|
: __r_(__a)
|
||||||
{
|
{
|
||||||
__init(__sv.data(), __sv.size());
|
__init(__sv.data(), __sv.size());
|
||||||
@@ -1863,7 +1865,8 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first,
|
|||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
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());
|
__init(__il.begin(), __il.end());
|
||||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||||
@@ -1873,7 +1876,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_t
|
|||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
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)
|
: __r_(__a)
|
||||||
{
|
{
|
||||||
__init(__il.begin(), __il.end());
|
__init(__il.begin(), __il.end());
|
||||||
|
|||||||
@@ -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.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#define _CONSTEXPR_CHAR_TRAITS
|
#define _CONSTEXPR_CHAR_TRAITS
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include "test_macros.h"
|
#include "test_macros.h"
|
||||||
|
|
||||||
@@ -118,7 +119,7 @@ template <class _CharT>
|
|||||||
TEST_CONSTEXPR_CXX14 _CharT*
|
TEST_CONSTEXPR_CXX14 _CharT*
|
||||||
constexpr_char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
|
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;
|
char_type* __r = __s1;
|
||||||
for (; __n; --__n, ++__s1, ++__s2)
|
for (; __n; --__n, ++__s1, ++__s2)
|
||||||
assign(*__s1, *__s2);
|
assign(*__s1, *__s2);
|
||||||
|
|||||||
@@ -397,6 +397,9 @@ class Configuration(object):
|
|||||||
if '__cpp_structured_bindings' not in macros:
|
if '__cpp_structured_bindings' not in macros:
|
||||||
self.config.available_features.add('libcpp-no-structured-bindings')
|
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:
|
if self.is_windows:
|
||||||
self.config.available_features.add('windows')
|
self.config.available_features.add('windows')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user