Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / test / std / strings / basic.string / string.cons / copy_alloc.pass.cpp
blob6b0040376a424ec1afd709707f82e8d831c2798a
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 // <string>
11 // basic_string(const basic_string& str, const Allocator& alloc); // constexpr since C++20
13 #include <string>
14 #include <cassert>
16 #include "test_macros.h"
17 #include "test_allocator.h"
18 #include "min_allocator.h"
20 #ifndef TEST_HAS_NO_EXCEPTIONS
21 struct alloc_imp {
22 bool active;
24 TEST_CONSTEXPR alloc_imp() : active(true) {}
26 template <class T>
27 T* allocate(std::size_t n) {
28 if (active)
29 return static_cast<T*>(std::malloc(n * sizeof(T)));
30 else
31 throw std::bad_alloc();
34 template <class T>
35 void deallocate(T* p, std::size_t) {
36 std::free(p);
38 void activate() { active = true; }
39 void deactivate() { active = false; }
42 template <class T>
43 struct poca_alloc {
44 typedef T value_type;
45 typedef std::true_type propagate_on_container_copy_assignment;
47 alloc_imp* imp;
49 TEST_CONSTEXPR poca_alloc(alloc_imp* imp_) : imp(imp_) {}
51 template <class U>
52 TEST_CONSTEXPR poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {}
54 T* allocate(std::size_t n) { return imp->allocate<T>(n); }
55 void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); }
58 template <typename T, typename U>
59 bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) {
60 return lhs.imp == rhs.imp;
63 template <typename T, typename U>
64 bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) {
65 return lhs.imp != rhs.imp;
68 template <class S>
69 TEST_CONSTEXPR_CXX20 void test_assign(S& s1, const S& s2) {
70 try {
71 s1 = s2;
72 } catch (std::bad_alloc&) {
73 return;
75 assert(false);
77 #endif
79 template <class S>
80 TEST_CONSTEXPR_CXX20 void test(S s1, const typename S::allocator_type& a) {
81 S s2(s1, a);
82 LIBCPP_ASSERT(s2.__invariants());
83 assert(s2 == s1);
84 assert(s2.capacity() >= s2.size());
85 assert(s2.get_allocator() == a);
88 template <class Alloc>
89 TEST_CONSTEXPR_CXX20 void test_string(const Alloc& a) {
90 typedef std::basic_string<char, std::char_traits<char>, Alloc> S;
91 test(S(), Alloc(a));
92 test(S("1"), Alloc(a));
93 test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), Alloc(a));
96 TEST_CONSTEXPR_CXX20 bool test() {
97 test_string(std::allocator<char>());
98 test_string(test_allocator<char>());
99 test_string(test_allocator<char>(3));
100 #if TEST_STD_VER >= 11
101 test_string(min_allocator<char>());
102 #endif
104 #if TEST_STD_VER >= 11
105 # ifndef TEST_HAS_NO_EXCEPTIONS
106 if (!TEST_IS_CONSTANT_EVALUATED) {
107 typedef poca_alloc<char> A;
108 typedef std::basic_string<char, std::char_traits<char>, A> S;
109 const char* p1 = "This is my first string";
110 const char* p2 = "This is my second string";
112 alloc_imp imp1;
113 alloc_imp imp2;
114 S s1(p1, A(&imp1));
115 S s2(p2, A(&imp2));
117 assert(s1 == p1);
118 assert(s2 == p2);
120 imp2.deactivate();
121 test_assign(s1, s2);
122 assert(s1 == p1);
123 assert(s2 == p2);
125 # endif
126 #endif
128 return true;
131 int main(int, char**) {
132 test();
133 #if TEST_STD_VER > 17
134 static_assert(test());
135 #endif
137 return 0;