186 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// <string>10 11// basic_string(const basic_string<charT,traits,Allocator>& str,12// size_type pos, size_type n,13// const Allocator& a = Allocator()); // constexpr since C++2014//15// basic_string(const basic_string<charT,traits,Allocator>& str,16// size_type pos,17// const Allocator& a = Allocator()); // constexpr since C++2018 19#include <string>20#include <stdexcept>21#include <algorithm>22#include <vector>23#include <scoped_allocator>24#include <cassert>25 26#include "test_macros.h"27#include "test_allocator.h"28#include "min_allocator.h"29#include "asan_testing.h"30 31template <class S>32TEST_CONSTEXPR_CXX20 void test(S str, unsigned pos) {33 typedef typename S::traits_type T;34 typedef typename S::allocator_type A;35 36 if (pos <= str.size()) {37 S s2(str, pos);38 LIBCPP_ASSERT(s2.__invariants());39 typename S::size_type rlen = str.size() - pos;40 assert(s2.size() == rlen);41 assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);42 assert(s2.get_allocator() == A());43 assert(s2.capacity() >= s2.size());44 LIBCPP_ASSERT(is_string_asan_correct(s2));45 }46#ifndef TEST_HAS_NO_EXCEPTIONS47 else if (!TEST_IS_CONSTANT_EVALUATED) {48 try {49 S s2(str, pos);50 assert(false);51 } catch (std::out_of_range&) {52 assert(pos > str.size());53 }54 }55#endif56}57 58template <class S>59TEST_CONSTEXPR_CXX20 void test(S str, unsigned pos, unsigned n) {60 typedef typename S::traits_type T;61 typedef typename S::allocator_type A;62 if (pos <= str.size()) {63 S s2(str, pos, n);64 LIBCPP_ASSERT(s2.__invariants());65 typename S::size_type rlen = std::min<typename S::size_type>(str.size() - pos, n);66 assert(s2.size() == rlen);67 assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);68 assert(s2.get_allocator() == A());69 assert(s2.capacity() >= s2.size());70 LIBCPP_ASSERT(is_string_asan_correct(s2));71 }72#ifndef TEST_HAS_NO_EXCEPTIONS73 else if (!TEST_IS_CONSTANT_EVALUATED) {74 try {75 S s2(str, pos, n);76 assert(false);77 } catch (std::out_of_range&) {78 assert(pos > str.size());79 }80 }81#endif82}83 84template <class S>85TEST_CONSTEXPR_CXX20 void test(S str, unsigned pos, unsigned n, const typename S::allocator_type& a) {86 typedef typename S::traits_type T;87 88 if (pos <= str.size()) {89 S s2(str, pos, n, a);90 LIBCPP_ASSERT(s2.__invariants());91 typename S::size_type rlen = std::min<typename S::size_type>(str.size() - pos, n);92 assert(s2.size() == rlen);93 assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);94 assert(s2.get_allocator() == a);95 assert(s2.capacity() >= s2.size());96 LIBCPP_ASSERT(is_string_asan_correct(s2));97 }98#ifndef TEST_HAS_NO_EXCEPTIONS99 else if (!TEST_IS_CONSTANT_EVALUATED) {100 try {101 S s2(str, pos, n, a);102 assert(false);103 } catch (std::out_of_range&) {104 assert(pos > str.size());105 }106 }107#endif108}109 110void test_lwg2583() {111#if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS)112 typedef std::basic_string<char, std::char_traits<char>, test_allocator<char> > StringA;113 std::vector<StringA, std::scoped_allocator_adaptor<test_allocator<StringA> > > vs;114 StringA s{"1234"};115 vs.emplace_back(s, 2);116 117 try {118 vs.emplace_back(s, 5);119 } catch (const std::out_of_range&) {120 return;121 }122 assert(false);123#endif124}125 126template <class Alloc>127TEST_CONSTEXPR_CXX20 void test_string(const Alloc& a1, const Alloc& a2) {128 using S = std::basic_string<char, std::char_traits<char>, Alloc>;129 130 test(S(Alloc(a1)), 0);131 test(S(Alloc(a1)), 1);132 test(S("1", Alloc(a1)), 0);133 test(S("1", Alloc(a1)), 1);134 test(S("1", Alloc(a1)), 2);135 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 0);136 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 5);137 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 50);138 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 500);139 140 test(S(Alloc(a1)), 0, 0);141 test(S(Alloc(a1)), 0, 1);142 test(S(Alloc(a1)), 1, 0);143 test(S(Alloc(a1)), 1, 1);144 test(S(Alloc(a1)), 1, 2);145 test(S("1", Alloc(a1)), 0, 0);146 test(S("1", Alloc(a1)), 0, 1);147 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 50, 0);148 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 50, 1);149 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 50, 10);150 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 50, 100);151 152 test(S(Alloc(a1)), 0, 0, Alloc(a2));153 test(S(Alloc(a1)), 0, 1, Alloc(a2));154 test(S(Alloc(a1)), 1, 0, Alloc(a2));155 test(S(Alloc(a1)), 1, 1, Alloc(a2));156 test(S(Alloc(a1)), 1, 2, Alloc(a2));157 test(S("1", Alloc(a1)), 0, 0, Alloc(a2));158 test(S("1", Alloc(a1)), 0, 1, Alloc(a2));159 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 50, 0, Alloc(a2));160 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 50, 1, Alloc(a2));161 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 50, 10, Alloc(a2));162 test(S("1234567890123456789012345678901234567890123456789012345678901234567890", Alloc(a1)), 50, 100, Alloc(a2));163}164 165TEST_CONSTEXPR_CXX20 bool test() {166 test_string(std::allocator<char>(), std::allocator<char>());167 test_string(test_allocator<char>(), test_allocator<char>());168 test_string(test_allocator<char>(3), test_allocator<char>(5));169#if TEST_STD_VER >= 11170 test_string(min_allocator<char>(), min_allocator<char>());171 test_string(safe_allocator<char>(), safe_allocator<char>());172#endif173 174 return true;175}176 177int main(int, char**) {178 test();179#if TEST_STD_VER > 17180 static_assert(test());181#endif182 test_lwg2583();183 184 return 0;185}186