xref: /llvm-project/libcxx/test/std/strings/basic.string/string.capacity/deallocate_size.pass.cpp (revision f71ea0e72e2419691e3c67bdbbe338d314ee77c0)
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 //===----------------------------------------------------------------------===//
8 
9 // <string>
10 
11 // Make sure the size we allocate and deallocate match. See https://github.com/llvm/llvm-project/pull/90292.
12 
13 #include <string>
14 #include <cassert>
15 #include <cstdint>
16 #include <type_traits>
17 
18 #include "test_macros.h"
19 
20 static int allocated_;
21 
22 template <class T, class Sz>
23 struct test_alloc {
24   typedef Sz size_type;
25   typedef typename std::make_signed<Sz>::type difference_type;
26   typedef T value_type;
27   typedef value_type* pointer;
28   typedef const value_type* const_pointer;
29   typedef typename std::add_lvalue_reference<value_type>::type reference;
30   typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
31 
32   template <class U>
33   struct rebind {
34     typedef test_alloc<U, Sz> other;
35   };
36 
37   TEST_CONSTEXPR test_alloc() TEST_NOEXCEPT {}
38 
39   template <class U>
40   TEST_CONSTEXPR test_alloc(const test_alloc<U, Sz>&) TEST_NOEXCEPT {}
41 
42   pointer allocate(size_type n, const void* = nullptr) {
43     allocated_ += n;
44     return std::allocator<value_type>().allocate(n);
45   }
46 
47   void deallocate(pointer p, size_type s) {
48     allocated_ -= s;
49     std::allocator<value_type>().deallocate(p, s);
50   }
51 
52   template <class U>
53   friend TEST_CONSTEXPR bool operator==(const test_alloc&, const test_alloc<U, Sz>&) TEST_NOEXCEPT {
54     return true;
55   }
56 
57 #if TEST_STD_VER < 20
58   template <class U>
59   friend TEST_CONSTEXPR bool operator!=(const test_alloc&, const test_alloc<U, Sz>&) TEST_NOEXCEPT {
60     return false;
61   }
62 #endif
63 };
64 
65 template <class Sz>
66 void test() {
67   for (int i = 1; i < 1000; ++i) {
68     using Str = std::basic_string<char, std::char_traits<char>, test_alloc<char, Sz> >;
69     {
70       Str s(i, 't');
71       assert(allocated_ == 0 || allocated_ >= i);
72     }
73   }
74   assert(allocated_ == 0);
75 }
76 
77 int main(int, char**) {
78   test<uint32_t>();
79   test<uint64_t>();
80   test<size_t>();
81 
82   return 0;
83 }
84