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// size_type max_size() const;
13
14#include <algorithm>
15#include <cassert>
16#include <climits>
17#include <cstdint>
18#include <limits>
19#include <memory>
20#include <type_traits>
21#include <vector>
22
23#include "min_allocator.h"
24#include "sized_allocator.h"
25#include "test_allocator.h"
26#include "test_macros.h"
27
28#if TEST_STD_VER >= 11
29
30template <typename Alloc>
31TEST_CONSTEXPR_CXX20 void test(const std::vector<bool, Alloc>& v) {
32 using Vector = std::vector<bool, Alloc>;
33 using size_type = typename Vector::size_type;
34 using difference_type = typename Vector::difference_type;
35 const size_type max_dist = static_cast<size_type>(std::numeric_limits<difference_type>::max());
36 assert(v.max_size() <= max_dist);
37
38 // The following check is specific to libc++ implementation details and is not portable to libstdc++
39 // and MSVC STL, as they use different types for the underlying word storage.
40# if defined(_LIBCPP_VERSION)
41 using storage_type = typename Vector::__storage_type;
42 using storage_alloc = typename std::allocator_traits<Alloc>::template rebind_alloc<storage_type>;
43 using storage_traits = typename std::allocator_traits<Alloc>::template rebind_traits<storage_type>;
44 const size_type max_alloc = storage_traits::max_size(storage_alloc(v.get_allocator()));
45 std::size_t bits_per_word = sizeof(storage_type) * CHAR_BIT;
46 const size_type max_size = max_dist / bits_per_word < max_alloc ? max_dist : max_alloc * bits_per_word;
47 assert(v.max_size() / bits_per_word <= max_alloc); // max_alloc * bits_per_word may overflow
48 assert(v.max_size() == max_size);
49# endif // defined(_LIBCPP_VERSION)
50}
51
52#endif // TEST_STD_VER >= 11
53
54TEST_CONSTEXPR_CXX20 bool tests() {
55 // The following check is specific to libc++ implementation details and is not portable to libstdc++
56 // and MSVC STL, as they use different types for the underlying word storage.
57#if defined(_LIBCPP_VERSION)
58 // Test cases where v.max_size() is determined by allocator::max_size()
59 {
60 using Alloc = limited_allocator<bool, 10>;
61 using Vector = std::vector<bool, Alloc>;
62 using storage_type = Vector::__storage_type;
63 Vector v;
64 std::size_t bits_per_word = sizeof(storage_type) * CHAR_BIT;
65 assert(v.max_size() == 10 * bits_per_word);
66 }
67#endif // defined(_LIBCPP_VERSION)
68
69#if TEST_STD_VER >= 11
70
71 // Test with various allocators and different `size_type`s
72 {
73 test(std::vector<bool>());
74 test(std::vector<bool, std::allocator<bool> >());
75 test(std::vector<bool, min_allocator<bool> >());
76 test(std::vector<bool, test_allocator<bool> >(test_allocator<bool>(1)));
77 test(std::vector<bool, other_allocator<bool> >(other_allocator<bool>(5)));
78 test(std::vector<bool, sized_allocator<bool, std::uint8_t, std::int8_t> >());
79 test(std::vector<bool, sized_allocator<bool, std::uint16_t, std::int16_t> >());
80 test(std::vector<bool, sized_allocator<bool, std::uint32_t, std::int32_t> >());
81 test(std::vector<bool, sized_allocator<bool, std::uint64_t, std::int64_t> >());
82 test(std::vector<bool, limited_allocator<bool, static_cast<std::size_t>(-1)> >());
83 }
84
85 // Test cases to identify incorrect implementations that unconditionally compute an internal-to-external
86 // capacity in a way that can overflow, leading to incorrect results.
87 {
88 test(std::vector<bool, limited_allocator<bool, static_cast<std::size_t>(-1) / 61> >());
89 test(std::vector<bool, limited_allocator<bool, static_cast<std::size_t>(-1) / 63> >());
90 }
91
92#endif // TEST_STD_VER >= 11
93
94 return true;
95}
96
97int main(int, char**) {
98 tests();
99
100#if TEST_STD_VER >= 20
101 static_assert(tests());
102#endif
103
104 return 0;
105}
106

source code of libcxx/test/std/containers/sequences/vector.bool/max_size.pass.cpp