mclow.lists created this revision.

This adds six calls each to `basic_string` and `basic_string_view`:

- starts_with (3 variants)
- ends_with (3 variants)

This is a C++2a feature


https://reviews.llvm.org/D40586

Files:
  include/string
  include/string_view
  test/std/strings/basic.string/string.ends_with/ends_with.char.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.string_view.pass.cpp
  
test/std/strings/basic.string/string.modifiers/string_append/push_back.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.ptr.pass.cpp
  
test/std/strings/basic.string/string.starts_with/starts_with.string_view.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.ptr.pass.cpp
  
test/std/strings/string.view/string.view.template/ends_with.string_view.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.ptr.pass.cpp
  
test/std/strings/string.view/string.view.template/starts_with.string_view.pass.cpp

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
+
+// <string_view>
+
+//   constexpr bool starts_with(string_view x) const noexcept;
+
+#include <string_view>
+#include <cassert>
+
+#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<char, constexpr_char_traits<char>> 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
+}
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
+
+// <string_view>
+
+//   constexpr bool starts_with(string_view x) const noexcept;
+
+#include <string_view>
+#include <cassert>
+
+#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<char, constexpr_char_traits<char>> 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.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
+
+// <string_view>
+
+//   constexpr bool starts_with(charT x) const noexcept;
+
+#include <string_view>
+#include <cassert>
+
+#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<char, constexpr_char_traits<char>> 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/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
+
+// <string_view>
+
+//   constexpr bool ends_with(string_view x) const noexcept;
+
+#include <string_view>
+#include <cassert>
+
+#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<char, constexpr_char_traits<char>> 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/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
+
+// <string_view>
+
+//   constexpr bool starts_with(const CharT *x) const;
+
+#include <string_view>
+#include <cassert>
+
+#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<char, constexpr_char_traits<char>> 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.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
+
+// <string_view>
+
+//   constexpr bool ends_with(charT x) const noexcept;
+
+#include <string_view>
+#include <cassert>
+
+#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<char, constexpr_char_traits<char>> 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/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
+
+// <string>
+
+//   bool starts_with(string_view x) const noexcept;
+
+#include <string>
+#include <cassert>
+
+#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/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
+
+// <string>
+
+//   bool starts_with(const CharT *x) const;
+
+#include <string>
+#include <cassert>
+
+#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.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
+
+// <string>
+
+//   bool starts_with(charT x) const noexcept;
+
+#include <string>
+#include <cassert>
+
+#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.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 <class S>
 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<veryLarge> s;
+    veryLarge vl;
+    s.push_back(vl);
+    s.push_back(vl);
+    s.push_back(vl);
+    }
 }
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
+
+// <string>
+
+//   bool ends_with(basic_string_view x) const noexcept;
+
+#include <string>
+#include <cassert>
+
+#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.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
+
+// <string>
+
+//   bool ends_with(const CharT *x) const;
+
+#include <string>
+#include <cassert>
+
+#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.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
+
+// <string>
+
+//   bool ends_with(charT x) const noexcept;
+
+#include <string>
+#include <cassert>
+
+#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: 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,30 @@
             (data(), size(), __s, __pos, traits_type::length(__s));
     }
 
+	_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)); }
+
 private:
     const   value_type* __data;
     size_type           __size;
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<charT, traits> sv) const noexcept;
+	bool starts_with(charT c) const noexcept;
+	bool starts_with(const charT* s) const;
+	bool ends_with(basic_string_view<charT, traits> sv) const noexcept;
+	bool ends_with(charT c) const noexcept;
+	bool ends_with(const charT* s) const;
+
     bool __invariants() const;
 };
 
@@ -457,10 +464,10 @@
 template <> struct hash<u32string>;
 template <> struct hash<wstring>;
 
-basic_string<char>     operator "" s( const char *str,     size_t len ); // C++14
-basic_string<wchar_t>  operator "" s( const wchar_t *str,  size_t len ); // C++14
-basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14
-basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14
+basic_string<char>     operator ""s( const char *str,     size_t len ); // C++14
+basic_string<wchar_t>  operator ""s( const wchar_t *str,  size_t len ); // C++14
+basic_string<char16_t> operator ""s( const char16_t *str, size_t len ); // C++14
+basic_string<char32_t> operator ""s( const char32_t *str, size_t len ); // C++14
 
 }  // std
 
@@ -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
@@ -1330,9 +1363,13 @@
     enum {__alignment = 16};
     static _LIBCPP_INLINE_VISIBILITY
     size_type __recommend(size_type __s) _NOEXCEPT
-        {return (__s < __min_cap ? static_cast<size_type>(__min_cap) :
-                 __align_it<sizeof(value_type) < __alignment ?
-                            __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;}
+        {
+        if (__s < __min_cap) return static_cast<size_type>(__min_cap) - 1;
+        size_type __guess = __align_it<sizeof(value_type) < __alignment ?
+                     __alignment/sizeof(value_type) : 1 > (__s+1) - 1;
+        if (__guess == __min_cap) ++__guess;
+        return __guess;
+        }
 
     inline
     void __init(const value_type* __s, size_type __sz, size_type __reserve);
@@ -4010,25 +4047,25 @@
   inline namespace string_literals
   {
     inline _LIBCPP_INLINE_VISIBILITY
-    basic_string<char> operator "" s( const char *__str, size_t __len )
+    basic_string<char> operator ""s( const char *__str, size_t __len )
     {
         return basic_string<char> (__str, __len);
     }
 
     inline _LIBCPP_INLINE_VISIBILITY
-    basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
+    basic_string<wchar_t> operator ""s( const wchar_t *__str, size_t __len )
     {
         return basic_string<wchar_t> (__str, __len);
     }
 
     inline _LIBCPP_INLINE_VISIBILITY
-    basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
+    basic_string<char16_t> operator ""s( const char16_t *__str, size_t __len )
     {
         return basic_string<char16_t> (__str, __len);
     }
 
     inline _LIBCPP_INLINE_VISIBILITY
-    basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
+    basic_string<char32_t> operator ""s( const char32_t *__str, size_t __len )
     {
         return basic_string<char32_t> (__str, __len);
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to