1baf6f918Svarconst //===----------------------------------------------------------------------===// 2baf6f918Svarconst // 3baf6f918Svarconst // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4baf6f918Svarconst // See https://llvm.org/LICENSE.txt for license information. 5baf6f918Svarconst // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6baf6f918Svarconst // 7baf6f918Svarconst //===----------------------------------------------------------------------===// 8baf6f918Svarconst 9baf6f918Svarconst // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 10baf6f918Svarconst 11baf6f918Svarconst // template<container-compatible-range<charT> R> 12baf6f918Svarconst // constexpr iterator insert_range(const_iterator p, R&& rg); // C++23 13baf6f918Svarconst 14*80097a1fSA. Jiang #include <sstream> 15baf6f918Svarconst #include <string> 16baf6f918Svarconst 17baf6f918Svarconst #include "../../../../containers/sequences/insert_range_sequence_containers.h" 18baf6f918Svarconst #include "test_macros.h" 19baf6f918Svarconst 20baf6f918Svarconst // Tested cases: 21baf6f918Svarconst // - different kinds of insertions (inserting an {empty/one-element/mid-sized/long range} into an 22baf6f918Svarconst // {empty/one-element/full} container at the {beginning/middle/end}); 23baf6f918Svarconst // - an exception is thrown when allocating new elements. 24baf6f918Svarconst 25baf6f918Svarconst constexpr bool test_constexpr() { 26baf6f918Svarconst for_all_iterators_and_allocators_constexpr<char, const char*>([]<class Iter, class Sent, class Alloc>() { 27346a2990SStephan T. Lavavej test_sequence_insert_range<std::basic_string<char, std::char_traits<char>, Alloc>, Iter, Sent>( 28346a2990SStephan T. Lavavej []([[maybe_unused]] auto&& c) { LIBCPP_ASSERT(c.__invariants()); }); 29baf6f918Svarconst }); 30baf6f918Svarconst 31*80097a1fSA. Jiang { // Ensure input-only sized ranges are accepted. 32*80097a1fSA. Jiang using input_iter = cpp20_input_iterator<const char*>; 33*80097a1fSA. Jiang const char in[]{'q', 'w', 'e', 'r'}; 34*80097a1fSA. Jiang std::string s = "zxcv"; 35*80097a1fSA. Jiang s.insert_range(s.begin(), std::views::counted(input_iter{std::ranges::begin(in)}, std::ranges::ssize(in))); 36*80097a1fSA. Jiang assert(s == "qwerzxcv"); 37*80097a1fSA. Jiang } 38*80097a1fSA. Jiang 39baf6f918Svarconst return true; 40baf6f918Svarconst } 41baf6f918Svarconst 42*80097a1fSA. Jiang #ifndef TEST_HAS_NO_LOCALIZATION 43*80097a1fSA. Jiang void test_counted_istream_view() { 44*80097a1fSA. Jiang std::istringstream is{"qwert"}; 45*80097a1fSA. Jiang auto vals = std::views::istream<char>(is); 46*80097a1fSA. Jiang std::string s = "zxcv"; 47*80097a1fSA. Jiang s.insert_range(s.begin(), std::views::counted(vals.begin(), 3)); 48*80097a1fSA. Jiang assert(s == "qwezxcv"); 49*80097a1fSA. Jiang } 50*80097a1fSA. Jiang #endif 51*80097a1fSA. Jiang 52baf6f918Svarconst int main(int, char**) { 53baf6f918Svarconst static_assert(test_constraints_insert_range<std::basic_string, char, int>()); 54baf6f918Svarconst 55baf6f918Svarconst for_all_iterators_and_allocators<char, const char*>([]<class Iter, class Sent, class Alloc>() { 56346a2990SStephan T. Lavavej test_sequence_insert_range<std::basic_string<char, std::char_traits<char>, Alloc>, Iter, Sent>( 57346a2990SStephan T. Lavavej []([[maybe_unused]] auto&& c) { LIBCPP_ASSERT(c.__invariants()); }); 58baf6f918Svarconst }); 59baf6f918Svarconst static_assert(test_constexpr()); 60baf6f918Svarconst 61*80097a1fSA. Jiang #ifndef TEST_HAS_NO_LOCALIZATION 62*80097a1fSA. Jiang test_counted_istream_view(); 63*80097a1fSA. Jiang #endif 64*80097a1fSA. Jiang 65baf6f918Svarconst // Note: `test_insert_range_exception_safety_throwing_copy` doesn't apply because copying chars cannot throw. 66baf6f918Svarconst { 67baf6f918Svarconst #if !defined(TEST_HAS_NO_EXCEPTIONS) 68baf6f918Svarconst // Note: the input string must be long enough to prevent SSO, otherwise the allocator won't be used. 69baf6f918Svarconst std::string in(64, 'a'); 70baf6f918Svarconst 71baf6f918Svarconst try { 72baf6f918Svarconst ThrowingAllocator<char> alloc; 73baf6f918Svarconst 74baf6f918Svarconst globalMemCounter.reset(); 75baf6f918Svarconst std::basic_string<char, std::char_traits<char>, ThrowingAllocator<char>> c(alloc); 76baf6f918Svarconst c.insert_range(c.end(), in); 77baf6f918Svarconst assert(false); // The function call above should throw. 78baf6f918Svarconst 79baf6f918Svarconst } catch (int) { 80baf6f918Svarconst assert(globalMemCounter.new_called == globalMemCounter.delete_called); 81baf6f918Svarconst } 82baf6f918Svarconst #endif 83baf6f918Svarconst } 84baf6f918Svarconst 85baf6f918Svarconst return 0; 86baf6f918Svarconst } 87