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 9*425620ccSNikolas Klauser // XFAIL: LIBCXX-AIX-FIXME 10*425620ccSNikolas Klauser 115a83710eSEric Fiselier // <string> 125a83710eSEric Fiselier 13*425620ccSNikolas Klauser // basic_string(const basic_string& str, const Allocator& alloc); // constexpr since C++20 145a83710eSEric Fiselier 155a83710eSEric Fiselier #include <string> 165a83710eSEric Fiselier #include <cassert> 175a83710eSEric Fiselier 181f4231f8SEric Fiselier #include "test_macros.h" 195a83710eSEric Fiselier #include "test_allocator.h" 205a83710eSEric Fiselier #include "min_allocator.h" 215a83710eSEric Fiselier 226f033f0cSMarshall Clow #ifndef TEST_HAS_NO_EXCEPTIONS 23d107be84SMarshall Clow struct alloc_imp { 24d107be84SMarshall Clow bool active; 25d107be84SMarshall Clow 2685e9b268SNikolas Klauser TEST_CONSTEXPR alloc_imp() : active(true) {} 27d107be84SMarshall Clow 287b9e4ebbSBilly Robert O'Neal III template <class T> 29d107be84SMarshall Clow T* allocate(std::size_t n) 30d107be84SMarshall Clow { 31d107be84SMarshall Clow if (active) 32d107be84SMarshall Clow return static_cast<T*>(std::malloc(n * sizeof(T))); 33d107be84SMarshall Clow else 34d107be84SMarshall Clow throw std::bad_alloc(); 35d107be84SMarshall Clow } 36d107be84SMarshall Clow 377b9e4ebbSBilly Robert O'Neal III template <class T> 38d107be84SMarshall Clow void deallocate(T* p, std::size_t) { std::free(p); } 39d107be84SMarshall Clow void activate () { active = true; } 40d107be84SMarshall Clow void deactivate() { active = false; } 41d107be84SMarshall Clow }; 42d107be84SMarshall Clow 43d107be84SMarshall Clow template <class T> 44d107be84SMarshall Clow struct poca_alloc { 45d107be84SMarshall Clow typedef T value_type; 46d107be84SMarshall Clow typedef std::true_type propagate_on_container_copy_assignment; 47d107be84SMarshall Clow 487b9e4ebbSBilly Robert O'Neal III alloc_imp *imp; 49d107be84SMarshall Clow 5085e9b268SNikolas Klauser TEST_CONSTEXPR poca_alloc(alloc_imp *imp_) : imp (imp_) {} 51d107be84SMarshall Clow 52d107be84SMarshall Clow template <class U> 5385e9b268SNikolas Klauser TEST_CONSTEXPR poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {} 54d107be84SMarshall Clow 557b9e4ebbSBilly Robert O'Neal III T* allocate (std::size_t n) { return imp->allocate<T>(n);} 56d107be84SMarshall Clow void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); } 57d107be84SMarshall Clow }; 58d107be84SMarshall Clow 59d107be84SMarshall Clow template <typename T, typename U> 60d107be84SMarshall Clow bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) 61d107be84SMarshall Clow { 62d107be84SMarshall Clow return lhs.imp == rhs.imp; 63d107be84SMarshall Clow } 64d107be84SMarshall Clow 65d107be84SMarshall Clow template <typename T, typename U> 66d107be84SMarshall Clow bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) 67d107be84SMarshall Clow { 68d107be84SMarshall Clow return lhs.imp != rhs.imp; 69d107be84SMarshall Clow } 70d107be84SMarshall Clow 716f033f0cSMarshall Clow template <class S> 7285e9b268SNikolas Klauser TEST_CONSTEXPR_CXX20 void test_assign(S &s1, const S& s2) 736f033f0cSMarshall Clow { 746f033f0cSMarshall Clow try { s1 = s2; } 756f033f0cSMarshall Clow catch ( std::bad_alloc &) { return; } 766f033f0cSMarshall Clow assert(false); 776f033f0cSMarshall Clow } 786f033f0cSMarshall Clow #endif 796f033f0cSMarshall Clow 80d107be84SMarshall Clow 81d107be84SMarshall Clow 825a83710eSEric Fiselier template <class S> 8385e9b268SNikolas Klauser TEST_CONSTEXPR_CXX20 void 845a83710eSEric Fiselier test(S s1, const typename S::allocator_type& a) 855a83710eSEric Fiselier { 865a83710eSEric Fiselier S s2(s1, a); 871f4231f8SEric Fiselier LIBCPP_ASSERT(s2.__invariants()); 885a83710eSEric Fiselier assert(s2 == s1); 895a83710eSEric Fiselier assert(s2.capacity() >= s2.size()); 905a83710eSEric Fiselier assert(s2.get_allocator() == a); 915a83710eSEric Fiselier } 925a83710eSEric Fiselier 93*425620ccSNikolas Klauser TEST_CONSTEXPR_CXX20 bool test() { 945a83710eSEric Fiselier { 955a83710eSEric Fiselier typedef test_allocator<char> A; 965a83710eSEric Fiselier typedef std::basic_string<char, std::char_traits<char>, A> S; 975a83710eSEric Fiselier test(S(), A(3)); 985a83710eSEric Fiselier test(S("1"), A(5)); 995a83710eSEric Fiselier test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7)); 1005a83710eSEric Fiselier } 1011f4231f8SEric Fiselier #if TEST_STD_VER >= 11 1025a83710eSEric Fiselier { 1035a83710eSEric Fiselier typedef min_allocator<char> A; 1045a83710eSEric Fiselier typedef std::basic_string<char, std::char_traits<char>, A> S; 1055a83710eSEric Fiselier test(S(), A()); 1065a83710eSEric Fiselier test(S("1"), A()); 1075a83710eSEric Fiselier test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A()); 1085a83710eSEric Fiselier } 109d107be84SMarshall Clow 110d107be84SMarshall Clow #ifndef TEST_HAS_NO_EXCEPTIONS 11185e9b268SNikolas Klauser if (!TEST_IS_CONSTANT_EVALUATED) { 112d107be84SMarshall Clow typedef poca_alloc<char> A; 113d107be84SMarshall Clow typedef std::basic_string<char, std::char_traits<char>, A> S; 114d107be84SMarshall Clow const char * p1 = "This is my first string"; 115d107be84SMarshall Clow const char * p2 = "This is my second string"; 116d107be84SMarshall Clow 1177b9e4ebbSBilly Robert O'Neal III alloc_imp imp1; 1187b9e4ebbSBilly Robert O'Neal III alloc_imp imp2; 119d107be84SMarshall Clow S s1(p1, A(&imp1)); 120d107be84SMarshall Clow S s2(p2, A(&imp2)); 121d107be84SMarshall Clow 122d107be84SMarshall Clow assert(s1 == p1); 123d107be84SMarshall Clow assert(s2 == p2); 124d107be84SMarshall Clow 125d107be84SMarshall Clow imp2.deactivate(); 126d107be84SMarshall Clow test_assign(s1, s2); 127d107be84SMarshall Clow assert(s1 == p1); 128d107be84SMarshall Clow assert(s2 == p2); 129d107be84SMarshall Clow } 130d107be84SMarshall Clow #endif 1315a83710eSEric Fiselier #endif 1322df59c50SJF Bastien 133e85018b7SNikolas Klauser return true; 134e85018b7SNikolas Klauser } 135e85018b7SNikolas Klauser 136e85018b7SNikolas Klauser int main(int, char**) 137e85018b7SNikolas Klauser { 138e85018b7SNikolas Klauser test(); 139e85018b7SNikolas Klauser #if TEST_STD_VER > 17 140*425620ccSNikolas Klauser static_assert(test()); 141e85018b7SNikolas Klauser #endif 142e85018b7SNikolas Klauser 1432df59c50SJF Bastien return 0; 1445a83710eSEric Fiselier } 145