1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// <string>
10
11// template<class charT, class traits, class Allocator>
12// basic_string<charT,traits,Allocator>
13// operator+(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs); // constexpr since C++20
14
15// template<class charT, class traits, class Allocator>
16// basic_string<charT,traits,Allocator>&&
17// operator+(basic_string<charT,traits,Allocator>&& lhs, const charT* rhs); // constexpr since C++20
18
19#include <cassert>
20#include <string>
21#include <utility>
22
23#include "asan_testing.h"
24#include "min_allocator.h"
25#include "test_macros.h"
26
27template <class S>
28TEST_CONSTEXPR_CXX20 void test0(const S& lhs, const typename S::value_type* rhs, const S& x) {
29 assert(lhs + rhs == x);
30 LIBCPP_ASSERT(is_string_asan_correct(lhs + rhs));
31}
32
33#if TEST_STD_VER >= 11
34template <class S>
35TEST_CONSTEXPR_CXX20 void test1(S&& lhs, const typename S::value_type* rhs, const S& x) {
36 assert(std::move(lhs) + rhs == x);
37}
38#endif
39
40template <class S>
41TEST_CONSTEXPR_CXX20 void test_string() {
42 const char* test_data[2][4] = {
43 {"", "abcde", "abcdefghij", "abcdefghijklmnopqrst"}, {"", "12345", "1234567890", "12345678901234567890"}};
44
45 const char* results[4][4] = {
46 {"", "12345", "1234567890", "12345678901234567890"},
47 {"abcde", "abcde12345", "abcde1234567890", "abcde12345678901234567890"},
48 {"abcdefghij", "abcdefghij12345", "abcdefghij1234567890", "abcdefghij12345678901234567890"},
49 {"abcdefghijklmnopqrst",
50 "abcdefghijklmnopqrst12345",
51 "abcdefghijklmnopqrst1234567890",
52 "abcdefghijklmnopqrst12345678901234567890"}};
53
54 for (size_t i = 0; i != 4; ++i) {
55 for (size_t k = 0; k != 4; ++k) {
56 { // operator+(const value_type*, const string&);
57 const S lhs(test_data[0][i]);
58 const char* rhs = test_data[1][k];
59 assert(lhs + rhs == results[i][k]);
60 }
61#if TEST_STD_VER >= 11
62 { // operator+(const value_type*, string&&);
63 S lhs(test_data[0][i]);
64 const char* rhs = test_data[1][k];
65 assert(std::move(lhs) + rhs == results[i][k]);
66 }
67#endif
68 }
69 }
70}
71
72TEST_CONSTEXPR_CXX20 bool test() {
73 test_string<std::string>();
74#if TEST_STD_VER >= 11
75 test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
76 test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
77#endif
78
79 { // check that growing to max_size() works
80 using string_type = std::basic_string<char, std::char_traits<char>, tiny_size_allocator<29, char> >;
81 string_type str;
82 str.resize(str.max_size() - 1);
83 string_type result = str + "a";
84
85 assert(result.size() == result.max_size());
86 assert(result.back() == 'a');
87 assert(result.capacity() <= result.get_allocator().max_size());
88 }
89
90 return true;
91}
92
93int main(int, char**) {
94 test();
95#if TEST_STD_VER >= 20
96 static_assert(test());
97#endif
98
99 return 0;
100}
101

source code of libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp