brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · edf1d6c Raw
115 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef SUPPORT_FROM_RANGE_HELPERS_H10#define SUPPORT_FROM_RANGE_HELPERS_H11 12#include <array>13#include <cstddef>14#include <iterator>15#include <type_traits>16#include <vector>17 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"23 24struct Empty {};25 26template <class T>27struct InputRange {28  cpp20_input_iterator<T*> begin();29  sentinel_wrapper<cpp20_input_iterator<T*>> end();30};31 32template <class Iter, class Sent, std::ranges::input_range Range>33constexpr 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));37}38 39template <class Iter, class Sent, class T, std::size_t N>40constexpr 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));44}45 46template <class Iter, class Sent, class T>47constexpr 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));51}52 53struct KeyValue {54  int key;    // Only the key is considered for equality comparison.55  char value; // Allows distinguishing equivalent instances.56 57  bool operator<(const KeyValue& other) const { return key < other.key; }58  bool operator==(const KeyValue& other) const { return key == other.key; }59};60 61template <>62struct std::hash<KeyValue> {63  std::size_t operator()(const KeyValue& kv) const { return kv.key; }64};65 66#if !defined(TEST_HAS_NO_EXCEPTIONS)67 68template <class T>69struct ThrowingAllocator {70  using value_type      = T;71  using char_type       = T;72  using is_always_equal = std::false_type;73 74  ThrowingAllocator() = default;75 76  template <class U>77  ThrowingAllocator(const ThrowingAllocator<U>&) {}78 79  T* allocate(std::size_t) { throw 1; }80  void deallocate(T*, std::size_t) {}81 82  template <class U>83  friend bool operator==(const ThrowingAllocator&, const ThrowingAllocator<U>&) {84    return true;85  }86};87#endif88 89template <class T, class Func>90constexpr void for_all_iterators_and_allocators(Func f) {91  using Iterators =92      types::type_list< cpp20_input_iterator<T*>,93                        forward_iterator<T*>,94                        bidirectional_iterator<T*>,95                        random_access_iterator<T*>,96                        contiguous_iterator<T*>,97                        T* >;98 99  types::for_each(Iterators{}, [=]<class Iter>() {100    f.template operator()<Iter, sentinel_wrapper<Iter>, std::allocator<T>>();101    f.template operator()<Iter, sentinel_wrapper<Iter>, test_allocator<T>>();102    f.template operator()<Iter, sentinel_wrapper<Iter>, min_allocator<T>>();103    f.template operator()<Iter, sentinel_wrapper<Iter>, safe_allocator<T>>();104 105    if constexpr (std::sentinel_for<Iter, Iter>) {106      f.template operator()<Iter, Iter, std::allocator<T>>();107      f.template operator()<Iter, Iter, test_allocator<T>>();108      f.template operator()<Iter, Iter, min_allocator<T>>();109      f.template operator()<Iter, Iter, safe_allocator<T>>();110    }111  });112}113 114#endif // SUPPORT_FROM_RANGE_HELPERS_H115