diff options
Diffstat (limited to 'test/std/strings')
30 files changed, 727 insertions, 51 deletions
diff --git a/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp b/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp new file mode 100644 index 000000000000..01f01218999d --- /dev/null +++ b/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <string> + +// Test that <string> provides all of the arithmetic, enum, and pointer +// hash specializations. + +#include <string> + +#include "poisoned_hash_helper.hpp" + +int main() { + test_library_hash_specializations_available(); + { + test_hash_enabled_for_type<std::string>(); + test_hash_enabled_for_type<std::wstring>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test_hash_enabled_for_type<std::u16string>(); + test_hash_enabled_for_type<std::u32string>(); +#endif + } +} diff --git a/test/std/strings/basic.string.hash/strings.pass.cpp b/test/std/strings/basic.string.hash/strings.pass.cpp index 5fc32c06a701..d74e485752fc 100644 --- a/test/std/strings/basic.string.hash/strings.pass.cpp +++ b/test/std/strings/basic.string.hash/strings.pass.cpp @@ -22,6 +22,8 @@ #include <cassert> #include <type_traits> +#include "test_macros.h" + template <class T> void test() @@ -29,6 +31,8 @@ test() typedef std::hash<T> H; static_assert((std::is_same<typename H::argument_type, T>::value), "" ); static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); + ASSERT_NOEXCEPT(H()(T())); + H h; std::string g1 = "1234567890"; std::string g2 = "1234567891"; diff --git a/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp index b3447b94b803..982bb43289d7 100644 --- a/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp @@ -18,6 +18,65 @@ #include "test_allocator.h" #include "min_allocator.h" +#ifndef TEST_HAS_NO_EXCEPTIONS +template <class T> +struct alloc_imp { + bool active; + + alloc_imp() : active(true) {} + + T* allocate(std::size_t n) + { + if (active) + return static_cast<T*>(std::malloc(n * sizeof(T))); + else + throw std::bad_alloc(); + } + + void deallocate(T* p, std::size_t) { std::free(p); } + void activate () { active = true; } + void deactivate() { active = false; } +}; + +template <class T> +struct poca_alloc { + typedef T value_type; + typedef std::true_type propagate_on_container_copy_assignment; + + alloc_imp<T> *imp; + + poca_alloc(alloc_imp<T> *imp_) : imp (imp_) {} + + template <class U> + poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {} + + T* allocate (std::size_t n) { return imp->allocate(n);} + void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); } +}; + +template <typename T, typename U> +bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) +{ + return lhs.imp == rhs.imp; +} + +template <typename T, typename U> +bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) +{ + return lhs.imp != rhs.imp; +} + +template <class S> +void test_assign(S &s1, const S& s2) +{ + try { s1 = s2; } + catch ( std::bad_alloc &) { return; } + assert(false); +} +#endif + + + template <class S> void test(S s1, const typename S::allocator_type& a) @@ -46,5 +105,27 @@ int main() test(S("1"), A()); test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A()); } + +#ifndef TEST_HAS_NO_EXCEPTIONS + { + typedef poca_alloc<char> A; + typedef std::basic_string<char, std::char_traits<char>, A> S; + const char * p1 = "This is my first string"; + const char * p2 = "This is my second string"; + + alloc_imp<char> imp1; + alloc_imp<char> imp2; + S s1(p1, A(&imp1)); + S s2(p2, A(&imp2)); + + assert(s1 == p1); + assert(s2 == p2); + + imp2.deactivate(); + test_assign(s1, s2); + assert(s1 == p1); + assert(s2 == p2); + } +#endif #endif } 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 0c6362d96863..f4ff0645afcf 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 @@ -42,8 +42,10 @@ int main() typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> C; static_assert(std::is_nothrow_destructible<C>::value, ""); } +#if defined(_LIBCPP_VERSION) { typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C; - LIBCPP_STATIC_ASSERT(!std::is_nothrow_destructible<C>::value, ""); + 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 new file mode 100644 index 000000000000..0fbd663db4bc --- /dev/null +++ b/test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp @@ -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. + } +} 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 1b10224cd9e7..1f83696891c4 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 @@ -29,7 +29,6 @@ test(It first, It last) { typedef typename std::iterator_traits<It>::value_type charT; typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S; - typedef typename S::traits_type T; typedef typename S::allocator_type A; S s2(first, last); LIBCPP_ASSERT(s2.__invariants()); @@ -47,7 +46,6 @@ test(It first, It last, const A& a) { typedef typename std::iterator_traits<It>::value_type charT; typedef std::basic_string<charT, std::char_traits<charT>, A> S; - typedef typename S::traits_type T; S s2(first, last, a); LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == static_cast<std::size_t>(std::distance(first, last))); diff --git a/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp index f56780095b7f..d9d451dc7112 100644 --- a/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp @@ -56,7 +56,6 @@ int main() { { typedef test_allocator<char> A; - typedef std::basic_string<char, std::char_traits<char>, A> S; test(""); test("", A(2)); @@ -73,7 +72,6 @@ int main() #if TEST_STD_VER >= 11 { typedef min_allocator<char> A; - typedef std::basic_string<char, std::char_traits<char>, A> S; test(""); test("", A()); 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 bcab9eb6789e..3c75a700eaed 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 @@ -53,7 +53,6 @@ int main() { { typedef test_allocator<char> A; - typedef std::basic_string<char, std::char_traits<char>, A> S; test("", 0); test("", 0, A(2)); @@ -70,7 +69,6 @@ int main() #if TEST_STD_VER >= 11 { typedef min_allocator<char> A; - typedef std::basic_string<char, std::char_traits<char>, A> S; test("", 0); test("", 0, A()); diff --git a/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp index 60443e9f358d..2adf0049a0b5 100644 --- a/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp @@ -26,7 +26,6 @@ void test(unsigned n, charT c) { typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S; - typedef typename S::traits_type T; typedef typename S::allocator_type A; S s2(n, c); LIBCPP_ASSERT(s2.__invariants()); @@ -42,7 +41,6 @@ void test(unsigned n, charT c, const A& a) { typedef std::basic_string<charT, std::char_traits<charT>, A> S; - typedef typename S::traits_type T; S s2(n, c, a); LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == n); @@ -58,7 +56,6 @@ test(Tp n, Tp c) { typedef char charT; typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S; - typedef typename S::traits_type T; typedef typename S::allocator_type A; S s2(n, c); LIBCPP_ASSERT(s2.__invariants()); @@ -75,7 +72,6 @@ test(Tp n, Tp c, const A& a) { typedef char charT; typedef std::basic_string<charT, std::char_traits<charT>, A> S; - typedef typename S::traits_type T; S s2(n, c, a); LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == static_cast<std::size_t>(n)); @@ -89,7 +85,6 @@ int main() { { typedef test_allocator<char> A; - typedef std::basic_string<char, std::char_traits<char>, A> S; test(0, 'a'); test(0, 'a', A(2)); @@ -109,7 +104,6 @@ int main() #if TEST_STD_VER >= 11 { typedef min_allocator<char> A; - typedef std::basic_string<char, std::char_traits<char>, A> S; test(0, 'a'); test(0, 'a', A()); diff --git a/test/std/strings/basic.string/string.cons/substr.pass.cpp b/test/std/strings/basic.string/string.cons/substr.pass.cpp index 4fd974273de9..13a9a4b96aab 100644 --- a/test/std/strings/basic.string/string.cons/substr.pass.cpp +++ b/test/std/strings/basic.string/string.cons/substr.pass.cpp @@ -98,7 +98,6 @@ void test(S str, unsigned pos, unsigned n, const typename S::allocator_type& a) { typedef typename S::traits_type T; - typedef typename S::allocator_type A; if (pos <= str.size()) { diff --git a/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp index dac8860f9a64..b464291d4c5d 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp @@ -204,4 +204,20 @@ int main() assert(s == "ABCD"); } + { // test with a move iterator that returns char&& + typedef forward_iterator<const char*> It; + typedef std::move_iterator<It> MoveIt; + const char p[] = "ABCD"; + std::string s; + s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); + assert(s == "ABCD"); + } + { // test with a move iterator that returns char&& + typedef const char* It; + typedef std::move_iterator<It> MoveIt; + const char p[] = "ABCD"; + std::string s; + s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); + assert(s == "ABCD"); + } } diff --git a/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp index e5ce8e51e1d6..2c8b6e4a1882 100644 --- a/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp @@ -188,10 +188,35 @@ int main() { // test assigning a different type typedef std::string S; - const uint8_t p[] = "ABCD"; + const uint8_t p[] = "ABCD"; - S s; - s.insert(s.begin(), p, p + 4); - assert(s == "ABCD"); + S s; + s.insert(s.begin(), p, p + 4); + assert(s == "ABCD"); } + + { // test with a move iterator that returns char&& + typedef input_iterator<const char*> It; + typedef std::move_iterator<It> MoveIt; + const char p[] = "ABCD"; + std::string s; + s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); + assert(s == "ABCD"); + } + { // test with a move iterator that returns char&& + typedef forward_iterator<const char*> It; + typedef std::move_iterator<It> MoveIt; + const char p[] = "ABCD"; + std::string s; + s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); + assert(s == "ABCD"); + } + { // test with a move iterator that returns char&& + typedef const char* It; + typedef std::move_iterator<It> MoveIt; + const char p[] = "ABCD"; + std::string s; + s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); + assert(s == "ABCD"); + } } diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp index 840b7614f482..dbf5f5b64446 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp @@ -29,16 +29,22 @@ test(S s, typename S::size_type pos1, typename S::size_type n1, SV sv, typename S::size_type pos2, typename S::size_type n2, S expected) { + typedef typename S::size_type SizeT; static_assert((!std::is_same<S, SV>::value), ""); - const typename S::size_type old_size = s.size(); + + // String and string_view may not always share the same size type, + // but both types should have the same size (ex. int vs long) + static_assert(sizeof(SizeT) == sizeof(typename SV::size_type), ""); + + const SizeT old_size = s.size(); S s0 = s; if (pos1 <= old_size && pos2 <= sv.size()) { s.replace(pos1, n1, sv, pos2, n2); LIBCPP_ASSERT(s.__invariants()); assert(s == expected); - typename S::size_type xlen = std::min(n1, old_size - pos1); - typename S::size_type rlen = std::min(n2, sv.size() - pos2); + SizeT xlen = std::min<SizeT>(n1, old_size - pos1); + SizeT rlen = std::min<SizeT>(n2, sv.size() - pos2); assert(s.size() == old_size - xlen + rlen); } #ifndef TEST_HAS_NO_EXCEPTIONS @@ -64,16 +70,17 @@ test_npos(S s, typename S::size_type pos1, typename S::size_type n1, SV sv, typename S::size_type pos2, S expected) { + typedef typename S::size_type SizeT; static_assert((!std::is_same<S, SV>::value), ""); - const typename S::size_type old_size = s.size(); + const SizeT old_size = s.size(); S s0 = s; if (pos1 <= old_size && pos2 <= sv.size()) { s.replace(pos1, n1, sv, pos2); LIBCPP_ASSERT(s.__invariants()); assert(s == expected); - typename S::size_type xlen = std::min(n1, old_size - pos1); - typename S::size_type rlen = std::min(S::npos, sv.size() - pos2); + SizeT xlen = std::min<SizeT>(n1, old_size - pos1); + SizeT rlen = std::min<SizeT>(S::npos, sv.size() - pos2); assert(s.size() == old_size - xlen + rlen); } #ifndef TEST_HAS_NO_EXCEPTIONS 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 757d5eeb2dc3..88c1bee32512 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 @@ -59,10 +59,12 @@ int main() typedef std::string C; static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); } +#if defined(_LIBCPP_VERSION) { typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> C; - LIBCPP_STATIC_ASSERT(noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); + static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); } +#endif // _LIBCPP_VERSION { typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C; #if TEST_STD_VER >= 14 diff --git a/test/std/strings/basic.string/traits_mismatch.fail.cpp b/test/std/strings/basic.string/traits_mismatch.fail.cpp new file mode 100644 index 000000000000..1d54238ae0c0 --- /dev/null +++ b/test/std/strings/basic.string/traits_mismatch.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// 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> +// The strings's value type must be the same as the traits's char_type + +#include <string> + +int main() +{ + std::basic_string<char, std::char_traits<wchar_t>> s; +} diff --git a/test/std/strings/string.classes/typedefs.pass.cpp b/test/std/strings/string.classes/typedefs.pass.cpp index 11ee6c8a1215..3aba1c3f15dd 100644 --- a/test/std/strings/string.classes/typedefs.pass.cpp +++ b/test/std/strings/string.classes/typedefs.pass.cpp @@ -18,13 +18,14 @@ // typedef basic_string<wchar_t> wstring; #include <string> +#include <type_traits> int main() { - typedef std::string test1; - typedef std::wstring test2; + static_assert((std::is_same<std::string, std::basic_string<char> >::value), ""); + static_assert((std::is_same<std::wstring, std::basic_string<wchar_t> >::value), ""); #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - typedef std::u16string test3; - typedef std::u32string test4; + static_assert((std::is_same<std::u16string, std::basic_string<char16_t> >::value), ""); + static_assert((std::is_same<std::u32string, std::basic_string<char32_t> >::value), ""); #endif // _LIBCPP_HAS_NO_UNICODE_CHARS } diff --git a/test/std/strings/string.conversions/stof.pass.cpp b/test/std/strings/string.conversions/stof.pass.cpp index 1e17e1d3abdd..aeef0ddfbc78 100644 --- a/test/std/strings/string.conversions/stof.pass.cpp +++ b/test/std/strings/string.conversions/stof.pass.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 -// XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// XFAIL: with_system_cxx_lib=x86_64-apple-macosx10.7 +// XFAIL: with_system_cxx_lib=x86_64-apple-macosx10.8 // <string> diff --git a/test/std/strings/string.conversions/stol.pass.cpp b/test/std/strings/string.conversions/stol.pass.cpp index 457cf0a76997..f01bbf8ce29e 100644 --- a/test/std/strings/string.conversions/stol.pass.cpp +++ b/test/std/strings/string.conversions/stol.pass.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 -// XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// XFAIL: with_system_cxx_lib=x86_64-apple-macosx10.7 +// XFAIL: with_system_cxx_lib=x86_64-apple-macosx10.8 // <string> diff --git a/test/std/strings/string.conversions/stoll.pass.cpp b/test/std/strings/string.conversions/stoll.pass.cpp index ca8412aeb758..b823ab742626 100644 --- a/test/std/strings/string.conversions/stoll.pass.cpp +++ b/test/std/strings/string.conversions/stoll.pass.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 -// XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// XFAIL: with_system_cxx_lib=x86_64-apple-macosx10.7 +// XFAIL: with_system_cxx_lib=x86_64-apple-macosx10.8 // <string> diff --git a/test/std/strings/string.conversions/stoul.pass.cpp b/test/std/strings/string.conversions/stoul.pass.cpp index 1acdf116458f..5e1f696cb6b7 100644 --- a/test/std/strings/string.conversions/stoul.pass.cpp +++ b/test/std/strings/string.conversions/stoul.pass.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 -// XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// XFAIL: with_system_cxx_lib=x86_64-apple-macosx10.7 +// XFAIL: with_system_cxx_lib=x86_64-apple-macosx10.8 // <string> diff --git a/test/std/strings/string.conversions/stoull.pass.cpp b/test/std/strings/string.conversions/stoull.pass.cpp index e63679eed2f4..70563d9be51f 100644 --- a/test/std/strings/string.conversions/stoull.pass.cpp +++ b/test/std/strings/string.conversions/stoull.pass.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 -// XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// XFAIL: with_system_cxx_lib=x86_64-apple-macosx10.7 +// XFAIL: with_system_cxx_lib=x86_64-apple-macosx10.8 // <string> diff --git a/test/std/strings/string.view/string.view.access/at.pass.cpp b/test/std/strings/string.view/string.view.access/at.pass.cpp index 0f1636d3f94f..6df879898f44 100644 --- a/test/std/strings/string.view/string.view.access/at.pass.cpp +++ b/test/std/strings/string.view/string.view.access/at.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// NOTE: Older versions of clang have a bug where they fail to evalute +// NOTE: Older versions of clang have a bug where they fail to evaluate // string_view::at as a constant expression. // XFAIL: clang-3.4, clang-3.3 diff --git a/test/std/strings/string.view/string.view.cons/assign.pass.cpp b/test/std/strings/string.view/string.view.cons/assign.pass.cpp new file mode 100644 index 000000000000..b7348ea226cf --- /dev/null +++ b/test/std/strings/string.view/string.view.cons/assign.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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_view> + +// constexpr basic_string_view& operator=(const basic_string_view &) noexcept = default; + +#include <string_view> +#include <cassert> + +#include "test_macros.h" + +template<typename T> +#if TEST_STD_VER > 11 +constexpr +#endif +bool test (T sv0) + { + T sv1; + sv1 = sv0; +// We can't just say "sv0 == sv1" here because string_view::compare +// isn't constexpr until C++17, and we want to support back to C++14 + return sv0.size() == sv1.size() && sv0.data() == sv1.data(); + } + +int main () { + + assert( test<std::string_view> ( "1234")); +#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS + assert( test<std::u16string_view> (u"1234")); + assert( test<std::u32string_view> (U"1234")); +#endif + assert( test<std::wstring_view> (L"1234")); + +#if TEST_STD_VER > 11 + static_assert( test<std::string_view> ({ "abc", 3}), ""); +#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS + static_assert( test<std::u16string_view> ({u"abc", 3}), ""); + static_assert( test<std::u32string_view> ({U"abc", 3}), ""); +#endif + static_assert( test<std::wstring_view> ({L"abc", 3}), ""); +#endif +} diff --git a/test/std/strings/string.view/string.view.cons/implicit_deduction_guides.pass.cpp b/test/std/strings/string.view/string.view.cons/implicit_deduction_guides.pass.cpp new file mode 100644 index 000000000000..7dd99d9c4405 --- /dev/null +++ b/test/std/strings/string.view/string.view.cons/implicit_deduction_guides.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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_view> + +// Test that the constructors offered by std::basic_string_view are formulated +// so they're compatible with implicit deduction guides. + +#include <string_view> +#include <cassert> + +#include "test_macros.h" +#include "constexpr_char_traits.hpp" + +// Overloads +// --------------- +// (1) basic_string_view() - NOT TESTED +// (2) basic_string_view(const basic_string_view&) +// (3) basic_string_view(const CharT*, size_type) +// (4) basic_string_view(const CharT*) +int main() +{ + { // Testing (1) + // Nothing TODO. Cannot deduce without any arguments. + } + { // Testing (2) + const std::string_view sin("abc"); + std::basic_string_view s(sin); + ASSERT_SAME_TYPE(decltype(s), std::string_view); + assert(s == "abc"); + + using WSV = std::basic_string_view<wchar_t, constexpr_char_traits<wchar_t>>; + const WSV win(L"abcdef"); + std::basic_string_view w(win); + ASSERT_SAME_TYPE(decltype(w), WSV); + assert(w == L"abcdef"); + } + { // Testing (3) + std::basic_string_view s("abc", 2); + ASSERT_SAME_TYPE(decltype(s), std::string_view); + assert(s == "ab"); + + std::basic_string_view w(L"abcdef", 4); + ASSERT_SAME_TYPE(decltype(w), std::wstring_view); + assert(w == L"abcd"); + } + { // Testing (4) + std::basic_string_view s("abc"); + ASSERT_SAME_TYPE(decltype(s), std::string_view); + assert(s == "abc"); + + std::basic_string_view w(L"abcdef"); + ASSERT_SAME_TYPE(decltype(w), std::wstring_view); + assert(w == L"abcdef"); + } +} diff --git a/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp b/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp new file mode 100644 index 000000000000..2e9ebcb4c037 --- /dev/null +++ b/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <string_view> + +// Test that <string_view> provides all of the arithmetic, enum, and pointer +// hash specializations. + +#include <string_view> + +#include "poisoned_hash_helper.hpp" + +int main() { + test_library_hash_specializations_available(); + { + test_hash_enabled_for_type<std::string_view>(); + test_hash_enabled_for_type<std::wstring_view>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test_hash_enabled_for_type<std::u16string_view>(); + test_hash_enabled_for_type<std::u32string_view>(); +#endif + } +} diff --git a/test/std/strings/string.view/string.view.hash/string_view.pass.cpp b/test/std/strings/string.view/string.view.hash/string_view.pass.cpp index 63099e2c8864..53c3d261d882 100644 --- a/test/std/strings/string.view/string.view.hash/string_view.pass.cpp +++ b/test/std/strings/string.view/string.view.hash/string_view.pass.cpp @@ -19,29 +19,41 @@ // Not very portable #include <string_view> +#include <string> #include <cassert> #include <type_traits> +#include "test_macros.h" + using std::string_view; -template <class T> +template <class SV> void test() { - typedef std::hash<T> H; - static_assert((std::is_same<typename H::argument_type, T>::value), "" ); + typedef std::hash<SV> H; + static_assert((std::is_same<typename H::argument_type, SV>::value), "" ); static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); - H h; -// std::string g1 = "1234567890"; -// std::string g2 = "1234567891"; - typedef typename T::value_type char_type; + + typedef typename SV::value_type char_type; + typedef std::basic_string<char_type> String; + typedef std::hash<String> SH; + ASSERT_NOEXCEPT(H()(SV())); + char_type g1 [ 10 ]; char_type g2 [ 10 ]; for ( int i = 0; i < 10; ++i ) g1[i] = g2[9-i] = static_cast<char_type>('0' + i); - T s1(g1, 10); - T s2(g2, 10); + H h; + SH sh; + SV s1(g1, 10); + String ss1(s1); + SV s2(g2, 10); + String ss2(s2); + assert(h(s1) == h(s1)); assert(h(s1) != h(s2)); + assert(sh(ss1) == h(s1)); + assert(sh(ss2) == h(s2)); } int main() diff --git a/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp b/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp index 381f792e5ce0..16a4da882739 100644 --- a/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp +++ b/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp @@ -58,4 +58,23 @@ int main() test(u16string_view{u"123"}); test(u32string_view{U"123"}); #endif + +#if TEST_STD_VER > 14 + { + constexpr string_view sv { "123", 3 }; + constexpr u16string_view u16sv {u"123", 3 }; + constexpr u32string_view u32sv {U"123", 3 }; + constexpr wstring_view wsv {L"123", 3 }; + + static_assert ( *sv.rbegin() == sv[2], "" ); + static_assert ( *u16sv.rbegin() == u16sv[2], "" ); + static_assert ( *u32sv.rbegin() == u32sv[2], "" ); + static_assert ( *wsv.rbegin() == wsv[2], "" ); + + static_assert ( *sv.crbegin() == sv[2], "" ); + static_assert ( *u16sv.crbegin() == u16sv[2], "" ); + static_assert ( *u32sv.crbegin() == u32sv[2], "" ); + static_assert ( *wsv.crbegin() == wsv[2], "" ); + } +#endif } diff --git a/test/std/strings/string.view/string.view.iterators/rend.pass.cpp b/test/std/strings/string.view/string.view.iterators/rend.pass.cpp index ca529fb708dc..08f9e5a7755b 100644 --- a/test/std/strings/string.view/string.view.iterators/rend.pass.cpp +++ b/test/std/strings/string.view/string.view.iterators/rend.pass.cpp @@ -66,4 +66,23 @@ int main() test(u16string_view{u"123"}); test(u32string_view{U"123"}); #endif + +#if TEST_STD_VER > 14 + { + constexpr string_view sv { "123", 3 }; + constexpr u16string_view u16sv {u"123", 3 }; + constexpr u32string_view u32sv {U"123", 3 }; + constexpr wstring_view wsv {L"123", 3 }; + + static_assert ( *--sv.rend() == sv[0], "" ); + static_assert ( *--u16sv.rend() == u16sv[0], "" ); + static_assert ( *--u32sv.rend() == u32sv[0], "" ); + static_assert ( *--wsv.rend() == wsv[0], "" ); + + static_assert ( *--sv.crend() == sv[0], "" ); + static_assert ( *--u16sv.crend() == u16sv[0], "" ); + static_assert ( *--u32sv.crend() == u32sv[0], "" ); + static_assert ( *--wsv.crend() == wsv[0], "" ); + } +#endif } diff --git a/test/std/strings/string.view/string_view.literals/literal.pass.cpp b/test/std/strings/string.view/string_view.literals/literal.pass.cpp index 9fb128ab0f55..710009cc51ee 100644 --- a/test/std/strings/string.view/string_view.literals/literal.pass.cpp +++ b/test/std/strings/string.view/string_view.literals/literal.pass.cpp @@ -48,7 +48,7 @@ int main() Lfoo = L"ABC"sv; assert(Lfoo == L"ABC"); assert(Lfoo == std::wstring_view ( L"ABC")); ufoo = u"ABC"sv; assert(ufoo == u"ABC"); assert(ufoo == std::u16string_view( u"ABC")); Ufoo = U"ABC"sv; assert(Ufoo == U"ABC"); assert(Ufoo == std::u32string_view( U"ABC")); - + static_assert( "ABC"sv.size() == 3, ""); static_assert(u8"ABC"sv.size() == 3, ""); static_assert( L"ABC"sv.size() == 3, ""); diff --git a/test/std/strings/string.view/nothing_to_do.pass.cpp b/test/std/strings/string.view/traits_mismatch.fail.cpp index 353dd98f415e..6cd15e6a67ba 100644 --- a/test/std/strings/string.view/nothing_to_do.pass.cpp +++ b/test/std/strings/string.view/traits_mismatch.fail.cpp @@ -7,6 +7,12 @@ // //===----------------------------------------------------------------------===// +// <string_view> +// The string_views's value type must be the same as the traits's char_type + #include <string_view> -int main () {} +int main() +{ + std::basic_string_view<char, std::char_traits<wchar_t>> s; +} |