diff options
Diffstat (limited to 'test/std/strings/basic.string')
30 files changed, 659 insertions, 43 deletions
diff --git a/test/std/strings/basic.string/char.bad.fail.cpp b/test/std/strings/basic.string/char.bad.fail.cpp new file mode 100644 index 000000000000..1878cd02ca38 --- /dev/null +++ b/test/std/strings/basic.string/char.bad.fail.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// 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> +// ... manipulating sequences of any non-array trivial standard-layout types. + +#include <string> +#include "test_traits.h" + +struct NotTrivial { + NotTrivial() : value(3) {} + int value; +}; + +struct NotStandardLayout { +public: + NotStandardLayout() : one(1), two(2) {} + int sum() const { return one + two; } // silences "unused field 'two' warning" + int one; +private: + int two; +}; + +int main() +{ + { +// array + typedef char C[3]; + static_assert(std::is_array<C>::value, ""); + std::basic_string<C, test_traits<C> > s; +// expected-error-re@string:* {{static_assert failed{{.*}} "Character type of basic_string must not be an array"}} + } + + { +// not trivial + static_assert(!std::is_trivial<NotTrivial>::value, ""); + std::basic_string<NotTrivial, test_traits<NotTrivial> > s; +// expected-error-re@string:* {{static_assert failed{{.*}} "Character type of basic_string must be trivial"}} + } + + { +// not standard layout + static_assert(!std::is_standard_layout<NotStandardLayout>::value, ""); + std::basic_string<NotStandardLayout, test_traits<NotStandardLayout> > s; +// expected-error-re@string:* {{static_assert failed{{.*}} "Character type of basic_string must be standard-layout"}} + } +} diff --git a/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp b/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp index b1e9108e90ba..34d5f306a739 100644 --- a/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp +++ b/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp @@ -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 } diff --git a/test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp b/test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp index 87698ec55103..a995a51eed48 100644 --- a/test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp +++ b/test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp @@ -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, ""); } } diff --git a/test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp b/test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp index f4ff0645afcf..a4de566a4dc0 100644 --- a/test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp +++ b/test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp @@ -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 diff --git a/test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp b/test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp index 0fbd663db4bc..3665e23a727b 100644 --- a/test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp +++ b/test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp @@ -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"); } } diff --git a/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp index 1f83696891c4..e7fefacc068f 100644 --- a/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp @@ -13,6 +13,7 @@ // basic_string(InputIterator begin, InputIterator end, // const Allocator& a = Allocator()); + #include <string> #include <iterator> #include <cassert> diff --git a/test/std/strings/basic.string/string.cons/iter_alloc_deduction.fail.cpp b/test/std/strings/basic.string/string.cons/iter_alloc_deduction.fail.cpp new file mode 100644 index 000000000000..9c2a3201f8af --- /dev/null +++ b/test/std/strings/basic.string/string.cons/iter_alloc_deduction.fail.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8, clang-3.9, clang-4.0 +// UNSUPPORTED: apple-clang-6, apple-clang-7, apple-clang-8, apple-clang-9 + +// template<class InputIterator, +// class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> +// basic_string(InputIterator, InputIterator, Allocator = Allocator()) +// -> basic_string<typename iterator_traits<InputIterator>::value_type, +// char_traits<typename iterator_traits<InputIterator>::value_type>, +// Allocator>; +// +// The deduction guide shall not participate in overload resolution if InputIterator +// is a type that does not qualify as an input iterator, or if Allocator is a type +// that does not qualify as an allocator. + + +#include <string> +#include <iterator> +#include <cassert> +#include <cstddef> + +#include "test_macros.h" + +class NotAnItertor {}; + +template <typename T> +struct NotAnAllocator { typedef T value_type; }; + +int main() +{ + { // Not an iterator at all + std::basic_string s1{NotAnItertor{}, NotAnItertor{}, std::allocator<char>{}}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}} + } + { // Not an input iterator + const char16_t* s = u"12345678901234"; + std::basic_string<char16_t> s0; + std::basic_string s1{std::back_insert_iterator(s0), // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}} + std::back_insert_iterator(s0), + std::allocator<char16_t>{}}; + } + { // Not an allocator + const wchar_t* s = L"12345678901234"; + std::basic_string s1{s, s+10, NotAnAllocator<wchar_t>{}}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}} + } + +} diff --git a/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp b/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp new file mode 100644 index 000000000000..815b5600dd47 --- /dev/null +++ b/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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 InputIterator, +// class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> +// basic_string(InputIterator, InputIterator, Allocator = Allocator()) +// -> basic_string<typename iterator_traits<InputIterator>::value_type, +// char_traits<typename iterator_traits<InputIterator>::value_type>, +// Allocator>; +// +// The deduction guide shall not participate in overload resolution if InputIterator +// is a type that does not qualify as an input iterator, or if Allocator is a type +// that does not qualify as an allocator. + + +#include <string> +#include <iterator> +#include <cassert> +#include <cstddef> + +#include "test_macros.h" +#include "test_allocator.h" +#include "../input_iterator.h" +#include "min_allocator.h" + +int main() +{ + { + const char* s = "12345678901234"; + std::basic_string s1(s, s+10); // Can't use {} here + 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() == 10); + assert(s1.compare(0, s1.size(), s, s1.size()) == 0); + } + + { + const char* s = "12345678901234"; + std::basic_string s1{s, s+10, 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() == 10); + assert(s1.compare(0, s1.size(), s, s1.size()) == 0); + } + { + const wchar_t* s = L"12345678901234"; + std::basic_string s1{s, s+10, 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() == 10); + assert(s1.compare(0, s1.size(), s, s1.size()) == 0); + } + { + const char16_t* s = u"12345678901234"; + std::basic_string s1{s, s+10, 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() == 10); + assert(s1.compare(0, s1.size(), s, s1.size()) == 0); + } + { + const char32_t* s = U"12345678901234"; + std::basic_string s1{s, s+10, 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() == 10); + assert(s1.compare(0, s1.size(), s, s1.size()) == 0); + } +} diff --git a/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp b/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp index 0720543420a8..ad9ed36d3f80 100644 --- a/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp +++ b/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp @@ -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; diff --git a/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp b/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp index 9a7c65ca2cf5..e0e4a4ff31bd 100644 --- a/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp +++ b/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp @@ -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 diff --git a/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp index 3c75a700eaed..6d660fd10e8e 100644 --- a/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp @@ -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 } diff --git a/test/std/strings/basic.string/string.cons/string_view_deduction.fail.cpp b/test/std/strings/basic.string/string.cons/string_view_deduction.fail.cpp new file mode 100644 index 000000000000..b2fece8da8c2 --- /dev/null +++ b/test/std/strings/basic.string/string.cons/string_view_deduction.fail.cpp @@ -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'}} + } +} diff --git a/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp b/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp new file mode 100644 index 000000000000..df1e99e0147f --- /dev/null +++ b/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp @@ -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); + } +} diff --git a/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp b/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp new file mode 100644 index 000000000000..f79e43f6a6b0 --- /dev/null +++ b/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp @@ -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'}} + } +} diff --git a/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp b/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp new file mode 100644 index 000000000000..d9561d22b882 --- /dev/null +++ b/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp @@ -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); + } +} diff --git a/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp index 5ca5aaf8629c..38b68aa69042 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp @@ -48,14 +48,13 @@ int main() test(S("12345678901234567890"), 'a', S("12345678901234567890a")); } #endif -#if 0 + { // https://bugs.llvm.org/show_bug.cgi?id=31454 std::basic_string<veryLarge> s; - veryLarge vl; + veryLarge vl = {}; s.push_back(vl); s.push_back(vl); s.push_back(vl); } -#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp index b58ed632893e..b3704268a4b6 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp @@ -77,4 +77,13 @@ int main() S("1234567890123456789012345678901234567890")); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s; + s.append({"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp index e7c5ecdc9c1b..4c3a87248c72 100644 --- a/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp @@ -218,4 +218,13 @@ int main() test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), S("can't happen")); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s; + s.insert(0, {"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp index 1064855c1506..bbe385015331 100644 --- a/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp @@ -77,4 +77,13 @@ int main() S("1234567890123456789012345678901234567890")); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s; + s += {"abc", 1}; + assert(s.size() == 1); + assert(s == "a"); + } +#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp index 190e10d5c830..f5f31254eb10 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp @@ -281,4 +281,13 @@ int main() test2<S>(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " "; + s.replace(s.cbegin(), s.cend(), {"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp index 612e1e200c90..88982e09804f 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp @@ -379,4 +379,13 @@ int main() test2<S>(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " "; + s.replace(0, 1, {"abc", 1}); + assert(s.size() == 1); + assert(s == "a"); + } +#endif } diff --git a/test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp index 73727198f28e..c8b784c2465f 100644 --- a/test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp @@ -35,8 +35,8 @@ struct some_alloc some_alloc() {} some_alloc(const some_alloc&); + T *allocate(size_t); void deallocate(void*, unsigned) {} - typedef std::true_type propagate_on_container_swap; }; @@ -47,6 +47,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_swap; diff --git a/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp b/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp index 0ddbf2e2f99f..be730cbc1242 100644 --- a/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp @@ -15,9 +15,8 @@ #include <stdexcept> #include <cassert> -#include "min_allocator.h" - #include "test_macros.h" +#include "min_allocator.h" int sign(int x) { @@ -378,4 +377,11 @@ int main() test2<S>(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.compare(0, 1, {"abc", 1}) < 0); + } +#endif } diff --git a/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp b/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp index 3f6c169d223a..80d579e300c3 100644 --- a/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int sign(int x) @@ -74,4 +75,11 @@ int main() test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), 0); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.compare({"abc", 1}) < 0); + } +#endif } diff --git a/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp index b7df3461792b..4ce343351a9e 100644 --- a/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -154,4 +155,11 @@ int main() test1<S>(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_first_not_of({"abc", 1}) == 0); + } +#endif } diff --git a/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp index 765d1603af8c..105c2a6db175 100644 --- a/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -154,4 +155,11 @@ int main() test1<S>(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_first_of({"abc", 1}) == std::string::npos); + } +#endif } diff --git a/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp index f3377596ab3d..57fab60e78a7 100644 --- a/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -154,4 +155,11 @@ int main() test1<S>(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_last_not_of({"abc", 1}) == s.size() - 1); + } +#endif } diff --git a/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp index 5cb2df7c6c7f..b6b5b8f1217e 100644 --- a/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -154,4 +155,11 @@ int main() test1<S>(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find_last_of({"abc", 1}) == std::string::npos); + } +#endif } diff --git a/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp index e519a7943ba9..769b51c8dc10 100644 --- a/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -154,4 +155,11 @@ int main() test1<S>(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.find({"abc", 1}) == std::string::npos); + } +#endif } diff --git a/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp index ef571c284b81..d7908ad8583b 100644 --- a/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -154,4 +155,11 @@ int main() test1<S>(); } #endif + +#if TEST_STD_VER > 3 + { // LWG 2946 + std::string s = " !"; + assert(s.rfind({"abc", 1}) == std::string::npos); + } +#endif } |
