1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LIBCPP_TEST_STD_UTILITIES_MEMORY_SPECIALIZED_ALGORITHMS_OVERLOAD_COMPARE_ITERATOR_H
11#define LIBCPP_TEST_STD_UTILITIES_MEMORY_SPECIALIZED_ALGORITHMS_OVERLOAD_COMPARE_ITERATOR_H
12
13#include <iterator>
14#include <memory>
15
16#include "test_macros.h"
17
18// An iterator type that overloads operator== and operator!= without any constraints, which
19// can trip up some algorithms if we compare iterators against types that we're not allowed to.
20//
21// See https://github.com/llvm/llvm-project/issues/69334 for details.
22template <class Iterator>
23struct overload_compare_iterator {
24 using value_type = typename std::iterator_traits<Iterator>::value_type;
25 using difference_type = typename std::iterator_traits<Iterator>::difference_type;
26 using reference = typename std::iterator_traits<Iterator>::reference;
27 using pointer = typename std::iterator_traits<Iterator>::pointer;
28 using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
29
30 overload_compare_iterator() = default;
31
32 explicit overload_compare_iterator(Iterator it) : it_(it) {}
33
34 overload_compare_iterator(overload_compare_iterator const&) = default;
35 overload_compare_iterator(overload_compare_iterator&&) = default;
36 overload_compare_iterator& operator=(overload_compare_iterator const&) = default;
37 overload_compare_iterator& operator=(overload_compare_iterator&&) = default;
38
39 reference operator*() const TEST_NOEXCEPT { return *it_; }
40
41 pointer operator->() const TEST_NOEXCEPT { return std::addressof(*it_); }
42
43 overload_compare_iterator& operator++() TEST_NOEXCEPT {
44 ++it_;
45 return *this;
46 }
47
48 overload_compare_iterator operator++(int) const TEST_NOEXCEPT {
49 overload_compare_iterator old(*this);
50 ++(*this);
51 return old;
52 }
53
54 bool operator==(overload_compare_iterator const& other) const TEST_NOEXCEPT { return this->it_ == other.it_; }
55
56 bool operator!=(overload_compare_iterator const& other) const TEST_NOEXCEPT { return !this->operator==(other); }
57
58 // Hostile overloads
59 template <class Sentinel>
60 friend bool operator==(overload_compare_iterator const& lhs, Sentinel const& rhs) TEST_NOEXCEPT {
61 return static_cast<Iterator const&>(lhs) == rhs;
62 }
63
64 template <class Sentinel>
65 friend bool operator!=(overload_compare_iterator const& lhs, Sentinel const& rhs) TEST_NOEXCEPT {
66 return static_cast<Iterator const&>(lhs) != rhs;
67 }
68
69private:
70 Iterator it_;
71};
72
73#endif // LIBCPP_TEST_STD_UTILITIES_MEMORY_SPECIALIZED_ALGORITHMS_OVERLOAD_COMPARE_ITERATOR_H
74

source code of libcxx/test/std/utilities/memory/specialized.algorithms/overload_compare_iterator.h