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 #ifndef TEST_STD_ITERATORS_ITERATOR_PRIMITIVES_RANGE_ITER_OPS_TYPES_H
10 #define TEST_STD_ITERATORS_ITERATOR_PRIMITIVES_RANGE_ITER_OPS_TYPES_H
11 
12 #include <cassert>
13 #include <cstddef>
14 #include <iterator>
15 #include <utility>
16 
17 #include "test_iterators.h" // for the fallthrough base() function
18 
19 class distance_apriori_sentinel {
20 public:
21   distance_apriori_sentinel() = default;
distance_apriori_sentinel(std::ptrdiff_t const count)22   constexpr explicit distance_apriori_sentinel(std::ptrdiff_t const count) : count_(count) {}
23 
24   constexpr bool operator==(std::input_or_output_iterator auto const&) const {
25     assert(false && "difference op should take precedence");
26     return false;
27   }
28 
29   friend constexpr std::ptrdiff_t operator-(std::input_or_output_iterator auto const&,
30                                             distance_apriori_sentinel const y) {
31     return -y.count_;
32   }
33 
34   friend constexpr std::ptrdiff_t operator-(distance_apriori_sentinel const x,
35                                             std::input_or_output_iterator auto const&) {
36     return x.count_;
37   }
38 
39 private:
40   std::ptrdiff_t count_ = 0;
41 };
42 
43 // Sentinel type that can be assigned to an iterator. This is to test the cases where the
44 // various iterator operations use assignment instead of successive increments/decrements.
45 template <class It>
46 class assignable_sentinel {
47 public:
48     explicit assignable_sentinel() = default;
assignable_sentinel(const It & it)49     constexpr explicit assignable_sentinel(const It& it) : base_(base(it)) {}
It()50     constexpr operator It() const { return It(base_); }
51     constexpr bool operator==(const It& other) const { return base_ == base(other); }
base(const assignable_sentinel & s)52     friend constexpr It base(const assignable_sentinel& s) { return It(s.base_); }
53 private:
54     decltype(base(std::declval<It>())) base_;
55 };
56 
57 template <class It>
58 assignable_sentinel(const It&) -> assignable_sentinel<It>;
59 
60 #endif // TEST_STD_ITERATORS_ITERATOR_PRIMITIVES_RANGE_ITER_OPS_TYPES_H
61