Implement LWG 2946, 3075 and 3076. Reviewed as https://reviews.llvm.org/D48616
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@336132 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -68,4 +68,13 @@ int main()
|
||||
S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_STD_VER > 3
|
||||
{ // LWG 2946
|
||||
std::string s;
|
||||
s = {"abc", 1};
|
||||
assert(s.size() == 1);
|
||||
assert(s == "a");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -22,13 +22,6 @@
|
||||
#include "test_macros.h"
|
||||
#include "test_allocator.h"
|
||||
|
||||
template <class T>
|
||||
struct some_alloc
|
||||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
@@ -40,7 +33,7 @@ int main()
|
||||
static_assert(std::is_nothrow_default_constructible<C>::value, "");
|
||||
}
|
||||
{
|
||||
typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C;
|
||||
typedef std::basic_string<char, std::char_traits<char>, limited_allocator<char, 10>> C;
|
||||
static_assert(!std::is_nothrow_default_constructible<C>::value, "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
#include "test_allocator.h"
|
||||
|
||||
template <class T>
|
||||
struct some_alloc
|
||||
struct throwing_alloc
|
||||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
~some_alloc() noexcept(false);
|
||||
throwing_alloc(const throwing_alloc&);
|
||||
T *allocate(size_t);
|
||||
~throwing_alloc() noexcept(false);
|
||||
};
|
||||
|
||||
// Test that it's possible to take the address of basic_string's destructors
|
||||
@@ -44,7 +45,7 @@ int main()
|
||||
}
|
||||
#if defined(_LIBCPP_VERSION)
|
||||
{
|
||||
typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C;
|
||||
typedef std::basic_string<char, std::char_traits<char>, throwing_alloc<char>> C;
|
||||
static_assert(!std::is_nothrow_destructible<C>::value, "");
|
||||
}
|
||||
#endif // _LIBCPP_VERSION
|
||||
|
||||
@@ -36,7 +36,7 @@ using BStr = std::basic_string<T, std::char_traits<T>, Alloc>;
|
||||
// (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
|
||||
// (5) basic_string(BS const&, size_type, size_type, A const& = A())
|
||||
// (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
|
||||
@@ -46,7 +46,7 @@ using BStr = std::basic_string<T, std::char_traits<T>, Alloc>;
|
||||
// (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
|
||||
// (15) basic_string(const T&, size_type, size_type, A const& = A())
|
||||
int main()
|
||||
{
|
||||
using TestSizeT = test_allocator<char>::size_type;
|
||||
@@ -106,7 +106,6 @@ int main()
|
||||
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);
|
||||
@@ -119,7 +118,6 @@ int main()
|
||||
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");
|
||||
@@ -178,20 +176,19 @@ int main()
|
||||
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
|
||||
assert(s == "abc");
|
||||
}
|
||||
{ // (8) w/ allocator
|
||||
using ExpectW = std::basic_string<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>;
|
||||
using It = input_iterator<const wchar_t*>;
|
||||
const wchar_t* input = L"abcdef";
|
||||
std::basic_string s(It(input), It(input + 3), test_allocator<wchar_t>{});
|
||||
ASSERT_SAME_TYPE(decltype(s), ExpectW);
|
||||
assert(s == L"abc");
|
||||
}
|
||||
{ // Testing (9)
|
||||
const std::string sin("abc");
|
||||
@@ -293,8 +290,28 @@ int main()
|
||||
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.
|
||||
{ // Testing (15) w/o allocator
|
||||
std::string s0("abc");
|
||||
std::basic_string s(s0, 1, 1);
|
||||
ASSERT_SAME_TYPE(decltype(s), std::string);
|
||||
assert(s == "b");
|
||||
|
||||
std::wstring w0(L"abcdef");
|
||||
std::basic_string w(w0, 2, 2);
|
||||
ASSERT_SAME_TYPE(decltype(w), std::wstring);
|
||||
assert(w == L"cd");
|
||||
}
|
||||
{ // Testing (15) w/ allocator
|
||||
using ExpectS = std::basic_string<char, std::char_traits<char>, test_allocator<char>>;
|
||||
ExpectS s0("abc");
|
||||
std::basic_string s(s0, 1, 1, test_allocator<char>{4});
|
||||
ASSERT_SAME_TYPE(decltype(s), ExpectS);
|
||||
assert(s == "b");
|
||||
|
||||
using ExpectW = std::basic_string<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>;
|
||||
ExpectW w0(L"abcdef");
|
||||
std::basic_string w(w0, 2, 2, test_allocator<wchar_t>{6});
|
||||
ASSERT_SAME_TYPE(decltype(w), ExpectW);
|
||||
assert(w == L"cd");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ struct some_alloc
|
||||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
T *allocate(size_t);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -41,6 +42,7 @@ struct some_alloc2
|
||||
|
||||
some_alloc2() {}
|
||||
some_alloc2(const some_alloc2&);
|
||||
T *allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::false_type propagate_on_container_move_assignment;
|
||||
@@ -54,6 +56,7 @@ struct some_alloc3
|
||||
|
||||
some_alloc3() {}
|
||||
some_alloc3(const some_alloc3&);
|
||||
T *allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::false_type propagate_on_container_move_assignment;
|
||||
|
||||
@@ -22,13 +22,6 @@
|
||||
#include "test_macros.h"
|
||||
#include "test_allocator.h"
|
||||
|
||||
template <class T>
|
||||
struct some_alloc
|
||||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
@@ -40,7 +33,7 @@ int main()
|
||||
static_assert(std::is_nothrow_move_constructible<C>::value, "");
|
||||
}
|
||||
{
|
||||
typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C;
|
||||
typedef std::basic_string<char, std::char_traits<char>, limited_allocator<char, 10>> C;
|
||||
#if TEST_STD_VER <= 14
|
||||
static_assert(!std::is_nothrow_move_constructible<C>::value, "");
|
||||
#else
|
||||
|
||||
@@ -83,4 +83,12 @@ int main()
|
||||
test("123456798012345679801234567980123456798012345679801234567980", 60, A());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_STD_VER > 3
|
||||
{ // LWG 2946
|
||||
std::string s({"abc", 1});
|
||||
assert(s.size() == 1);
|
||||
assert(s == "a");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <string>
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// XFAIL: libcpp-no-deduction-guides
|
||||
|
||||
// template<class InputIterator>
|
||||
// basic_string(InputIterator begin, InputIterator end,
|
||||
// const Allocator& a = Allocator());
|
||||
|
||||
// template<class charT,
|
||||
// class traits,
|
||||
// class Allocator = allocator<charT>
|
||||
// >
|
||||
// basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
|
||||
// -> basic_string<charT, traits, Allocator>;
|
||||
//
|
||||
// The deduction guide shall not participate in overload resolution if Allocator
|
||||
// is a type that does not qualify as an allocator.
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::string_view sv = "12345678901234";
|
||||
std::basic_string s1{sv, 23}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <string>
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// XFAIL: libcpp-no-deduction-guides
|
||||
|
||||
// template<class InputIterator>
|
||||
// basic_string(InputIterator begin, InputIterator end,
|
||||
// const Allocator& a = Allocator());
|
||||
|
||||
// template<class charT,
|
||||
// class traits,
|
||||
// class Allocator = allocator<charT>
|
||||
// >
|
||||
// basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
|
||||
// -> basic_string<charT, traits, Allocator>;
|
||||
//
|
||||
// The deduction guide shall not participate in overload resolution if Allocator
|
||||
// is a type that does not qualify as an allocator.
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_allocator.h"
|
||||
#include "../input_iterator.h"
|
||||
#include "min_allocator.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::string_view sv = "12345678901234";
|
||||
std::basic_string s1(sv);
|
||||
using S = decltype(s1); // what type did we get?
|
||||
static_assert(std::is_same_v<S::value_type, char>, "");
|
||||
static_assert(std::is_same_v<S::traits_type, std::char_traits<char>>, "");
|
||||
static_assert(std::is_same_v<S::allocator_type, std::allocator<char>>, "");
|
||||
assert(s1.size() == sv.size());
|
||||
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
std::string_view sv = "12345678901234";
|
||||
std::basic_string s1{sv, std::allocator<char>{}};
|
||||
using S = decltype(s1); // what type did we get?
|
||||
static_assert(std::is_same_v<S::value_type, char>, "");
|
||||
static_assert(std::is_same_v<S::traits_type, std::char_traits<char>>, "");
|
||||
static_assert(std::is_same_v<S::allocator_type, std::allocator<char>>, "");
|
||||
assert(s1.size() == sv.size());
|
||||
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
|
||||
}
|
||||
{
|
||||
std::wstring_view sv = L"12345678901234";
|
||||
std::basic_string s1{sv, test_allocator<wchar_t>{}};
|
||||
using S = decltype(s1); // what type did we get?
|
||||
static_assert(std::is_same_v<S::value_type, wchar_t>, "");
|
||||
static_assert(std::is_same_v<S::traits_type, std::char_traits<wchar_t>>, "");
|
||||
static_assert(std::is_same_v<S::allocator_type, test_allocator<wchar_t>>, "");
|
||||
assert(s1.size() == sv.size());
|
||||
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
|
||||
}
|
||||
{
|
||||
std::u16string_view sv = u"12345678901234";
|
||||
std::basic_string s1{sv, min_allocator<char16_t>{}};
|
||||
using S = decltype(s1); // what type did we get?
|
||||
static_assert(std::is_same_v<S::value_type, char16_t>, "");
|
||||
static_assert(std::is_same_v<S::traits_type, std::char_traits<char16_t>>, "");
|
||||
static_assert(std::is_same_v<S::allocator_type, min_allocator<char16_t>>, "");
|
||||
assert(s1.size() == sv.size());
|
||||
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
|
||||
}
|
||||
{
|
||||
std::u32string_view sv = U"12345678901234";
|
||||
std::basic_string s1{sv, explicit_allocator<char32_t>{}};
|
||||
using S = decltype(s1); // what type did we get?
|
||||
static_assert(std::is_same_v<S::value_type, char32_t>, "");
|
||||
static_assert(std::is_same_v<S::traits_type, std::char_traits<char32_t>>, "");
|
||||
static_assert(std::is_same_v<S::allocator_type, explicit_allocator<char32_t>>, "");
|
||||
assert(s1.size() == sv.size());
|
||||
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <string>
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// XFAIL: libcpp-no-deduction-guides
|
||||
|
||||
// template<class InputIterator>
|
||||
// basic_string(InputIterator begin, InputIterator end,
|
||||
// const Allocator& a = Allocator());
|
||||
|
||||
// template<class charT,
|
||||
// class traits,
|
||||
// class Allocator = allocator<charT>
|
||||
// >
|
||||
// basic_string(basic_string_view<charT, traits>,
|
||||
// typename see below::size_type,
|
||||
// typename see below::size_type,
|
||||
// const Allocator& = Allocator())
|
||||
// -> basic_string<charT, traits, Allocator>;
|
||||
//
|
||||
// A size_type parameter type in a basic_string deduction guide refers to the size_type
|
||||
// member type of the type deduced by the deduction guide.
|
||||
//
|
||||
// The deduction guide shall not participate in overload resolution if Allocator
|
||||
// is a type that does not qualify as an allocator.
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::string_view sv = "12345678901234";
|
||||
std::basic_string s1{sv, 0, 4, 23}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <string>
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// XFAIL: libcpp-no-deduction-guides
|
||||
|
||||
// template<class InputIterator>
|
||||
// basic_string(InputIterator begin, InputIterator end,
|
||||
// const Allocator& a = Allocator());
|
||||
|
||||
// template<class charT,
|
||||
// class traits,
|
||||
// class Allocator = allocator<charT>
|
||||
// >
|
||||
// basic_string(basic_string_view<charT, traits>,
|
||||
// typename see below::size_type,
|
||||
// typename see below::size_type,
|
||||
// const Allocator& = Allocator())
|
||||
// -> basic_string<charT, traits, Allocator>;
|
||||
//
|
||||
// A size_type parameter type in a basic_string deduction guide refers to the size_type
|
||||
// member type of the type deduced by the deduction guide.
|
||||
//
|
||||
// The deduction guide shall not participate in overload resolution if Allocator
|
||||
// is a type that does not qualify as an allocator.
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_allocator.h"
|
||||
#include "../input_iterator.h"
|
||||
#include "min_allocator.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::string_view sv = "12345678901234";
|
||||
std::basic_string s1{sv, 0, 4};
|
||||
using S = decltype(s1); // what type did we get?
|
||||
static_assert(std::is_same_v<S::value_type, char>, "");
|
||||
static_assert(std::is_same_v<S::traits_type, std::char_traits<char>>, "");
|
||||
static_assert(std::is_same_v<S::allocator_type, std::allocator<char>>, "");
|
||||
assert(s1.size() == 4);
|
||||
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
std::string_view sv = "12345678901234";
|
||||
std::basic_string s1{sv, 0, 4, std::allocator<char>{}};
|
||||
using S = decltype(s1); // what type did we get?
|
||||
static_assert(std::is_same_v<S::value_type, char>, "");
|
||||
static_assert(std::is_same_v<S::traits_type, std::char_traits<char>>, "");
|
||||
static_assert(std::is_same_v<S::allocator_type, std::allocator<char>>, "");
|
||||
assert(s1.size() == 4);
|
||||
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
|
||||
}
|
||||
{
|
||||
std::wstring_view sv = L"12345678901234";
|
||||
std::basic_string s1{sv, 0, 4, test_allocator<wchar_t>{}};
|
||||
using S = decltype(s1); // what type did we get?
|
||||
static_assert(std::is_same_v<S::value_type, wchar_t>, "");
|
||||
static_assert(std::is_same_v<S::traits_type, std::char_traits<wchar_t>>, "");
|
||||
static_assert(std::is_same_v<S::allocator_type, test_allocator<wchar_t>>, "");
|
||||
assert(s1.size() == 4);
|
||||
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
|
||||
}
|
||||
{
|
||||
std::u16string_view sv = u"12345678901234";
|
||||
std::basic_string s1{sv, 0, 4, min_allocator<char16_t>{}};
|
||||
using S = decltype(s1); // what type did we get?
|
||||
static_assert(std::is_same_v<S::value_type, char16_t>, "");
|
||||
static_assert(std::is_same_v<S::traits_type, std::char_traits<char16_t>>, "");
|
||||
static_assert(std::is_same_v<S::allocator_type, min_allocator<char16_t>>, "");
|
||||
assert(s1.size() == 4);
|
||||
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
|
||||
}
|
||||
{
|
||||
std::u32string_view sv = U"12345678901234";
|
||||
std::basic_string s1{sv, 0, 4, explicit_allocator<char32_t>{}};
|
||||
using S = decltype(s1); // what type did we get?
|
||||
static_assert(std::is_same_v<S::value_type, char32_t>, "");
|
||||
static_assert(std::is_same_v<S::traits_type, std::char_traits<char32_t>>, "");
|
||||
static_assert(std::is_same_v<S::allocator_type, explicit_allocator<char32_t>>, "");
|
||||
assert(s1.size() == 4);
|
||||
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user