1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // <string> 11 12 // basic_string(const basic_string& str, const Allocator& alloc); 13 14 #include <string> 15 #include <cassert> 16 17 #include "test_macros.h" 18 #include "test_allocator.h" 19 #include "min_allocator.h" 20 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> *ximp) : imp (ximp) {} 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 69 70 template <class S> 71 void 72 test(S s1, const typename S::allocator_type& a) 73 { 74 S s2(s1, a); 75 LIBCPP_ASSERT(s2.__invariants()); 76 assert(s2 == s1); 77 assert(s2.capacity() >= s2.size()); 78 assert(s2.get_allocator() == a); 79 } 80 81 #ifndef TEST_HAS_NO_EXCEPTIONS 82 template <class S> 83 void test_assign(S &s1, const S& s2) 84 { 85 try { s1 = s2; } 86 catch ( std::bad_alloc &) { return; } 87 assert(false); 88 } 89 #endif 90 91 int main() 92 { 93 { 94 typedef test_allocator<char> A; 95 typedef std::basic_string<char, std::char_traits<char>, A> S; 96 test(S(), A(3)); 97 test(S("1"), A(5)); 98 test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7)); 99 } 100 #if TEST_STD_VER >= 11 101 { 102 typedef min_allocator<char> A; 103 typedef std::basic_string<char, std::char_traits<char>, A> S; 104 test(S(), A()); 105 test(S("1"), A()); 106 test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A()); 107 } 108 109 #ifndef TEST_HAS_NO_EXCEPTIONS 110 { 111 typedef poca_alloc<char> A; 112 typedef std::basic_string<char, std::char_traits<char>, A> S; 113 const char * p1 = "This is my first string"; 114 const char * p2 = "This is my second string"; 115 116 alloc_imp<char> imp1; 117 alloc_imp<char> imp2; 118 S s1(p1, A(&imp1)); 119 S s2(p2, A(&imp2)); 120 121 assert(s1 == p1); 122 assert(s2 == p2); 123 124 imp2.deactivate(); 125 test_assign(s1, s2); 126 assert(s1 == p1); 127 assert(s2 == p2); 128 } 129 #endif 130 #endif 131 } 132