Index: test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp =================================================================== --- test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp +++ test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp @@ -18,12 +18,12 @@ #include "min_allocator.h" #ifndef TEST_HAS_NO_EXCEPTIONS -template struct alloc_imp { bool active; alloc_imp() : active(true) {} + template T* allocate(std::size_t n) { if (active) @@ -32,6 +32,7 @@ throw std::bad_alloc(); } + template void deallocate(T* p, std::size_t) { std::free(p); } void activate () { active = true; } void deactivate() { active = false; } @@ -42,14 +43,14 @@ typedef T value_type; typedef std::true_type propagate_on_container_copy_assignment; - alloc_imp *imp; + alloc_imp *imp; - poca_alloc(alloc_imp *imp_) : imp (imp_) {} + poca_alloc(alloc_imp *imp_) : imp (imp_) {} template poca_alloc(const poca_alloc& other) : imp(other.imp) {} - T* allocate (std::size_t n) { return imp->allocate(n);} + T* allocate (std::size_t n) { return imp->allocate(n);} void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); } }; @@ -112,8 +113,8 @@ const char * p1 = "This is my first string"; const char * p2 = "This is my second string"; - alloc_imp imp1; - alloc_imp imp2; + alloc_imp imp1; + alloc_imp imp2; S s1(p1, A(&imp1)); S s2(p2, A(&imp2)); @@ -122,7 +123,11 @@ imp2.deactivate(); test_assign(s1, s2); - assert(s1 == p1); + // libc++ provides the strong exception safety guarantee on the copy assignment operator, + // but the standard only requires the basic guarantee: + LIBCPP_ASSERT(s1 == p1); + s1.clear(); // under the basic guarantee, s1 must still be a valid string object. + assert(s1.empty()); assert(s2 == p2); } #endif