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