xref: /llvm-project/libcxx/test/std/strings/basic.string/string.cons/substr_rvalue.pass.cpp (revision 4dee6411e0d993fd17099bd7564276474412383e)
129378ab2SNikolas Klauser //===----------------------------------------------------------------------===//
229378ab2SNikolas Klauser //
329378ab2SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
429378ab2SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
529378ab2SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
629378ab2SNikolas Klauser //
729378ab2SNikolas Klauser //===----------------------------------------------------------------------===//
829378ab2SNikolas Klauser 
929378ab2SNikolas Klauser // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
1029378ab2SNikolas Klauser 
1129378ab2SNikolas Klauser // <string>
1229378ab2SNikolas Klauser 
1329378ab2SNikolas Klauser // constexpr basic_string(basic_string&& str, size_type pos, const Allocator& a = Allocator());
1429378ab2SNikolas Klauser // constexpr basic_string(basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator());
1529378ab2SNikolas Klauser 
1629378ab2SNikolas Klauser #include <cassert>
17d3933a5dSCasey Carter #include <stdexcept>
1829378ab2SNikolas Klauser #include <string>
1929378ab2SNikolas Klauser 
2029378ab2SNikolas Klauser #include "constexpr_char_traits.h"
2129378ab2SNikolas Klauser #include "count_new.h"
2229378ab2SNikolas Klauser #include "make_string.h"
2329378ab2SNikolas Klauser #include "min_allocator.h"
2429378ab2SNikolas Klauser #include "test_allocator.h"
2529378ab2SNikolas Klauser #include "test_macros.h"
269ed20568STacet #include "asan_testing.h"
27*4dee6411SMark de Wever #include "operator_hijacker.h"
2829378ab2SNikolas Klauser 
2929378ab2SNikolas Klauser #define STR(string) MAKE_CSTRING(typename S::value_type, string)
3029378ab2SNikolas Klauser 
3129378ab2SNikolas Klauser constexpr struct should_throw_exception_t {
3229378ab2SNikolas Klauser } should_throw_exception;
3329378ab2SNikolas Klauser 
3429378ab2SNikolas Klauser template <class S>
3529378ab2SNikolas Klauser constexpr void test_string_pos(S orig, typename S::size_type pos, S expected) {
3629378ab2SNikolas Klauser #ifdef _LIBCPP_VERSION
3729378ab2SNikolas Klauser   ConstexprDisableAllocationGuard g;
3829378ab2SNikolas Klauser #endif
3929378ab2SNikolas Klauser   S substr(std::move(orig), pos);
4029378ab2SNikolas Klauser   LIBCPP_ASSERT(orig.__invariants());
4129378ab2SNikolas Klauser   LIBCPP_ASSERT(orig.empty());
4229378ab2SNikolas Klauser   LIBCPP_ASSERT(substr.__invariants());
4329378ab2SNikolas Klauser   assert(substr == expected);
449ed20568STacet   LIBCPP_ASSERT(is_string_asan_correct(orig));
459ed20568STacet   LIBCPP_ASSERT(is_string_asan_correct(substr));
4629378ab2SNikolas Klauser }
4729378ab2SNikolas Klauser 
4829378ab2SNikolas Klauser template <class S>
4929378ab2SNikolas Klauser constexpr void test_string_pos(S orig, typename S::size_type pos, should_throw_exception_t) {
5029378ab2SNikolas Klauser #ifndef TEST_HAS_NO_EXCEPTIONS
5129378ab2SNikolas Klauser   if (!std::is_constant_evaluated()) {
5229378ab2SNikolas Klauser     try {
5329378ab2SNikolas Klauser       [[maybe_unused]] S substr = S(std::move(orig), pos);
5429378ab2SNikolas Klauser       assert(false);
5529378ab2SNikolas Klauser     } catch (const std::out_of_range&) {
5629378ab2SNikolas Klauser     }
5729378ab2SNikolas Klauser   }
5829378ab2SNikolas Klauser #else
5929378ab2SNikolas Klauser   (void)orig;
6029378ab2SNikolas Klauser   (void)pos;
6129378ab2SNikolas Klauser #endif
6229378ab2SNikolas Klauser }
6329378ab2SNikolas Klauser 
6429378ab2SNikolas Klauser template <class S>
6529378ab2SNikolas Klauser constexpr void
6629378ab2SNikolas Klauser test_string_pos_alloc(S orig, typename S::size_type pos, const typename S::allocator_type& alloc, S expected) {
6729378ab2SNikolas Klauser   S substr(std::move(orig), pos, alloc);
6829378ab2SNikolas Klauser   LIBCPP_ASSERT(orig.__invariants());
6929378ab2SNikolas Klauser   LIBCPP_ASSERT(substr.__invariants());
7029378ab2SNikolas Klauser   assert(substr == expected);
7129378ab2SNikolas Klauser   assert(substr.get_allocator() == alloc);
729ed20568STacet   LIBCPP_ASSERT(is_string_asan_correct(orig));
739ed20568STacet   LIBCPP_ASSERT(is_string_asan_correct(substr));
7429378ab2SNikolas Klauser }
7529378ab2SNikolas Klauser 
7629378ab2SNikolas Klauser template <class S>
7729378ab2SNikolas Klauser constexpr void test_string_pos_alloc(
7829378ab2SNikolas Klauser     S orig, typename S::size_type pos, const typename S::allocator_type& alloc, should_throw_exception_t) {
7929378ab2SNikolas Klauser #ifndef TEST_HAS_NO_EXCEPTIONS
8029378ab2SNikolas Klauser   if (!std::is_constant_evaluated()) {
8129378ab2SNikolas Klauser     try {
8229378ab2SNikolas Klauser       [[maybe_unused]] S substr = S(std::move(orig), pos, alloc);
8329378ab2SNikolas Klauser       assert(false);
8429378ab2SNikolas Klauser     } catch (const std::out_of_range&) {
8529378ab2SNikolas Klauser     }
8629378ab2SNikolas Klauser   }
8729378ab2SNikolas Klauser #else
8829378ab2SNikolas Klauser   (void)orig;
8929378ab2SNikolas Klauser   (void)pos;
9029378ab2SNikolas Klauser   (void)alloc;
9129378ab2SNikolas Klauser #endif
9229378ab2SNikolas Klauser }
9329378ab2SNikolas Klauser 
9429378ab2SNikolas Klauser template <class S>
9529378ab2SNikolas Klauser constexpr void test_string_pos_n(S orig, typename S::size_type pos, typename S::size_type n, S expected) {
9629378ab2SNikolas Klauser #ifdef _LIBCPP_VERSION
9729378ab2SNikolas Klauser   ConstexprDisableAllocationGuard g;
9829378ab2SNikolas Klauser #endif
9929378ab2SNikolas Klauser   S substr(std::move(orig), pos, n);
10029378ab2SNikolas Klauser   LIBCPP_ASSERT(orig.__invariants());
10129378ab2SNikolas Klauser   LIBCPP_ASSERT(orig.empty());
10229378ab2SNikolas Klauser   LIBCPP_ASSERT(substr.__invariants());
10329378ab2SNikolas Klauser   assert(substr == expected);
1049ed20568STacet   LIBCPP_ASSERT(is_string_asan_correct(orig));
1059ed20568STacet   LIBCPP_ASSERT(is_string_asan_correct(substr));
10629378ab2SNikolas Klauser }
10729378ab2SNikolas Klauser 
10829378ab2SNikolas Klauser template <class S>
10929378ab2SNikolas Klauser constexpr void test_string_pos_n(S orig, typename S::size_type pos, typename S::size_type n, should_throw_exception_t) {
11029378ab2SNikolas Klauser #ifndef TEST_HAS_NO_EXCEPTIONS
11129378ab2SNikolas Klauser   if (!std::is_constant_evaluated()) {
11229378ab2SNikolas Klauser     try {
11329378ab2SNikolas Klauser       [[maybe_unused]] S substr = S(std::move(orig), pos, n);
11429378ab2SNikolas Klauser       assert(false);
11529378ab2SNikolas Klauser     } catch (const std::out_of_range&) {
11629378ab2SNikolas Klauser     }
11729378ab2SNikolas Klauser   }
11829378ab2SNikolas Klauser #else
11929378ab2SNikolas Klauser   (void)orig;
12029378ab2SNikolas Klauser   (void)pos;
12129378ab2SNikolas Klauser   (void)n;
12229378ab2SNikolas Klauser #endif
12329378ab2SNikolas Klauser }
12429378ab2SNikolas Klauser 
12529378ab2SNikolas Klauser template <class S>
12629378ab2SNikolas Klauser constexpr void test_string_pos_n_alloc(
12729378ab2SNikolas Klauser     S orig, typename S::size_type pos, typename S::size_type n, const typename S::allocator_type& alloc, S expected) {
12829378ab2SNikolas Klauser   S substr(std::move(orig), pos, n, alloc);
12929378ab2SNikolas Klauser   LIBCPP_ASSERT(orig.__invariants());
13029378ab2SNikolas Klauser   LIBCPP_ASSERT(substr.__invariants());
13129378ab2SNikolas Klauser   assert(substr == expected);
13229378ab2SNikolas Klauser   assert(substr.get_allocator() == alloc);
1339ed20568STacet   LIBCPP_ASSERT(is_string_asan_correct(orig));
1349ed20568STacet   LIBCPP_ASSERT(is_string_asan_correct(substr));
13529378ab2SNikolas Klauser }
13629378ab2SNikolas Klauser 
13729378ab2SNikolas Klauser template <class S>
13829378ab2SNikolas Klauser constexpr void test_string_pos_n_alloc(
13929378ab2SNikolas Klauser     S orig,
14029378ab2SNikolas Klauser     typename S::size_type pos,
14129378ab2SNikolas Klauser     typename S::size_type n,
14229378ab2SNikolas Klauser     const typename S::allocator_type& alloc,
14329378ab2SNikolas Klauser     should_throw_exception_t) {
14429378ab2SNikolas Klauser #ifndef TEST_HAS_NO_EXCEPTIONS
14529378ab2SNikolas Klauser   if (!std::is_constant_evaluated()) {
14629378ab2SNikolas Klauser     try {
14729378ab2SNikolas Klauser       [[maybe_unused]] S substr = S(std::move(orig), pos, n, alloc);
14829378ab2SNikolas Klauser       assert(false);
14929378ab2SNikolas Klauser     } catch (const std::out_of_range&) {
15029378ab2SNikolas Klauser     }
15129378ab2SNikolas Klauser   }
15229378ab2SNikolas Klauser #else
15329378ab2SNikolas Klauser   (void)orig;
15429378ab2SNikolas Klauser   (void)pos;
15529378ab2SNikolas Klauser   (void)n;
15629378ab2SNikolas Klauser   (void)alloc;
15729378ab2SNikolas Klauser #endif
15829378ab2SNikolas Klauser }
15929378ab2SNikolas Klauser 
16029378ab2SNikolas Klauser template <class S>
16129378ab2SNikolas Klauser constexpr void test_string(const typename S::allocator_type& alloc) {
16229378ab2SNikolas Klauser   test_string_pos<S>(STR(""), 0, STR(""));
16329378ab2SNikolas Klauser   test_string_pos<S>(STR(""), 1, should_throw_exception);
16429378ab2SNikolas Klauser   test_string_pos<S>(STR("Banane"), 1, STR("anane"));
16529378ab2SNikolas Klauser   test_string_pos<S>(STR("Banane"), 6, STR(""));
16629378ab2SNikolas Klauser   test_string_pos<S>(STR("Banane"), 7, should_throw_exception);
16729378ab2SNikolas Klauser   test_string_pos<S>(STR("long long string so no SSO"), 0, STR("long long string so no SSO"));
16829378ab2SNikolas Klauser   test_string_pos<S>(STR("long long string so no SSO"), 10, STR("string so no SSO"));
16929378ab2SNikolas Klauser   test_string_pos<S>(STR("long long string so no SSO"), 26, STR(""));
17029378ab2SNikolas Klauser   test_string_pos<S>(STR("long long string so no SSO"), 27, should_throw_exception);
17129378ab2SNikolas Klauser 
17229378ab2SNikolas Klauser   test_string_pos_alloc<S>(STR(""), 0, alloc, STR(""));
17329378ab2SNikolas Klauser   test_string_pos_alloc<S>(STR(""), 1, alloc, should_throw_exception);
17429378ab2SNikolas Klauser   test_string_pos_alloc<S>(STR("Banane"), 1, alloc, STR("anane"));
17529378ab2SNikolas Klauser   test_string_pos_alloc<S>(STR("Banane"), 6, alloc, STR(""));
17629378ab2SNikolas Klauser   test_string_pos_alloc<S>(STR("Banane"), 7, alloc, should_throw_exception);
17729378ab2SNikolas Klauser   test_string_pos_alloc<S>(STR("long long string so no SSO"), 0, alloc, STR("long long string so no SSO"));
17829378ab2SNikolas Klauser   test_string_pos_alloc<S>(STR("long long string so no SSO"), 10, alloc, STR("string so no SSO"));
17929378ab2SNikolas Klauser   test_string_pos_alloc<S>(STR("long long string so no SSO"), 26, alloc, STR(""));
18029378ab2SNikolas Klauser   test_string_pos_alloc<S>(STR("long long string so no SSO"), 27, alloc, should_throw_exception);
18129378ab2SNikolas Klauser 
18229378ab2SNikolas Klauser   test_string_pos_n<S>(STR(""), 0, 0, STR(""));
18329378ab2SNikolas Klauser   test_string_pos_n<S>(STR(""), 0, 1, STR(""));
18429378ab2SNikolas Klauser   test_string_pos_n<S>(STR(""), 1, 0, should_throw_exception);
18529378ab2SNikolas Klauser   test_string_pos_n<S>(STR(""), 1, 1, should_throw_exception);
18629378ab2SNikolas Klauser   test_string_pos_n<S>(STR("Banane"), 1, 10, STR("anane"));
18729378ab2SNikolas Klauser   test_string_pos_n<S>(STR("Banane"), 6, 0, STR(""));
18829378ab2SNikolas Klauser   test_string_pos_n<S>(STR("Banane"), 6, 5, STR(""));
18929378ab2SNikolas Klauser   test_string_pos_n<S>(STR("Banane"), 7, 10, should_throw_exception);
19029378ab2SNikolas Klauser   test_string_pos_n<S>(STR("long long string so no SSO"), 0, 10, STR("long long "));
19129378ab2SNikolas Klauser   test_string_pos_n<S>(STR("long long string so no SSO"), 10, 8, STR("string s"));
19229378ab2SNikolas Klauser   test_string_pos_n<S>(STR("long long string so no SSO"), 20, 10, STR("no SSO"));
19329378ab2SNikolas Klauser   test_string_pos_n<S>(STR("long long string so no SSO"), 26, 10, STR(""));
19429378ab2SNikolas Klauser   test_string_pos_n<S>(STR("long long string so no SSO"), 27, 10, should_throw_exception);
19529378ab2SNikolas Klauser 
19629378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR(""), 0, 0, alloc, STR(""));
19729378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR(""), 0, 1, alloc, STR(""));
19829378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR(""), 1, 0, alloc, should_throw_exception);
19929378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR(""), 1, 1, alloc, should_throw_exception);
20029378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR("Banane"), 1, 10, alloc, STR("anane"));
20129378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR("Banane"), 6, 0, alloc, STR(""));
20229378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR("Banane"), 6, 5, alloc, STR(""));
20329378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR("Banane"), 7, 10, alloc, should_throw_exception);
20429378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR("long long string so no SSO"), 0, 10, alloc, STR("long long "));
20529378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR("long long string so no SSO"), 10, 8, alloc, STR("string s"));
20629378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR("long long string so no SSO"), 20, 10, alloc, STR("no SSO"));
20729378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR("long long string so no SSO"), 26, 10, alloc, STR(""));
20829378ab2SNikolas Klauser   test_string_pos_n_alloc<S>(STR("long long string so no SSO"), 27, 10, alloc, should_throw_exception);
20929378ab2SNikolas Klauser }
21029378ab2SNikolas Klauser 
21129378ab2SNikolas Klauser template <class CharT, class CharTraits>
21229378ab2SNikolas Klauser constexpr void test_allocators() {
21329378ab2SNikolas Klauser   test_string<std::basic_string<CharT, CharTraits, std::allocator<CharT>>>(std::allocator<CharT>{});
21429378ab2SNikolas Klauser   test_string<std::basic_string<CharT, CharTraits, min_allocator<CharT>>>(min_allocator<CharT>{});
21529378ab2SNikolas Klauser   test_string<std::basic_string<CharT, CharTraits, test_allocator<CharT>>>(test_allocator<CharT>{42});
216*4dee6411SMark de Wever   test_string<std::basic_string<CharT, CharTraits, operator_hijacker_allocator<CharT>>>(
217*4dee6411SMark de Wever       operator_hijacker_allocator<CharT>{});
21829378ab2SNikolas Klauser }
21929378ab2SNikolas Klauser 
22029378ab2SNikolas Klauser template <class CharT>
22129378ab2SNikolas Klauser constexpr bool test_char_traits() {
22229378ab2SNikolas Klauser   test_allocators<CharT, std::char_traits<CharT>>();
22329378ab2SNikolas Klauser   test_allocators<CharT, constexpr_char_traits<CharT>>();
22429378ab2SNikolas Klauser 
22529378ab2SNikolas Klauser   return true;
22629378ab2SNikolas Klauser }
22729378ab2SNikolas Klauser 
22829378ab2SNikolas Klauser int main(int, char**) {
22929378ab2SNikolas Klauser   // TODO: put these into a single function when we increase the constexpr step limit
23029378ab2SNikolas Klauser   test_char_traits<char>();
23129378ab2SNikolas Klauser   static_assert(test_char_traits<char>());
23229378ab2SNikolas Klauser   test_char_traits<char16_t>();
23329378ab2SNikolas Klauser   static_assert(test_char_traits<char16_t>());
23429378ab2SNikolas Klauser   test_char_traits<char32_t>();
23529378ab2SNikolas Klauser   static_assert(test_char_traits<char32_t>());
23629378ab2SNikolas Klauser #ifndef TEST_HAS_NO_WIDE_CHARACTERS
23729378ab2SNikolas Klauser   test_char_traits<wchar_t>();
23829378ab2SNikolas Klauser   static_assert(test_char_traits<wchar_t>());
23929378ab2SNikolas Klauser #endif
24029378ab2SNikolas Klauser #ifndef TEST_HAS_NO_CHAR8_T
24129378ab2SNikolas Klauser   test_char_traits<char8_t>();
24229378ab2SNikolas Klauser   static_assert(test_char_traits<char8_t>());
24329378ab2SNikolas Klauser #endif
24429378ab2SNikolas Klauser 
24529378ab2SNikolas Klauser   return 0;
24629378ab2SNikolas Klauser }
247