RxCpp
The Reactive Extensions for Native (RxCpp) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators in both C and C++.
linq_iterators.hpp
Go to the documentation of this file.
1 // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
2 
3 #if !defined(CPPLINQ_LINQ_ITERATORS_HPP)
4 #define CPPLINQ_LINQ_ITERATORS_HPP
5 #pragma once
6 
7 #include <cstddef>
8 
9 namespace cpplinq {
10 
11  // if a member, provides the straightforward implementation of various redundant operators. For example,
12  // providing -> for any iterator providing *, and so forth.
14 
15  #define CPPLINQ_USE_DEFAULT_ITERATOR_OPERATORS \
16  operator ::cpplinq::use_default_iterator_operators() const { return ::cpplinq::use_default_iterator_operators(); }
17 
18  template <class Iter>
19  typename std::enable_if<
20  std::is_convertible<Iter, use_default_iterator_operators>::value,
21  Iter
22  >::type
23  operator+(const Iter& it, typename std::iterator_traits<Iter>::distance_type n) {
24  return it += n;
25  }
26  template <class Iter>
27  typename std::enable_if<
28  std::is_convertible<Iter, use_default_iterator_operators>::value,
29  Iter
30  >::type
31  operator-(const Iter& it, typename std::iterator_traits<Iter>::distance_type n) {
32  return it -= n;
33  }
34  template <class Iter>
35  typename std::enable_if<
36  std::is_convertible<Iter, use_default_iterator_operators>::value,
37  Iter
38  >::type
39  operator-=(const Iter& it, typename std::iterator_traits<Iter>::distance_type n) {
40  return it += (-n);
41  }
42 
43  template <class Iter>
44  typename std::enable_if<
45  std::is_convertible<Iter, use_default_iterator_operators>::value,
46  bool
47  >::type
48  operator!=(const Iter& it, const Iter& it2) {
49  return !(it == it2);
50  }
51  template <class Iter>
52  typename std::enable_if<
53  std::is_convertible<Iter, use_default_iterator_operators>::value,
54  bool
55  >::type
56  operator>(const Iter& it, const Iter& it2) {
57  return it2 < it;
58  }
59  template <class Iter>
60  typename std::enable_if<
61  std::is_convertible<Iter, use_default_iterator_operators>::value,
62  bool
63  >::type
64  operator<=(const Iter& it, const Iter& it2) {
65  return !(it2 < it);
66  }
67  template <class Iter>
68  typename std::enable_if<
69  std::is_convertible<Iter, use_default_iterator_operators>::value,
70  bool
71  >::type
72  operator>=(const Iter& it, const Iter& it2) {
73  return !(it < it2);
74  }
75 
76  namespace util {
77  template <class Iter, class T>
78  typename std::iterator_traits<Iter>::pointer deref_iterator(const Iter& it) {
79  return deref_iterator(it, util::identity<typename std::iterator_traits<Iter>::reference>());
80  }
81 
82  template <class Iter, class T>
83  T* deref_iterator(const Iter& it, util::identity<T&>) {
84  return &*it;
85  }
86 
87  template <class Iter, class T>
89  return util::value_ptr<T>(*it);
90  }
91  }
92 
93 
94  template <class Iter>
95  class iter_range
96  {
97  Iter start, finish;
98  public:
99 
101 
102  typedef Iter iterator;
103  typedef typename iterator::value_type value_type;
104 
105  explicit iter_range(Iter start, Iter finish) : start(start), finish(finish) {}
106  iterator begin() const { return start; }
107  iterator end() const { return finish; }
108  };
109  template <class Iter>
110  iter_range<Iter> make_range(Iter start, Iter finish) {
111  return iter_range<Iter>(start, finish);
112  }
113 
114  // decays into a onepass/forward iterator
115  template <class Cursor>
117  : public std::iterator<std::forward_iterator_tag,
118  typename Cursor::element_type,
119  std::ptrdiff_t,
120  typename std::conditional<std::is_reference<typename Cursor::reference_type>::value,
121  typename std::add_pointer<typename Cursor::element_type>::type,
122  util::value_ptr<typename Cursor::element_type>>::type,
123  typename Cursor::reference_type>
124  {
125  public:
127 
128  cursor_iterator(Cursor cur) : cur(cur) {
129  }
130 
131  cursor_iterator() : cur() {
132  }
133 
134  bool operator==(const cursor_iterator& other) const {
135  return !cur && !other.cur;
136  }
137 
138  typename Cursor::reference_type operator*() const {
139  return cur->get();
140  }
141 
142  typename cursor_iterator::pointer operator->() const {
143  auto& v = **this;
144  return &v;
145  }
146 
148  cur->inc();
149 
150  if (cur->empty()) { cur.reset(); }
151  return *this;
152  }
153 
154  cursor_iterator& operator+=(std::ptrdiff_t n) {
155  cur->skip(n);
156 
157  if (cur->empty()) { cur.reset(); }
158  return *this;
159  }
160 
161 
162 
163  private:
164  bool empty() const {
165  !cur || cur->empty();
166  }
167 
169  };
170 
171  template <class Container>
173  {
174  Container c;
175 
176  public:
178 
179  container_range(Container c) : c(c)
180  {
181  }
182 
183  iterator begin() const
184  {
185  return iterator(c.get_cursor());
186  }
187 
188  iterator end() const
189  {
190  return iterator();
191  }
192  };
193 
194 }
195 
196 #endif
Definition: util.hpp:123
cursor_iterator::pointer operator->() const
Definition: linq_iterators.hpp:142
Definition: linq_iterators.hpp:116
auto empty() -> decltype(from< T >())
Returns an observable that sends no items to observer and immediately completes, on the specified sch...
Definition: rx-empty.hpp:37
std::enable_if< std::is_convertible< Iter, use_default_iterator_operators >::value, bool >::type operator>=(const Iter &it, const Iter &it2)
Definition: linq_iterators.hpp:72
std::enable_if< std::is_convertible< Iter, use_default_iterator_operators >::value, Iter >::type operator-=(const Iter &it, typename std::iterator_traits< Iter >::distance_type n)
Definition: linq_iterators.hpp:39
iter_range< Iter > make_range(Iter start, Iter finish)
Definition: linq_iterators.hpp:110
iter_range(Iter start, Iter finish)
Definition: linq_iterators.hpp:105
CPPLINQ_USE_DEFAULT_ITERATOR_OPERATORS
Definition: linq_iterators.hpp:126
Definition: linq_iterators.hpp:172
cursor_iterator()
Definition: linq_iterators.hpp:131
cursor_iterator & operator+=(std::ptrdiff_t n)
Definition: linq_iterators.hpp:154
std::enable_if< std::is_convertible< Iter, use_default_iterator_operators >::value, Iter >::type operator-(const Iter &it, typename std::iterator_traits< Iter >::distance_type n)
Definition: linq_iterators.hpp:31
Definition: linq.hpp:186
#define CPPLINQ_USE_DEFAULT_ITERATOR_OPERATORS
Definition: linq_iterators.hpp:15
std::enable_if< std::is_convertible< Iter, use_default_iterator_operators >::value, bool >::type operator>(const Iter &it, const Iter &it2)
Definition: linq_iterators.hpp:56
cursor_iterator & operator++()
Definition: linq_iterators.hpp:147
Definition: util.hpp:115
Definition: linq_iterators.hpp:95
std::enable_if< std::is_convertible< Iter, use_default_iterator_operators >::value, bool >::type operator<=(const Iter &it, const Iter &it2)
Definition: linq_iterators.hpp:64
cursor_iterator< typename Container::cursor > iterator
Definition: linq_iterators.hpp:177
bool operator==(const cursor_iterator &other) const
Definition: linq_iterators.hpp:134
std::enable_if< std::is_convertible< Iter, use_default_iterator_operators >::value, Iter >::type operator+(const Iter &it, typename std::iterator_traits< Iter >::distance_type n)
Definition: linq_iterators.hpp:23
Cursor::reference_type operator*() const
Definition: linq_iterators.hpp:138
Definition: linq_iterators.hpp:13
container_range(Container c)
Definition: linq_iterators.hpp:179
iterator end() const
Definition: linq_iterators.hpp:107
std::enable_if< std::is_convertible< Iter, use_default_iterator_operators >::value, bool >::type operator!=(const Iter &it, const Iter &it2)
Definition: linq_iterators.hpp:48
iterator begin() const
Definition: linq_iterators.hpp:106
cursor_iterator(Cursor cur)
Definition: linq_iterators.hpp:128
iterator end() const
Definition: linq_iterators.hpp:188
iterator::value_type value_type
Definition: linq_iterators.hpp:103
CPPLINQ_USE_DEFAULT_ITERATOR_OPERATORS typedef Iter iterator
Definition: linq_iterators.hpp:102
iterator begin() const
Definition: linq_iterators.hpp:183
util::value_ptr< T > deref_iterator(const Iter &it, util::identity< T >)
Definition: linq_iterators.hpp:88