Index: include/string =================================================================== --- include/string +++ include/string @@ -301,6 +301,13 @@ 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 @@ 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 Index: include/string_view =================================================================== --- include/string_view +++ include/string_view @@ -143,6 +143,13 @@ 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 @@ (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; Index: test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp +++ 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')); + } +} Index: test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp +++ 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")); + } +} Index: test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp =================================================================== --- test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp +++ 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)); + } +} Index: test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp =================================================================== --- test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp +++ 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 @@ 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); + } } Index: test/std/strings/basic.string/string.starts_with/starts_with.char.pass.cpp =================================================================== --- test/std/strings/basic.string/string.starts_with/starts_with.char.pass.cpp +++ 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')); + } +} Index: test/std/strings/basic.string/string.starts_with/starts_with.ptr.pass.cpp =================================================================== --- test/std/strings/basic.string/string.starts_with/starts_with.ptr.pass.cpp +++ 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")); + } +} Index: test/std/strings/basic.string/string.starts_with/starts_with.string_view.pass.cpp =================================================================== --- test/std/strings/basic.string/string.starts_with/starts_with.string_view.pass.cpp +++ 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)); + } +} Index: test/std/strings/string.view/string.view.template/ends_with.char.pass.cpp =================================================================== --- test/std/strings/string.view/string.view.template/ends_with.char.pass.cpp +++ 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 +} Index: test/std/strings/string.view/string.view.template/ends_with.ptr.pass.cpp =================================================================== --- test/std/strings/string.view/string.view.template/ends_with.ptr.pass.cpp +++ 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 +} Index: test/std/strings/string.view/string.view.template/ends_with.string_view.pass.cpp =================================================================== --- test/std/strings/string.view/string.view.template/ends_with.string_view.pass.cpp +++ 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 +} Index: test/std/strings/string.view/string.view.template/starts_with.char.pass.cpp =================================================================== --- test/std/strings/string.view/string.view.template/starts_with.char.pass.cpp +++ 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 +} Index: test/std/strings/string.view/string.view.template/starts_with.ptr.pass.cpp =================================================================== --- test/std/strings/string.view/string.view.template/starts_with.ptr.pass.cpp +++ 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 +} Index: test/std/strings/string.view/string.view.template/starts_with.string_view.pass.cpp =================================================================== --- test/std/strings/string.view/string.view.template/starts_with.string_view.pass.cpp +++ 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 +}