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 template <class T> 22 struct alloc_imp { 23 bool active; 24 25 alloc_imp() : active(true) {} 26 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 void deallocate(T* p, std::size_t) { std::free(p); } 36 void activate () { active = true; } 37 void deactivate() { active = false; } 38 }; 39 40 template <class T> 41 struct poca_alloc { 42 typedef T value_type; 43 typedef std::true_type propagate_on_container_copy_assignment; 44 45 alloc_imp<T> *imp; 46 47 poca_alloc(alloc_imp<T> *imp_) : imp (imp_) {} 48 49 template <class U> 50 poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {} 51 52 T* allocate (std::size_t n) { return imp->allocate(n);} 53 void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); } 54 }; 55 56 template <typename T, typename U> 57 bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) 58 { 59 return lhs.imp == rhs.imp; 60 } 61 62 template <typename T, typename U> 63 bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) 64 { 65 return lhs.imp != rhs.imp; 66 } 67 68 template <class S> 69 void test_assign(S &s1, const S& s2) 70 { 71 try { s1 = s2; } 72 catch ( std::bad_alloc &) { return; } 73 assert(false); 74 } 75 #endif 76 77 78 79 template <class S> 80 void 81 test(S s1, const typename S::allocator_type& a) 82 { 83 S s2(s1, a); 84 LIBCPP_ASSERT(s2.__invariants()); 85 assert(s2 == s1); 86 assert(s2.capacity() >= s2.size()); 87 assert(s2.get_allocator() == a); 88 } 89 90 int main(int, char**) 91 { 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<char> imp1; 116 alloc_imp<char> 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 0; 132 } 133