master
 1//===-- Standalone implementation of iterator -------------------*- C++ -*-===//
 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 LLVM_LIBC_SRC___SUPPORT_CPP_ITERATOR_H
10#define LLVM_LIBC_SRC___SUPPORT_CPP_ITERATOR_H
11
12#include "src/__support/CPP/type_traits/enable_if.h"
13#include "src/__support/CPP/type_traits/is_convertible.h"
14#include "src/__support/CPP/type_traits/is_same.h"
15#include "src/__support/macros/attributes.h"
16#include "src/__support/macros/config.h"
17
18namespace LIBC_NAMESPACE_DECL {
19namespace cpp {
20
21template <typename T> struct iterator_traits;
22template <typename T> struct iterator_traits<T *> {
23  using reference = T &;
24  using value_type = T;
25};
26
27template <typename Iter> class reverse_iterator {
28  Iter current;
29
30public:
31  using reference = typename iterator_traits<Iter>::reference;
32  using value_type = typename iterator_traits<Iter>::value_type;
33  using iterator_type = Iter;
34
35  LIBC_INLINE reverse_iterator() : current() {}
36  LIBC_INLINE constexpr explicit reverse_iterator(Iter it) : current(it) {}
37
38  template <typename Other,
39            cpp::enable_if_t<!cpp::is_same_v<Iter, Other> &&
40                                 cpp::is_convertible_v<const Other &, Iter>,
41                             int> = 0>
42  LIBC_INLINE constexpr explicit reverse_iterator(const Other &it)
43      : current(it) {}
44
45  LIBC_INLINE friend constexpr bool operator==(const reverse_iterator &lhs,
46                                               const reverse_iterator &rhs) {
47    return lhs.base() == rhs.base();
48  }
49
50  LIBC_INLINE friend constexpr bool operator!=(const reverse_iterator &lhs,
51                                               const reverse_iterator &rhs) {
52    return lhs.base() != rhs.base();
53  }
54
55  LIBC_INLINE friend constexpr bool operator<(const reverse_iterator &lhs,
56                                              const reverse_iterator &rhs) {
57    return lhs.base() > rhs.base();
58  }
59
60  LIBC_INLINE friend constexpr bool operator<=(const reverse_iterator &lhs,
61                                               const reverse_iterator &rhs) {
62    return lhs.base() >= rhs.base();
63  }
64
65  LIBC_INLINE friend constexpr bool operator>(const reverse_iterator &lhs,
66                                              const reverse_iterator &rhs) {
67    return lhs.base() < rhs.base();
68  }
69
70  LIBC_INLINE friend constexpr bool operator>=(const reverse_iterator &lhs,
71                                               const reverse_iterator &rhs) {
72    return lhs.base() <= rhs.base();
73  }
74
75  LIBC_INLINE constexpr iterator_type base() const { return current; }
76
77  LIBC_INLINE constexpr reference operator*() const {
78    Iter tmp = current;
79    return *--tmp;
80  }
81  LIBC_INLINE constexpr reverse_iterator operator--() {
82    ++current;
83    return *this;
84  }
85  LIBC_INLINE constexpr reverse_iterator &operator++() {
86    --current;
87    return *this;
88  }
89  LIBC_INLINE constexpr reverse_iterator operator++(int) {
90    reverse_iterator tmp(*this);
91    --current;
92    return tmp;
93  }
94};
95
96} // namespace cpp
97} // namespace LIBC_NAMESPACE_DECL
98
99#endif // LLVM_LIBC_SRC___SUPPORT_CPP_ITERATOR_H