proxygen
Enumerate.h
Go to the documentation of this file.
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <iterator>
20 #include <memory>
21 
22 #include <folly/CPortability.h>
24 
47 namespace folly {
48 
49 namespace detail {
50 
51 template <class T>
52 struct MakeConst {
53  using type = const T;
54 };
55 template <class T>
56 struct MakeConst<T&> {
57  using type = const T&;
58 };
59 template <class T>
60 struct MakeConst<T*> {
61  using type = const T*;
62 };
63 
64 // Raw pointers don't have an operator->() member function, so the
65 // second overload will be SFINAEd out in that case. Otherwise, the
66 // second is preferred in the partial order for getPointer(_, 0).
67 template <class Iterator>
68 FOLLY_ALWAYS_INLINE auto getPointer(const Iterator& it, long)
69  -> decltype(std::addressof(*it)) {
70  return std::addressof(*it);
71 }
72 template <class Iterator>
73 FOLLY_ALWAYS_INLINE auto getPointer(const Iterator& it, int)
74  -> decltype(it.operator->()) {
75  return it.operator->();
76 }
77 
78 template <class Iterator>
79 class Enumerator {
80  public:
81  explicit Enumerator(Iterator it) : it_(std::move(it)) {}
82 
83  class Proxy {
84  public:
85  using difference_type = ssize_t;
86  using value_type = typename std::iterator_traits<Iterator>::value_type;
87  using reference = typename std::iterator_traits<Iterator>::reference;
88  using pointer = typename std::iterator_traits<Iterator>::pointer;
89  using iterator_category = std::input_iterator_tag;
90 
92  : it_(e.it_), index(e.idx_) {}
93 
94  // Non-const Proxy: Forward constness from Iterator.
96  return *it_;
97  }
99  return getPointer(it_, 0);
100  }
101 
102  // Const Proxy: Force const references.
104  return *it_;
105  }
107  return getPointer(it_, 0);
108  }
109 
110  private:
111  const Iterator& it_;
112 
113  public:
114  const size_t index;
115  };
116 
118  return Proxy(*this);
119  }
120 
122  ++it_;
123  ++idx_;
124  return *this;
125  }
126 
127  template <typename OtherIterator>
129  const Enumerator<OtherIterator>& rhs) const {
130  return it_ == rhs.it_;
131  }
132 
133  template <typename OtherIterator>
135  const Enumerator<OtherIterator>& rhs) const {
136  return !(it_ == rhs.it_);
137  }
138 
139  private:
140  template <typename OtherIterator>
141  friend class Enumerator;
142 
143  Iterator it_;
144  size_t idx_ = 0;
145 };
146 
147 template <class Range>
150  using BeginIteratorType = decltype(std::declval<Range>().begin());
151  using EndIteratorType = decltype(std::declval<Range>().end());
152 
153  public:
154  explicit RangeEnumerator(Range&& r) : r_(std::forward<Range>(r)) {}
155 
158  }
160  return Enumerator<EndIteratorType>(r_.end());
161  }
162 };
163 
164 } // namespace detail
165 
166 template <class Range>
168  return detail::RangeEnumerator<Range>(std::forward<Range>(r));
169 }
170 
171 } // namespace folly
FOLLY_ALWAYS_INLINE bool operator!=(const Enumerator< OtherIterator > &rhs) const
Definition: Enumerate.h:134
FOLLY_ALWAYS_INLINE MakeConst< reference >::type operator*() const
Definition: Enumerate.h:103
#define FOLLY_ALWAYS_INLINE
Definition: CPortability.h:151
FOLLY_ALWAYS_INLINE Proxy(const Enumerator &e)
Definition: Enumerate.h:91
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
FOLLY_ALWAYS_INLINE auto getPointer(const Iterator &it, long) -> decltype(std::addressof(*it))
Definition: Enumerate.h:68
STL namespace.
auto begin(TestAdlIterable &instance)
Definition: ForeachTest.cpp:56
folly::std T
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
FOLLY_ALWAYS_INLINE bool operator==(const Enumerator< OtherIterator > &rhs) const
Definition: Enumerate.h:128
Enumerator(Iterator it)
Definition: Enumerate.h:81
std::input_iterator_tag iterator_category
Definition: Enumerate.h:89
FOLLY_PUSH_WARNING RHS rhs
Definition: Traits.h:649
typename std::iterator_traits< Iterator >::pointer pointer
Definition: Enumerate.h:88
Enumerator< BeginIteratorType > begin()
Definition: Enumerate.h:156
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
FOLLY_ALWAYS_INLINE reference operator*()
Definition: Enumerate.h:95
typename std::iterator_traits< Iterator >::value_type value_type
Definition: Enumerate.h:86
FOLLY_ALWAYS_INLINE MakeConst< pointer >::type operator->() const
Definition: Enumerate.h:106
detail::RangeEnumerator< Range > enumerate(Range &&r)
Definition: Enumerate.h:167
constexpr Iter end() const
Definition: Range.h:455
constexpr Iter begin() const
Definition: Range.h:452
typename std::iterator_traits< Iterator >::reference reference
Definition: Enumerate.h:87
FOLLY_ALWAYS_INLINE Proxy operator*() const
Definition: Enumerate.h:117
FOLLY_ALWAYS_INLINE pointer operator->()
Definition: Enumerate.h:98
FOLLY_ALWAYS_INLINE Enumerator & operator++()
Definition: Enumerate.h:121
decltype(std::declval< Range >().end()) EndIteratorType
Definition: Enumerate.h:151
decltype(std::declval< Range >().begin()) BeginIteratorType
Definition: Enumerate.h:150
Enumerator< EndIteratorType > end()
Definition: Enumerate.h:159