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_FROM_RANGE_HELPERS_H
10 #define SUPPORT_FROM_RANGE_HELPERS_H
15 #include <type_traits>
18 #include "min_allocator.h"
19 #include "test_allocator.h"
20 #include "test_iterators.h"
21 #include "test_macros.h"
22 #include "type_algorithms.h"
28 cpp20_input_iterator
<T
*> begin();
29 sentinel_wrapper
<cpp20_input_iterator
<T
*>> end();
32 template <class Iter
, class Sent
, std::ranges::input_range Range
>
33 constexpr auto wrap_input(Range
&& input
) {
34 auto b
= Iter(std::ranges::begin(input
));
35 auto e
= Sent(Iter(std::ranges::end(input
)));
36 return std::ranges::subrange(std::move(b
), std::move(e
));
39 template <class Iter
, class Sent
, class T
, std::size_t N
>
40 constexpr auto wrap_input(std::array
<T
, N
>& input
) {
41 auto b
= Iter(input
.data());
42 auto e
= Sent(Iter(input
.data() + input
.size()));
43 return std::ranges::subrange(std::move(b
), std::move(e
));
46 template <class Iter
, class Sent
, class T
>
47 constexpr auto wrap_input(std::vector
<T
>& input
) {
48 auto b
= Iter(input
.data());
49 auto e
= Sent(Iter(input
.data() + input
.size()));
50 return std::ranges::subrange(std::move(b
), std::move(e
));
54 int key
; // Only the key is considered for equality comparison.
55 char value
; // Allows distinguishing equivalent instances.
57 bool operator<(const KeyValue
& other
) const { return key
< other
.key
; }
58 bool operator==(const KeyValue
& other
) const { return key
== other
.key
; }
62 struct std::hash
<KeyValue
> {
63 std::size_t operator()(const KeyValue
& kv
) const {
68 #if !defined(TEST_HAS_NO_EXCEPTIONS)
71 struct ThrowingAllocator
{
74 using is_always_equal
= std::false_type
;
76 ThrowingAllocator() = default;
79 ThrowingAllocator(const ThrowingAllocator
<U
>&) {}
81 T
* allocate(std::size_t) { throw 1; }
82 void deallocate(T
*, std::size_t) {}
85 friend bool operator==(const ThrowingAllocator
&, const ThrowingAllocator
<U
>&) {
91 template <class T
, class Func
>
92 constexpr void for_all_iterators_and_allocators(Func f
) {
93 using Iterators
= types::type_list
<
94 cpp20_input_iterator
<T
*>,
96 bidirectional_iterator
<T
*>,
97 random_access_iterator
<T
*>,
98 contiguous_iterator
<T
*>,
102 types::for_each(Iterators
{}, [=]<class Iter
>() {
103 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, std::allocator
<T
>>();
104 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, test_allocator
<T
>>();
105 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, min_allocator
<T
>>();
106 f
.template operator()<Iter
, sentinel_wrapper
<Iter
>, safe_allocator
<T
>>();
108 if constexpr (std::sentinel_for
<Iter
, Iter
>) {
109 f
.template operator()<Iter
, Iter
, std::allocator
<T
>>();
110 f
.template operator()<Iter
, Iter
, test_allocator
<T
>>();
111 f
.template operator()<Iter
, Iter
, min_allocator
<T
>>();
112 f
.template operator()<Iter
, Iter
, safe_allocator
<T
>>();
117 #endif // SUPPORT_FROM_RANGE_HELPERS_H