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 #ifndef TEST_HAS_NO_EXCEPTIONS 22 template <class T> 23 struct alloc_imp { 24 bool active; 25 26 alloc_imp() : active(true) {} 27 28 T* allocate(std::size_t n) 29 { 30 if (active) 31 return static_cast<T*>(std::malloc(n * sizeof(T))); 32 else 33 throw std::bad_alloc(); 34 } 35 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<T> *imp; 47 48 poca_alloc(alloc_imp<T> *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(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 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