xref: /llvm-project/libcxx/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp (revision c2e438675754b83c31d7d5ba40cb13fe77e795de)
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 // <vector>
10 // vector<bool>
11 
12 // void shrink_to_fit();
13 
14 #include <vector>
15 #include <cassert>
16 
17 #include "test_macros.h"
18 #include "min_allocator.h"
19 
20 TEST_CONSTEXPR_CXX20 bool tests()
21 {
22     {
23         std::vector<bool> v(100);
24         v.push_back(1);
25         v.shrink_to_fit();
26         assert(v.capacity() >= 101);
27         assert(v.size() >= 101);
28     }
29 #if TEST_STD_VER >= 11
30     {
31         std::vector<bool, min_allocator<bool>> v(100);
32         v.push_back(1);
33         v.shrink_to_fit();
34         assert(v.capacity() >= 101);
35         assert(v.size() >= 101);
36     }
37 #endif
38 
39     return true;
40 }
41 
42 #if TEST_STD_VER >= 23
43 template <typename T>
44 struct increasing_allocator {
45   using value_type         = T;
46   std::size_t min_elements = 1000;
47   increasing_allocator()   = default;
48 
49   template <typename U>
50   constexpr increasing_allocator(const increasing_allocator<U>& other) noexcept : min_elements(other.min_elements) {}
51 
52   constexpr std::allocation_result<T*> allocate_at_least(std::size_t n) {
53     if (n < min_elements)
54       n = min_elements;
55     min_elements += 1000;
56     return std::allocator<T>{}.allocate_at_least(n);
57   }
58   constexpr T* allocate(std::size_t n) { return allocate_at_least(n).ptr; }
59   constexpr void deallocate(T* p, std::size_t n) noexcept { std::allocator<T>{}.deallocate(p, n); }
60 };
61 
62 template <typename T, typename U>
63 bool operator==(increasing_allocator<T>, increasing_allocator<U>) {
64   return true;
65 }
66 
67 // https://github.com/llvm/llvm-project/issues/95161
68 constexpr bool test_increasing_allocator() {
69   std::vector<bool, increasing_allocator<bool>> v;
70   v.push_back(1);
71   std::size_t capacity = v.capacity();
72   v.shrink_to_fit();
73   assert(v.capacity() <= capacity);
74   assert(v.size() == 1);
75 
76   return true;
77 }
78 #endif // TEST_STD_VER >= 23
79 
80 int main(int, char**)
81 {
82   tests();
83 #if TEST_STD_VER > 17
84     static_assert(tests());
85 #endif
86 #if TEST_STD_VER >= 23
87     test_increasing_allocator();
88     static_assert(test_increasing_allocator());
89 #endif // TEST_STD_VER >= 23
90 
91     return 0;
92 }
93