1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef SUPPORT_INSERT_RANGE_HELPERS_H
10 #define SUPPORT_INSERT_RANGE_HELPERS_H
19 #include <type_traits>
20 #include <unordered_map>
21 #include <unordered_set>
24 #include "exception_safety_helpers.h"
25 #include "from_range_helpers.h"
26 #include "min_allocator.h"
27 #include "test_allocator.h"
28 #include "test_iterators.h"
29 #include "test_macros.h"
30 #include "type_algorithms.h"
32 // A simple literal-type container. It can be used as a `constexpr` global variable (which isn't supported by
34 template <class T
, std::size_t N
= 32>
37 constexpr Buffer() = default;
39 constexpr Buffer(std::initializer_list
<T
> input
) {
40 assert(input
.size() <= N
);
41 std::ranges::copy(input
, data_
);
45 // Makes initializing `Buffer<char>` nicer -- allows writing `buf = "abc"` instead of `buf = {'a', 'b', 'c'}`.
46 // To make the two forms equivalent, omits the terminating null.
47 template <std::size_t N2
>
48 constexpr Buffer(const char (&input
) [N2
])
49 requires
std::same_as
<T
, char> {
50 static_assert(N2
<= N
);
51 std::ranges::copy(input
, data_
);
52 // Omit the terminating null.
53 size_
= input
[N2
- 1] == '\0' ? N2
- 1 : N2
;
56 constexpr const T
* begin() const { return data_
; }
57 constexpr const T
* end() const { return data_
+ size_
; }
58 constexpr std::size_t size() const { return size_
; }
61 std::size_t size_
= 0;
68 std::size_t index
= 0;
73 template <class T
, class PtrT
, class Func
>
74 constexpr void for_all_iterators_and_allocators(Func f
) {
75 using Iterators
= types::type_list
<
76 cpp20_input_iterator
<PtrT
>,
77 forward_iterator
<PtrT
>,
78 bidirectional_iterator
<PtrT
>,
79 random_access_iterator
<PtrT
>,
80 contiguous_iterator
<PtrT
>,
84 types::for_each(Iterators
{}, [=]<class Iter
>() {
85 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, std::allocator
<T
>>();
86 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, test_allocator
<T
>>();
87 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, min_allocator
<T
>>();
88 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, safe_allocator
<T
>>();
90 if constexpr (std::sentinel_for
<Iter
, Iter
>) {
91 f
.template operator()<Iter
, Iter
, std::allocator
<T
>>();
92 f
.template operator()<Iter
, Iter
, test_allocator
<T
>>();
93 f
.template operator()<Iter
, Iter
, min_allocator
<T
>>();
94 f
.template operator()<Iter
, Iter
, safe_allocator
<T
>>();
99 // Uses a shorter list of iterator types for use in `constexpr` mode for cases when running the full set in would take
101 template <class T
, class PtrT
, class Func
>
102 constexpr void for_all_iterators_and_allocators_constexpr(Func f
) {
103 using Iterators
= types::type_list
<
104 cpp20_input_iterator
<PtrT
>,
105 forward_iterator
<PtrT
>,
109 types::for_each(Iterators
{}, [=]<class Iter
>() {
110 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, std::allocator
<T
>>();
111 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, test_allocator
<T
>>();
112 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, min_allocator
<T
>>();
113 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, safe_allocator
<T
>>();
115 if constexpr (std::sentinel_for
<Iter
, Iter
>) {
116 f
.template operator()<Iter
, Iter
, std::allocator
<T
>>();
117 f
.template operator()<Iter
, Iter
, test_allocator
<T
>>();
118 f
.template operator()<Iter
, Iter
, min_allocator
<T
>>();
119 f
.template operator()<Iter
, Iter
, safe_allocator
<T
>>();
124 #endif // SUPPORT_INSERT_RANGE_HELPERS_H