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 // basic_string(const basic_string& str, const Allocator& alloc); 12 13 #include <string> 14 #include <cassert> 15 16 #include "test_macros.h" 17 #include "test_allocator.h" 18 #include "min_allocator.h" 19 20 #ifndef TEST_HAS_NO_EXCEPTIONS 21 struct alloc_imp { 22 bool active; 23 24 alloc_imp() : active(true) {} 25 26 template <class T> 27 T* allocate(std::size_t n) 28 { 29 if (active) 30 return static_cast<T*>(std::malloc(n * sizeof(T))); 31 else 32 throw std::bad_alloc(); 33 } 34 35 template <class T> 36 void deallocate(T* p, std::size_t) { std::free(p); } 37 void activate () { active = true; } 38 void deactivate() { active = false; } 39 }; 40 41 template <class T> 42 struct poca_alloc { 43 typedef T value_type; 44 typedef std::true_type propagate_on_container_copy_assignment; 45 46 alloc_imp *imp; 47 48 poca_alloc(alloc_imp *imp_) : imp (imp_) {} 49 50 template <class U> 51 poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {} 52 53 T* allocate (std::size_t n) { return imp->allocate<T>(n);} 54 void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); } 55 }; 56 57 template <typename T, typename U> 58 bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) 59 { 60 return lhs.imp == rhs.imp; 61 } 62 63 template <typename T, typename U> 64 bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) 65 { 66 return lhs.imp != rhs.imp; 67 } 68 69 template <class S> 70 void test_assign(S &s1, const S& s2) 71 { 72 try { s1 = s2; } 73 catch ( std::bad_alloc &) { return; } 74 assert(false); 75 } 76 #endif 77 78 79 80 template <class S> 81 void 82 test(S s1, const typename S::allocator_type& a) 83 { 84 S s2(s1, a); 85 LIBCPP_ASSERT(s2.__invariants()); 86 assert(s2 == s1); 87 assert(s2.capacity() >= s2.size()); 88 assert(s2.get_allocator() == a); 89 } 90 91 bool test() { 92 { 93 typedef test_allocator<char> A; 94 typedef std::basic_string<char, std::char_traits<char>, A> S; 95 test(S(), A(3)); 96 test(S("1"), A(5)); 97 test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7)); 98 } 99 #if TEST_STD_VER >= 11 100 { 101 typedef min_allocator<char> A; 102 typedef std::basic_string<char, std::char_traits<char>, A> S; 103 test(S(), A()); 104 test(S("1"), A()); 105 test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A()); 106 } 107 108 #ifndef TEST_HAS_NO_EXCEPTIONS 109 { 110 typedef poca_alloc<char> A; 111 typedef std::basic_string<char, std::char_traits<char>, A> S; 112 const char * p1 = "This is my first string"; 113 const char * p2 = "This is my second string"; 114 115 alloc_imp imp1; 116 alloc_imp imp2; 117 S s1(p1, A(&imp1)); 118 S s2(p2, A(&imp2)); 119 120 assert(s1 == p1); 121 assert(s2 == p2); 122 123 imp2.deactivate(); 124 test_assign(s1, s2); 125 assert(s1 == p1); 126 assert(s2 == p2); 127 } 128 #endif 129 #endif 130 131 return true; 132 } 133 134 int main(int, char**) 135 { 136 test(); 137 #if TEST_STD_VER > 17 138 // static_assert(test()); 139 #endif 140 141 return 0; 142 } 143