15a83710eSEric Fiselier //===----------------------------------------------------------------------===// 25a83710eSEric Fiselier // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65a83710eSEric Fiselier // 75a83710eSEric Fiselier //===----------------------------------------------------------------------===// 85a83710eSEric Fiselier 95a83710eSEric Fiselier // <string> 105a83710eSEric Fiselier 115a83710eSEric Fiselier // basic_string(const basic_string& str, const Allocator& alloc); 125a83710eSEric Fiselier 135a83710eSEric Fiselier #include <string> 145a83710eSEric Fiselier #include <cassert> 155a83710eSEric Fiselier 161f4231f8SEric Fiselier #include "test_macros.h" 175a83710eSEric Fiselier #include "test_allocator.h" 185a83710eSEric Fiselier #include "min_allocator.h" 195a83710eSEric Fiselier 206f033f0cSMarshall Clow #ifndef TEST_HAS_NO_EXCEPTIONS 21d107be84SMarshall Clow struct alloc_imp { 22d107be84SMarshall Clow bool active; 23d107be84SMarshall Clow 24d107be84SMarshall Clow alloc_imp() : active(true) {} 25d107be84SMarshall Clow 267b9e4ebbSBilly Robert O'Neal III template <class T> 27d107be84SMarshall Clow T* allocate(std::size_t n) 28d107be84SMarshall Clow { 29d107be84SMarshall Clow if (active) 30d107be84SMarshall Clow return static_cast<T*>(std::malloc(n * sizeof(T))); 31d107be84SMarshall Clow else 32d107be84SMarshall Clow throw std::bad_alloc(); 33d107be84SMarshall Clow } 34d107be84SMarshall Clow 357b9e4ebbSBilly Robert O'Neal III template <class T> 36d107be84SMarshall Clow void deallocate(T* p, std::size_t) { std::free(p); } 37d107be84SMarshall Clow void activate () { active = true; } 38d107be84SMarshall Clow void deactivate() { active = false; } 39d107be84SMarshall Clow }; 40d107be84SMarshall Clow 41d107be84SMarshall Clow template <class T> 42d107be84SMarshall Clow struct poca_alloc { 43d107be84SMarshall Clow typedef T value_type; 44d107be84SMarshall Clow typedef std::true_type propagate_on_container_copy_assignment; 45d107be84SMarshall Clow 467b9e4ebbSBilly Robert O'Neal III alloc_imp *imp; 47d107be84SMarshall Clow 487b9e4ebbSBilly Robert O'Neal III poca_alloc(alloc_imp *imp_) : imp (imp_) {} 49d107be84SMarshall Clow 50d107be84SMarshall Clow template <class U> 51d107be84SMarshall Clow poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {} 52d107be84SMarshall Clow 537b9e4ebbSBilly Robert O'Neal III T* allocate (std::size_t n) { return imp->allocate<T>(n);} 54d107be84SMarshall Clow void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); } 55d107be84SMarshall Clow }; 56d107be84SMarshall Clow 57d107be84SMarshall Clow template <typename T, typename U> 58d107be84SMarshall Clow bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) 59d107be84SMarshall Clow { 60d107be84SMarshall Clow return lhs.imp == rhs.imp; 61d107be84SMarshall Clow } 62d107be84SMarshall Clow 63d107be84SMarshall Clow template <typename T, typename U> 64d107be84SMarshall Clow bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) 65d107be84SMarshall Clow { 66d107be84SMarshall Clow return lhs.imp != rhs.imp; 67d107be84SMarshall Clow } 68d107be84SMarshall Clow 696f033f0cSMarshall Clow template <class S> 706f033f0cSMarshall Clow void test_assign(S &s1, const S& s2) 716f033f0cSMarshall Clow { 726f033f0cSMarshall Clow try { s1 = s2; } 736f033f0cSMarshall Clow catch ( std::bad_alloc &) { return; } 746f033f0cSMarshall Clow assert(false); 756f033f0cSMarshall Clow } 766f033f0cSMarshall Clow #endif 776f033f0cSMarshall Clow 78d107be84SMarshall Clow 79d107be84SMarshall Clow 805a83710eSEric Fiselier template <class S> 815a83710eSEric Fiselier void 825a83710eSEric Fiselier test(S s1, const typename S::allocator_type& a) 835a83710eSEric Fiselier { 845a83710eSEric Fiselier S s2(s1, a); 851f4231f8SEric Fiselier LIBCPP_ASSERT(s2.__invariants()); 865a83710eSEric Fiselier assert(s2 == s1); 875a83710eSEric Fiselier assert(s2.capacity() >= s2.size()); 885a83710eSEric Fiselier assert(s2.get_allocator() == a); 895a83710eSEric Fiselier } 905a83710eSEric Fiselier 91*e85018b7SNikolas Klauser bool test() { 925a83710eSEric Fiselier { 935a83710eSEric Fiselier typedef test_allocator<char> A; 945a83710eSEric Fiselier typedef std::basic_string<char, std::char_traits<char>, A> S; 955a83710eSEric Fiselier test(S(), A(3)); 965a83710eSEric Fiselier test(S("1"), A(5)); 975a83710eSEric Fiselier test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7)); 985a83710eSEric Fiselier } 991f4231f8SEric Fiselier #if TEST_STD_VER >= 11 1005a83710eSEric Fiselier { 1015a83710eSEric Fiselier typedef min_allocator<char> A; 1025a83710eSEric Fiselier typedef std::basic_string<char, std::char_traits<char>, A> S; 1035a83710eSEric Fiselier test(S(), A()); 1045a83710eSEric Fiselier test(S("1"), A()); 1055a83710eSEric Fiselier test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A()); 1065a83710eSEric Fiselier } 107d107be84SMarshall Clow 108d107be84SMarshall Clow #ifndef TEST_HAS_NO_EXCEPTIONS 109d107be84SMarshall Clow { 110d107be84SMarshall Clow typedef poca_alloc<char> A; 111d107be84SMarshall Clow typedef std::basic_string<char, std::char_traits<char>, A> S; 112d107be84SMarshall Clow const char * p1 = "This is my first string"; 113d107be84SMarshall Clow const char * p2 = "This is my second string"; 114d107be84SMarshall Clow 1157b9e4ebbSBilly Robert O'Neal III alloc_imp imp1; 1167b9e4ebbSBilly Robert O'Neal III alloc_imp imp2; 117d107be84SMarshall Clow S s1(p1, A(&imp1)); 118d107be84SMarshall Clow S s2(p2, A(&imp2)); 119d107be84SMarshall Clow 120d107be84SMarshall Clow assert(s1 == p1); 121d107be84SMarshall Clow assert(s2 == p2); 122d107be84SMarshall Clow 123d107be84SMarshall Clow imp2.deactivate(); 124d107be84SMarshall Clow test_assign(s1, s2); 125d107be84SMarshall Clow assert(s1 == p1); 126d107be84SMarshall Clow assert(s2 == p2); 127d107be84SMarshall Clow } 128d107be84SMarshall Clow #endif 1295a83710eSEric Fiselier #endif 1302df59c50SJF Bastien 131*e85018b7SNikolas Klauser return true; 132*e85018b7SNikolas Klauser } 133*e85018b7SNikolas Klauser 134*e85018b7SNikolas Klauser int main(int, char**) 135*e85018b7SNikolas Klauser { 136*e85018b7SNikolas Klauser test(); 137*e85018b7SNikolas Klauser #if TEST_STD_VER > 17 138*e85018b7SNikolas Klauser // static_assert(test()); 139*e85018b7SNikolas Klauser #endif 140*e85018b7SNikolas Klauser 1412df59c50SJF Bastien return 0; 1425a83710eSEric Fiselier } 143