| //===----------------------------------------------------------------------===// | 
 | // | 
 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
 | // See https://llvm.org/LICENSE.txt for license information. | 
 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #ifndef SUPPORT_INSERT_RANGE_HELPERS_H | 
 | #define SUPPORT_INSERT_RANGE_HELPERS_H | 
 |  | 
 | #include <algorithm> | 
 | #include <array> | 
 | #include <cassert> | 
 | #include <concepts> | 
 | #include <map> | 
 | #include <ranges> | 
 | #include <set> | 
 | #include <type_traits> | 
 | #include <unordered_map> | 
 | #include <unordered_set> | 
 | #include <vector> | 
 |  | 
 | #include "exception_safety_helpers.h" | 
 | #include "from_range_helpers.h" | 
 | #include "min_allocator.h" | 
 | #include "test_allocator.h" | 
 | #include "test_iterators.h" | 
 | #include "test_macros.h" | 
 | #include "type_algorithms.h" | 
 |  | 
 | // A simple literal-type container. It can be used as a `constexpr` global variable (which isn't supported by | 
 | // `std::vector`). | 
 | template <class T, std::size_t N = 32> | 
 | class Buffer { | 
 |  public: | 
 |   constexpr Buffer() = default; | 
 |  | 
 |   constexpr Buffer(std::initializer_list<T> input) { | 
 |     assert(input.size() <= N); | 
 |     std::ranges::copy(input, data_); | 
 |     size_ = input.size(); | 
 |   } | 
 |  | 
 |   // Makes initializing `Buffer<char>` nicer -- allows writing `buf = "abc"` instead of `buf = {'a', 'b', 'c'}`. | 
 |   // To make the two forms equivalent, omits the terminating null. | 
 |   template <std::size_t N2> | 
 |   constexpr Buffer(const char (&input) [N2]) | 
 |   requires std::same_as<T, char> { | 
 |     static_assert(N2 <= N); | 
 |     std::ranges::copy(input, data_); | 
 |     // Omit the terminating null. | 
 |     size_ = input[N2 - 1] == '\0' ? N2 - 1 : N2; | 
 |   } | 
 |  | 
 |   constexpr const T* begin() const { return data_; } | 
 |   constexpr const T* end() const { return data_ + size_; } | 
 |   constexpr std::size_t size() const { return size_; } | 
 |  | 
 |  private: | 
 |   std::size_t size_ = 0; | 
 |   T data_[N] = {}; | 
 | }; | 
 |  | 
 | template <class T> | 
 | struct TestCase { | 
 |   Buffer<T> initial; | 
 |   std::size_t index = 0; | 
 |   Buffer<T> input; | 
 |   Buffer<T> expected; | 
 | }; | 
 |  | 
 | template <class T, class PtrT, class Func> | 
 | constexpr void for_all_iterators_and_allocators(Func f) { | 
 |   using Iterators = types::type_list< | 
 |     cpp20_input_iterator<PtrT>, | 
 |     forward_iterator<PtrT>, | 
 |     bidirectional_iterator<PtrT>, | 
 |     random_access_iterator<PtrT>, | 
 |     contiguous_iterator<PtrT>, | 
 |     PtrT | 
 |   >; | 
 |  | 
 |   types::for_each(Iterators{}, [=]<class Iter>() { | 
 |     f.template operator()<Iter, sentinel_wrapper<Iter>, std::allocator<T>>(); | 
 |     f.template operator()<Iter, sentinel_wrapper<Iter>, test_allocator<T>>(); | 
 |     f.template operator()<Iter, sentinel_wrapper<Iter>, min_allocator<T>>(); | 
 |     f.template operator()<Iter, sentinel_wrapper<Iter>, safe_allocator<T>>(); | 
 |  | 
 |     if constexpr (std::sentinel_for<Iter, Iter>) { | 
 |       f.template operator()<Iter, Iter, std::allocator<T>>(); | 
 |       f.template operator()<Iter, Iter, test_allocator<T>>(); | 
 |       f.template operator()<Iter, Iter, min_allocator<T>>(); | 
 |       f.template operator()<Iter, Iter, safe_allocator<T>>(); | 
 |     } | 
 |   }); | 
 | } | 
 |  | 
 | // Uses a shorter list of iterator types for use in `constexpr` mode for cases when running the full set in would take | 
 | // too long. | 
 | template <class T, class PtrT, class Func> | 
 | constexpr void for_all_iterators_and_allocators_constexpr(Func f) { | 
 |   using Iterators = types::type_list< | 
 |     cpp20_input_iterator<PtrT>, | 
 |     forward_iterator<PtrT>, | 
 |     PtrT | 
 |   >; | 
 |  | 
 |   types::for_each(Iterators{}, [=]<class Iter>() { | 
 |     f.template operator()<Iter, sentinel_wrapper<Iter>, std::allocator<T>>(); | 
 |     f.template operator()<Iter, sentinel_wrapper<Iter>, test_allocator<T>>(); | 
 |     f.template operator()<Iter, sentinel_wrapper<Iter>, min_allocator<T>>(); | 
 |     f.template operator()<Iter, sentinel_wrapper<Iter>, safe_allocator<T>>(); | 
 |  | 
 |     if constexpr (std::sentinel_for<Iter, Iter>) { | 
 |       f.template operator()<Iter, Iter, std::allocator<T>>(); | 
 |       f.template operator()<Iter, Iter, test_allocator<T>>(); | 
 |       f.template operator()<Iter, Iter, min_allocator<T>>(); | 
 |       f.template operator()<Iter, Iter, safe_allocator<T>>(); | 
 |     } | 
 |   }); | 
 | } | 
 |  | 
 | #endif // SUPPORT_INSERT_RANGE_HELPERS_H |