From 46b4ad54001bb01f90e01e0a10e367689e8fec54 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 4 Dec 2017 20:11:38 +0000 Subject: [PATCH] Implement P0457R2: 'String Prefix and Suffix Checking' for c++2a git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@319687 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/string | 33 ++++++ include/string_view | 33 ++++++ .../string.ends_with/ends_with.char.pass.cpp | 34 ++++++ .../string.ends_with/ends_with.ptr.pass.cpp | 63 +++++++++++ .../ends_with.string_view.pass.cpp | 72 ++++++++++++ .../string_append/push_back.pass.cpp | 14 +++ .../starts_with.char.pass.cpp | 34 ++++++ .../starts_with.ptr.pass.cpp | 62 +++++++++++ .../starts_with.string_view.pass.cpp | 72 ++++++++++++ .../ends_with.char.pass.cpp | 47 ++++++++ .../ends_with.ptr.pass.cpp | 104 ++++++++++++++++++ .../ends_with.string_view.pass.cpp | 104 ++++++++++++++++++ .../starts_with.char.pass.cpp | 47 ++++++++ .../starts_with.ptr.pass.cpp | 104 ++++++++++++++++++ .../starts_with.string_view.pass.cpp | 104 ++++++++++++++++++ www/cxx2a_status.html | 2 +- 16 files changed, 928 insertions(+), 1 deletion(-) create mode 100644 test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp create mode 100644 test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp create mode 100644 test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp create mode 100644 test/std/strings/basic.string/string.starts_with/starts_with.char.pass.cpp create mode 100644 test/std/strings/basic.string/string.starts_with/starts_with.ptr.pass.cpp create mode 100644 test/std/strings/basic.string/string.starts_with/starts_with.string_view.pass.cpp create mode 100644 test/std/strings/string.view/string.view.template/ends_with.char.pass.cpp create mode 100644 test/std/strings/string.view/string.view.template/ends_with.ptr.pass.cpp create mode 100644 test/std/strings/string.view/string.view.template/ends_with.string_view.pass.cpp create mode 100644 test/std/strings/string.view/string.view.template/starts_with.char.pass.cpp create mode 100644 test/std/strings/string.view/string.view.template/starts_with.ptr.pass.cpp create mode 100644 test/std/strings/string.view/string.view.template/starts_with.string_view.pass.cpp diff --git a/include/string b/include/string index e7142b2b2..f5d548965 100644 --- a/include/string +++ b/include/string @@ -301,6 +301,13 @@ public: int compare(size_type pos1, size_type n1, const value_type* s) const; int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; + bool starts_with(basic_string_view sv) const noexcept; // C++2a + bool starts_with(charT c) const noexcept; // C++2a + bool starts_with(const charT* s) const; // C++2a + bool ends_with(basic_string_view sv) const noexcept; // C++2a + bool ends_with(charT c) const noexcept; // C++2a + bool ends_with(const charT* s) const; // C++2a + bool __invariants() const; }; @@ -1215,6 +1222,32 @@ public: int compare(size_type __pos1, size_type __n1, const value_type* __s) const; int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; +#if _LIBCPP_STD_VER > 17 + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool starts_with(__self_view __sv) const _NOEXCEPT + { return __self_view(data(), size()).starts_with(__sv); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool starts_with(value_type __c) const _NOEXCEPT + { return !empty() && _Traits::eq(front(), __c); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool starts_with(const value_type* __s) const _NOEXCEPT + { return starts_with(__self_view(__s)); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool ends_with(__self_view __sv) const _NOEXCEPT + { return __self_view(data(), size()).ends_with( __sv); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool ends_with(value_type __c) const _NOEXCEPT + { return !empty() && _Traits::eq(back(), __c); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool ends_with(const value_type* __s) const _NOEXCEPT + { return ends_with(__self_view(__s)); } +#endif + _LIBCPP_INLINE_VISIBILITY bool __invariants() const; _LIBCPP_INLINE_VISIBILITY diff --git a/include/string_view b/include/string_view index 4d8e1a931..4d8358288 100644 --- a/include/string_view +++ b/include/string_view @@ -143,6 +143,13 @@ namespace std { constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const; + constexpr bool starts_with(basic_string_view s) const noexcept; // C++2a + constexpr bool starts_with(charT c) const noexcept; // C++2a + constexpr bool starts_with(const charT* s) const; // C++2a + constexpr bool ends_with(basic_string_view s) const noexcept; // C++2a + constexpr bool ends_with(charT c) const noexcept; // C++2a + constexpr bool ends_with(const charT* s) const; // C++2a + private: const_pointer data_; // exposition only size_type size_; // exposition only @@ -565,6 +572,32 @@ public: (data(), size(), __s, __pos, traits_type::length(__s)); } +#if _LIBCPP_STD_VER > 17 + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool starts_with(basic_string_view __s) const _NOEXCEPT + { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool starts_with(value_type __c) const _NOEXCEPT + { return !empty() && _Traits::eq(front(), __c); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool starts_with(const value_type* __s) const _NOEXCEPT + { return starts_with(basic_string_view(__s)); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool ends_with(basic_string_view __s) const _NOEXCEPT + { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool ends_with(value_type __c) const _NOEXCEPT + { return !empty() && _Traits::eq(back(), __c); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool ends_with(const value_type* __s) const _NOEXCEPT + { return ends_with(basic_string_view(__s)); } +#endif + private: const value_type* __data; size_type __size; diff --git a/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp b/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp new file mode 100644 index 000000000..6091e0c06 --- /dev/null +++ b/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++17 + +// + +// bool ends_with(charT x) const noexcept; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + S s1 {}; + S s2 { "abcde", 5 }; + + ASSERT_NOEXCEPT(s1.ends_with('e')); + + assert (!s1.ends_with('e')); + assert (!s1.ends_with('x')); + assert ( s2.ends_with('e')); + assert (!s2.ends_with('x')); + } +} diff --git a/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp b/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp new file mode 100644 index 000000000..fc28bcd30 --- /dev/null +++ b/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++17 + +// + +// bool ends_with(const CharT *x) const; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + const char *s = "abcde"; + + S s0; + S s1 { s + 4, 1 }; + S s2 { s + 3, 2 }; +// S s3 { s + 2, 3 }; +// S s4 { s + 1, 4 }; +// S s5 { s, 5 }; + S sNot { "def", 3 }; + + LIBCPP_ASSERT_NOEXCEPT(s0.ends_with("")); + + assert ( s0.ends_with("")); + assert (!s0.ends_with("e")); + + assert ( s1.ends_with("")); + assert ( s1.ends_with("e")); + assert (!s1.ends_with("de")); + assert (!s1.ends_with("cde")); + assert (!s1.ends_with("bcde")); + assert (!s1.ends_with("abcde")); + assert (!s1.ends_with("def")); + + assert ( s2.ends_with("")); + assert ( s2.ends_with("e")); + assert ( s2.ends_with("de")); + assert (!s2.ends_with("cde")); + assert (!s2.ends_with("bcde")); + assert (!s2.ends_with("abcde")); + assert (!s2.ends_with("def")); + + assert ( sNot.ends_with("")); + assert (!sNot.ends_with("e")); + assert (!sNot.ends_with("de")); + assert (!sNot.ends_with("cde")); + assert (!sNot.ends_with("bcde")); + assert (!sNot.ends_with("abcde")); + assert ( sNot.ends_with("def")); + } +} diff --git a/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp b/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp new file mode 100644 index 000000000..0708dffb4 --- /dev/null +++ b/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++17 + +// + +// bool ends_with(basic_string_view x) const noexcept; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + const char *s = "abcde"; + + S s0; + S s1 { s + 4, 1 }; + S s2 { s + 3, 2 }; +// S s3 { s + 2, 3 }; +// S s4 { s + 1, 4 }; +// S s5 { s, 5 }; + S sNot { "def", 3 }; + + SV sv0; + SV sv1 { s + 4, 1 }; + SV sv2 { s + 3, 2 }; + SV sv3 { s + 2, 3 }; + SV sv4 { s + 1, 4 }; + SV sv5 { s , 5 }; + SV svNot {"def", 3 }; + + ASSERT_NOEXCEPT(s0.ends_with(sv0)); + + assert ( s0.ends_with(sv0)); + assert (!s0.ends_with(sv1)); + + assert ( s1.ends_with(sv0)); + assert ( s1.ends_with(sv1)); + assert (!s1.ends_with(sv2)); + assert (!s1.ends_with(sv3)); + assert (!s1.ends_with(sv4)); + assert (!s1.ends_with(sv5)); + assert (!s1.ends_with(svNot)); + + assert ( s2.ends_with(sv0)); + assert ( s2.ends_with(sv1)); + assert ( s2.ends_with(sv2)); + assert (!s2.ends_with(sv3)); + assert (!s2.ends_with(sv4)); + assert (!s2.ends_with(sv5)); + assert (!s2.ends_with(svNot)); + + assert ( sNot.ends_with(sv0)); + assert (!sNot.ends_with(sv1)); + assert (!sNot.ends_with(sv2)); + assert (!sNot.ends_with(sv3)); + assert (!sNot.ends_with(sv4)); + assert (!sNot.ends_with(sv5)); + assert ( sNot.ends_with(svNot)); + } +} 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 f2fb8782a..de0a02392 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 @@ -17,6 +17,12 @@ #include "test_macros.h" #include "min_allocator.h" +struct veryLarge +{ + long long a; + char b; +}; + template void test(S s, typename S::value_type c, S expected) @@ -42,4 +48,12 @@ int main() test(S("12345678901234567890"), 'a', S("12345678901234567890a")); } #endif + { +// https://bugs.llvm.org/show_bug.cgi?id=31454 + std::basic_string s; + veryLarge vl; + s.push_back(vl); + s.push_back(vl); + s.push_back(vl); + } } diff --git a/test/std/strings/basic.string/string.starts_with/starts_with.char.pass.cpp b/test/std/strings/basic.string/string.starts_with/starts_with.char.pass.cpp new file mode 100644 index 000000000..4be35a765 --- /dev/null +++ b/test/std/strings/basic.string/string.starts_with/starts_with.char.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++17 + +// + +// bool starts_with(charT x) const noexcept; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + S s1 {}; + S s2 { "abcde", 5 }; + + ASSERT_NOEXCEPT(s1.starts_with('e')); + + assert (!s1.starts_with('a')); + assert (!s1.starts_with('x')); + assert ( s2.starts_with('a')); + assert (!s2.starts_with('x')); + } +} diff --git a/test/std/strings/basic.string/string.starts_with/starts_with.ptr.pass.cpp b/test/std/strings/basic.string/string.starts_with/starts_with.ptr.pass.cpp new file mode 100644 index 000000000..5dec2156e --- /dev/null +++ b/test/std/strings/basic.string/string.starts_with/starts_with.ptr.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++17 + +// + +// bool starts_with(const CharT *x) const; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + const char *s = "abcde"; + S s0 {}; + S s1 { s, 1 }; + S s2 { s, 2 }; +// S s3 { s, 3 }; +// S s4 { s, 4 }; +// S s5 { s, 5 }; + S sNot {"def", 3 }; + + LIBCPP_ASSERT_NOEXCEPT(s0.starts_with("")); + + assert ( s0.starts_with("")); + assert (!s0.starts_with("a")); + + assert ( s1.starts_with("")); + assert ( s1.starts_with("a")); + assert (!s1.starts_with("ab")); + assert (!s1.starts_with("abc")); + assert (!s1.starts_with("abcd")); + assert (!s1.starts_with("abcde")); + assert (!s1.starts_with("def")); + + assert ( s2.starts_with("")); + assert ( s2.starts_with("a")); + assert ( s2.starts_with("ab")); + assert (!s2.starts_with("abc")); + assert (!s2.starts_with("abcd")); + assert (!s2.starts_with("abcde")); + assert (!s2.starts_with("def")); + + assert ( sNot.starts_with("")); + assert (!sNot.starts_with("a")); + assert (!sNot.starts_with("ab")); + assert (!sNot.starts_with("abc")); + assert (!sNot.starts_with("abcd")); + assert (!sNot.starts_with("abcde")); + assert ( sNot.starts_with("def")); + } +} diff --git a/test/std/strings/basic.string/string.starts_with/starts_with.string_view.pass.cpp b/test/std/strings/basic.string/string.starts_with/starts_with.string_view.pass.cpp new file mode 100644 index 000000000..2dccd73df --- /dev/null +++ b/test/std/strings/basic.string/string.starts_with/starts_with.string_view.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++17 + +// + +// bool starts_with(string_view x) const noexcept; + +#include +#include + +#include "test_macros.h" + +int main() +{ + { + typedef std::string S; + typedef std::string_view SV; + const char *s = "abcde"; + + S s0; + S s1 { s, 1 }; + S s2 { s, 2 }; +// S s3 { s, 3 }; +// S s4 { s, 4 }; +// S s5 { s, 5 }; + S sNot { "def", 3 }; + + SV sv0; + SV sv1 { s, 1 }; + SV sv2 { s, 2 }; + SV sv3 { s, 3 }; + SV sv4 { s, 4 }; + SV sv5 { s, 5 }; + SV svNot {"def", 3 }; + + ASSERT_NOEXCEPT(s0.starts_with(sv0)); + + assert ( s0.starts_with(sv0)); + assert (!s0.starts_with(sv1)); + + assert ( s1.starts_with(sv0)); + assert ( s1.starts_with(sv1)); + assert (!s1.starts_with(sv2)); + assert (!s1.starts_with(sv3)); + assert (!s1.starts_with(sv4)); + assert (!s1.starts_with(sv5)); + assert (!s1.starts_with(svNot)); + + assert ( s2.starts_with(sv0)); + assert ( s2.starts_with(sv1)); + assert ( s2.starts_with(sv2)); + assert (!s2.starts_with(sv3)); + assert (!s2.starts_with(sv4)); + assert (!s2.starts_with(sv5)); + assert (!s2.starts_with(svNot)); + + assert ( sNot.starts_with(sv0)); + assert (!sNot.starts_with(sv1)); + assert (!sNot.starts_with(sv2)); + assert (!sNot.starts_with(sv3)); + assert (!sNot.starts_with(sv4)); + assert (!sNot.starts_with(sv5)); + assert ( sNot.starts_with(svNot)); + } +} diff --git a/test/std/strings/string.view/string.view.template/ends_with.char.pass.cpp b/test/std/strings/string.view/string.view.template/ends_with.char.pass.cpp new file mode 100644 index 000000000..1511f014b --- /dev/null +++ b/test/std/strings/string.view/string.view.template/ends_with.char.pass.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. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// constexpr bool ends_with(charT x) const noexcept; + +#include +#include + +#include "test_macros.h" +#include "constexpr_char_traits.hpp" + +int main() +{ + { + typedef std::string_view SV; + SV sv1 {}; + SV sv2 { "abcde", 5 }; + + ASSERT_NOEXCEPT(sv1.ends_with('e')); + + assert (!sv1.ends_with('e')); + assert (!sv1.ends_with('x')); + assert ( sv2.ends_with('e')); + assert (!sv2.ends_with('x')); + } + +#if TEST_STD_VER > 11 + { + typedef std::basic_string_view> SV; + constexpr SV sv1 {}; + constexpr SV sv2 { "abcde", 5 }; + static_assert (!sv1.ends_with('e'), "" ); + static_assert (!sv1.ends_with('x'), "" ); + static_assert ( sv2.ends_with('e'), "" ); + static_assert (!sv2.ends_with('x'), "" ); + } +#endif +} diff --git a/test/std/strings/string.view/string.view.template/ends_with.ptr.pass.cpp b/test/std/strings/string.view/string.view.template/ends_with.ptr.pass.cpp new file mode 100644 index 000000000..544cddd84 --- /dev/null +++ b/test/std/strings/string.view/string.view.template/ends_with.ptr.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++17 + +// + +// constexpr bool starts_with(const CharT *x) const; + +#include +#include + +#include "test_macros.h" +#include "constexpr_char_traits.hpp" + +int main() +{ + { + typedef std::string_view SV; + const char *s = "abcde"; + SV sv0 {}; + SV sv1 { s + 4, 1 }; + SV sv2 { s + 3, 2 }; +// SV sv3 { s + 2, 3 }; +// SV sv4 { s + 1, 4 }; +// SV sv5 { s , 5 }; + SV svNot {"def", 3 }; + + LIBCPP_ASSERT_NOEXCEPT(sv0.ends_with("")); + + assert ( sv0.ends_with("")); + assert (!sv0.ends_with("e")); + + assert ( sv1.ends_with("")); + assert ( sv1.ends_with("e")); + assert (!sv1.ends_with("de")); + assert (!sv1.ends_with("cde")); + assert (!sv1.ends_with("bcde")); + assert (!sv1.ends_with("abcde")); + assert (!sv1.ends_with("def")); + + assert ( sv2.ends_with("")); + assert ( sv2.ends_with("e")); + assert ( sv2.ends_with("de")); + assert (!sv2.ends_with("cde")); + assert (!sv2.ends_with("bcde")); + assert (!sv2.ends_with("abcde")); + assert (!sv2.ends_with("def")); + + assert ( svNot.ends_with("")); + assert (!svNot.ends_with("e")); + assert (!svNot.ends_with("de")); + assert (!svNot.ends_with("cde")); + assert (!svNot.ends_with("bcde")); + assert (!svNot.ends_with("abcde")); + assert ( svNot.ends_with("def")); + } + +#if TEST_STD_VER > 11 + { + typedef std::basic_string_view> SV; + constexpr const char *s = "abcde"; + constexpr SV sv0 {}; + constexpr SV sv1 { s + 4, 1 }; + constexpr SV sv2 { s + 3, 2 }; +// constexpr SV sv3 { s + 2, 3 }; +// constexpr SV sv4 { s + 1, 4 }; +// constexpr SV sv5 { s, 5 }; + constexpr SV svNot {"def", 3 }; + + static_assert ( sv0.ends_with(""), "" ); + static_assert (!sv0.ends_with("e"), "" ); + + static_assert ( sv1.ends_with(""), "" ); + static_assert ( sv1.ends_with("e"), "" ); + static_assert (!sv1.ends_with("de"), "" ); + static_assert (!sv1.ends_with("cde"), "" ); + static_assert (!sv1.ends_with("bcde"), "" ); + static_assert (!sv1.ends_with("abcde"), "" ); + static_assert (!sv1.ends_with("def"), "" ); + + static_assert ( sv2.ends_with(""), "" ); + static_assert ( sv2.ends_with("e"), "" ); + static_assert ( sv2.ends_with("de"), "" ); + static_assert (!sv2.ends_with("cde"), "" ); + static_assert (!sv2.ends_with("bcde"), "" ); + static_assert (!sv2.ends_with("abcde"), "" ); + static_assert (!sv2.ends_with("def"), "" ); + + static_assert ( svNot.ends_with(""), "" ); + static_assert (!svNot.ends_with("e"), "" ); + static_assert (!svNot.ends_with("de"), "" ); + static_assert (!svNot.ends_with("cde"), "" ); + static_assert (!svNot.ends_with("bcde"), "" ); + static_assert (!svNot.ends_with("abcde"), "" ); + static_assert ( svNot.ends_with("def"), "" ); + } +#endif +} diff --git a/test/std/strings/string.view/string.view.template/ends_with.string_view.pass.cpp b/test/std/strings/string.view/string.view.template/ends_with.string_view.pass.cpp new file mode 100644 index 000000000..61ea807ba --- /dev/null +++ b/test/std/strings/string.view/string.view.template/ends_with.string_view.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++17 + +// + +// constexpr bool ends_with(string_view x) const noexcept; + +#include +#include + +#include "test_macros.h" +#include "constexpr_char_traits.hpp" + +int main() +{ + { + typedef std::string_view SV; + const char *s = "abcde"; + SV sv0; + SV sv1 { s + 4, 1 }; + SV sv2 { s + 3, 2 }; + SV sv3 { s + 2, 3 }; + SV sv4 { s + 1, 4 }; + SV sv5 { s , 5 }; + SV svNot {"def", 3 }; + + ASSERT_NOEXCEPT(sv0.ends_with(sv0)); + + assert ( sv0.ends_with(sv0)); + assert (!sv0.ends_with(sv1)); + + assert ( sv1.ends_with(sv0)); + assert ( sv1.ends_with(sv1)); + assert (!sv1.ends_with(sv2)); + assert (!sv1.ends_with(sv3)); + assert (!sv1.ends_with(sv4)); + assert (!sv1.ends_with(sv5)); + assert (!sv1.ends_with(svNot)); + + assert ( sv2.ends_with(sv0)); + assert ( sv2.ends_with(sv1)); + assert ( sv2.ends_with(sv2)); + assert (!sv2.ends_with(sv3)); + assert (!sv2.ends_with(sv4)); + assert (!sv2.ends_with(sv5)); + assert (!sv2.ends_with(svNot)); + + assert ( svNot.ends_with(sv0)); + assert (!svNot.ends_with(sv1)); + assert (!svNot.ends_with(sv2)); + assert (!svNot.ends_with(sv3)); + assert (!svNot.ends_with(sv4)); + assert (!svNot.ends_with(sv5)); + assert ( svNot.ends_with(svNot)); + } + +#if TEST_STD_VER > 11 + { + typedef std::basic_string_view> SV; + constexpr const char *s = "abcde"; + constexpr SV sv0 {}; + constexpr SV sv1 { s + 4, 1 }; + constexpr SV sv2 { s + 3, 2 }; + constexpr SV sv3 { s + 2, 3 }; + constexpr SV sv4 { s + 1, 4 }; + constexpr SV sv5 { s, 5 }; + constexpr SV svNot {"def", 3 }; + + static_assert ( sv0.ends_with(sv0), "" ); + static_assert (!sv0.ends_with(sv1), "" ); + + static_assert ( sv1.ends_with(sv0), "" ); + static_assert ( sv1.ends_with(sv1), "" ); + static_assert (!sv1.ends_with(sv2), "" ); + static_assert (!sv1.ends_with(sv3), "" ); + static_assert (!sv1.ends_with(sv4), "" ); + static_assert (!sv1.ends_with(sv5), "" ); + static_assert (!sv1.ends_with(svNot), "" ); + + static_assert ( sv2.ends_with(sv0), "" ); + static_assert ( sv2.ends_with(sv1), "" ); + static_assert ( sv2.ends_with(sv2), "" ); + static_assert (!sv2.ends_with(sv3), "" ); + static_assert (!sv2.ends_with(sv4), "" ); + static_assert (!sv2.ends_with(sv5), "" ); + static_assert (!sv2.ends_with(svNot), "" ); + + static_assert ( svNot.ends_with(sv0), "" ); + static_assert (!svNot.ends_with(sv1), "" ); + static_assert (!svNot.ends_with(sv2), "" ); + static_assert (!svNot.ends_with(sv3), "" ); + static_assert (!svNot.ends_with(sv4), "" ); + static_assert (!svNot.ends_with(sv5), "" ); + static_assert ( svNot.ends_with(svNot), "" ); + } +#endif +} diff --git a/test/std/strings/string.view/string.view.template/starts_with.char.pass.cpp b/test/std/strings/string.view/string.view.template/starts_with.char.pass.cpp new file mode 100644 index 000000000..042aea601 --- /dev/null +++ b/test/std/strings/string.view/string.view.template/starts_with.char.pass.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. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// + +// constexpr bool starts_with(charT x) const noexcept; + +#include +#include + +#include "test_macros.h" +#include "constexpr_char_traits.hpp" + +int main() +{ + { + typedef std::string_view SV; + SV sv1 {}; + SV sv2 { "abcde", 5 }; + + ASSERT_NOEXCEPT(sv1.starts_with('e')); + + assert (!sv1.starts_with('a')); + assert (!sv1.starts_with('x')); + assert ( sv2.starts_with('a')); + assert (!sv2.starts_with('x')); + } + +#if TEST_STD_VER > 11 + { + typedef std::basic_string_view> SV; + constexpr SV sv1 {}; + constexpr SV sv2 { "abcde", 5 }; + static_assert (!sv1.starts_with('a'), "" ); + static_assert (!sv1.starts_with('x'), "" ); + static_assert ( sv2.starts_with('a'), "" ); + static_assert (!sv2.starts_with('x'), "" ); + } +#endif +} diff --git a/test/std/strings/string.view/string.view.template/starts_with.ptr.pass.cpp b/test/std/strings/string.view/string.view.template/starts_with.ptr.pass.cpp new file mode 100644 index 000000000..baaa4c973 --- /dev/null +++ b/test/std/strings/string.view/string.view.template/starts_with.ptr.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++17 + +// + +// constexpr bool starts_with(string_view x) const noexcept; + +#include +#include + +#include "test_macros.h" +#include "constexpr_char_traits.hpp" + +int main() +{ + { + typedef std::string_view SV; + const char *s = "abcde"; + SV sv0 {}; + SV sv1 { s, 1 }; + SV sv2 { s, 2 }; +// SV sv3 { s, 3 }; +// SV sv4 { s, 4 }; +// SV sv5 { s, 5 }; + SV svNot {"def", 3 }; + + LIBCPP_ASSERT_NOEXCEPT(sv0.starts_with("")); + + assert ( sv0.starts_with("")); + assert (!sv0.starts_with("a")); + + assert ( sv1.starts_with("")); + assert ( sv1.starts_with("a")); + assert (!sv1.starts_with("ab")); + assert (!sv1.starts_with("abc")); + assert (!sv1.starts_with("abcd")); + assert (!sv1.starts_with("abcde")); + assert (!sv1.starts_with("def")); + + assert ( sv2.starts_with(s + 5)); + assert ( sv2.starts_with("a")); + assert ( sv2.starts_with("ab")); + assert (!sv2.starts_with("abc")); + assert (!sv2.starts_with("abcd")); + assert (!sv2.starts_with("abcde")); + assert (!sv2.starts_with("def")); + + assert ( svNot.starts_with("")); + assert (!svNot.starts_with("a")); + assert (!svNot.starts_with("ab")); + assert (!svNot.starts_with("abc")); + assert (!svNot.starts_with("abcd")); + assert (!svNot.starts_with("abcde")); + assert ( svNot.starts_with("def")); + } + +#if TEST_STD_VER > 11 + { + typedef std::basic_string_view> SV; + constexpr const char *s = "abcde"; + constexpr SV sv0 {}; + constexpr SV sv1 { s, 1 }; + constexpr SV sv2 { s, 2 }; +// constexpr SV sv3 { s, 3 }; +// constexpr SV sv4 { s, 4 }; +// constexpr SV sv5 { s, 5 }; + constexpr SV svNot {"def", 3 }; + + static_assert ( sv0.starts_with(""), "" ); + static_assert (!sv0.starts_with("a"), "" ); + + static_assert ( sv1.starts_with(""), "" ); + static_assert ( sv1.starts_with("a"), "" ); + static_assert (!sv1.starts_with("ab"), "" ); + static_assert (!sv1.starts_with("abc"), "" ); + static_assert (!sv1.starts_with("abcd"), "" ); + static_assert (!sv1.starts_with("abcde"), "" ); + static_assert (!sv1.starts_with("def"), "" ); + + static_assert ( sv2.starts_with(s + 5), "" ); + static_assert ( sv2.starts_with("a"), "" ); + static_assert ( sv2.starts_with("ab"), "" ); + static_assert (!sv2.starts_with("abc"), "" ); + static_assert (!sv2.starts_with("abcd"), "" ); + static_assert (!sv2.starts_with("abcde"), "" ); + static_assert (!sv2.starts_with("def"), "" ); + + static_assert ( svNot.starts_with(""), "" ); + static_assert (!svNot.starts_with("a"), "" ); + static_assert (!svNot.starts_with("ab"), "" ); + static_assert (!svNot.starts_with("abc"), "" ); + static_assert (!svNot.starts_with("abcd"), "" ); + static_assert (!svNot.starts_with("abcde"), "" ); + static_assert ( svNot.starts_with("def"), "" ); + } +#endif +} diff --git a/test/std/strings/string.view/string.view.template/starts_with.string_view.pass.cpp b/test/std/strings/string.view/string.view.template/starts_with.string_view.pass.cpp new file mode 100644 index 000000000..7501926af --- /dev/null +++ b/test/std/strings/string.view/string.view.template/starts_with.string_view.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++17 + +// + +// constexpr bool starts_with(string_view x) const noexcept; + +#include +#include + +#include "test_macros.h" +#include "constexpr_char_traits.hpp" + +int main() +{ + { + typedef std::string_view SV; + const char *s = "abcde"; + SV sv0 {}; + SV sv1 { s, 1 }; + SV sv2 { s, 2 }; + SV sv3 { s, 3 }; + SV sv4 { s, 4 }; + SV sv5 { s, 5 }; + SV svNot {"def", 3 }; + + ASSERT_NOEXCEPT(sv0.starts_with(sv0)); + + assert ( sv0.starts_with(sv0)); + assert (!sv0.starts_with(sv1)); + + assert ( sv1.starts_with(sv0)); + assert ( sv1.starts_with(sv1)); + assert (!sv1.starts_with(sv2)); + assert (!sv1.starts_with(sv3)); + assert (!sv1.starts_with(sv4)); + assert (!sv1.starts_with(sv5)); + assert (!sv1.starts_with(svNot)); + + assert ( sv2.starts_with(sv0)); + assert ( sv2.starts_with(sv1)); + assert ( sv2.starts_with(sv2)); + assert (!sv2.starts_with(sv3)); + assert (!sv2.starts_with(sv4)); + assert (!sv2.starts_with(sv5)); + assert (!sv2.starts_with(svNot)); + + assert ( svNot.starts_with(sv0)); + assert (!svNot.starts_with(sv1)); + assert (!svNot.starts_with(sv2)); + assert (!svNot.starts_with(sv3)); + assert (!svNot.starts_with(sv4)); + assert (!svNot.starts_with(sv5)); + assert ( svNot.starts_with(svNot)); + } + +#if TEST_STD_VER > 11 + { + typedef std::basic_string_view> SV; + constexpr const char *s = "abcde"; + constexpr SV sv0 {}; + constexpr SV sv1 { s, 1 }; + constexpr SV sv2 { s, 2 }; + constexpr SV sv3 { s, 3 }; + constexpr SV sv4 { s, 4 }; + constexpr SV sv5 { s, 5 }; + constexpr SV svNot {"def", 3 }; + + static_assert ( sv0.starts_with(sv0), "" ); + static_assert (!sv0.starts_with(sv1), "" ); + + static_assert ( sv1.starts_with(sv0), "" ); + static_assert ( sv1.starts_with(sv1), "" ); + static_assert (!sv1.starts_with(sv2), "" ); + static_assert (!sv1.starts_with(sv3), "" ); + static_assert (!sv1.starts_with(sv4), "" ); + static_assert (!sv1.starts_with(sv5), "" ); + static_assert (!sv1.starts_with(svNot), "" ); + + static_assert ( sv2.starts_with(sv0), "" ); + static_assert ( sv2.starts_with(sv1), "" ); + static_assert ( sv2.starts_with(sv2), "" ); + static_assert (!sv2.starts_with(sv3), "" ); + static_assert (!sv2.starts_with(sv4), "" ); + static_assert (!sv2.starts_with(sv5), "" ); + static_assert (!sv2.starts_with(svNot), "" ); + + static_assert ( svNot.starts_with(sv0), "" ); + static_assert (!svNot.starts_with(sv1), "" ); + static_assert (!svNot.starts_with(sv2), "" ); + static_assert (!svNot.starts_with(sv3), "" ); + static_assert (!svNot.starts_with(sv4), "" ); + static_assert (!svNot.starts_with(sv5), "" ); + static_assert ( svNot.starts_with(svNot), "" ); + } +#endif +} diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html index 92ed9a5d9..9e45c3de1 100644 --- a/www/cxx2a_status.html +++ b/www/cxx2a_status.html @@ -63,7 +63,7 @@ P0202R3LWGAdd constexpr modifiers to functions in <algorithm> and <utility> HeadersAlbuquerque P0415R1LWGConstexpr for std::complexAlbuquerque P0439R0LWGMake std::memory_order a scoped enumerationAlbuquerque - P0457R2LWGString Prefix and Suffix CheckingAlbuquerque + P0457R2LWGString Prefix and Suffix CheckingAlbuquerqueComplete6.0 P0550R2LWGTransformation Trait remove_cvrefAlbuquerqueComplete6.0 P0600R1LWGnodiscard in the LibraryAlbuquerqueIn Progress P0616R0LWGde-pessimize legacy algorithms with std::moveAlbuquerque