Skip to content

Commit 13ab5be

Browse files
author
joboc
committed
Add consecutive free function
1 parent 78f7c72 commit 13ab5be

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

consecutive.hpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#ifndef CONSECUTIVE_HPP
2+
#define CONSECUTIVE_HPP
3+
4+
/* range view adaptor to represent pairs of consecutive elements:
5+
Applying it on range containing:
6+
{a, b, c, d, e, f}
7+
produces a view seeing:
8+
{
9+
std::pair(a,b),
10+
std::pair(b,c),
11+
std::pair(c,d),
12+
std::pair(d,e),
13+
std::pair(e,f)
14+
}
15+
*/
16+
17+
#include "iterator_range.hpp"
18+
#include "named_type.hpp"
19+
20+
#include <iterator>
21+
#include <utility>
22+
23+
namespace ranges
24+
{
25+
26+
template<typename Iterator>
27+
using BeginIterator = NamedType<Iterator, struct begin_context>;
28+
template<typename Iterator>
29+
using EndIterator = NamedType<Iterator, struct end_context>;
30+
31+
template<typename UnderlyingIterator>
32+
class consecutive_iterator
33+
: public std::iterator<
34+
typename std::iterator_traits<UnderlyingIterator>::iterator_category,
35+
std::pair<typename std::iterator_traits<UnderlyingIterator>::value_type, typename std::iterator_traits<UnderlyingIterator>::value_type>,
36+
typename std::iterator_traits<UnderlyingIterator>::difference_type,
37+
const std::pair<typename std::iterator_traits<UnderlyingIterator>::value_type, typename std::iterator_traits<UnderlyingIterator>::value_type>*,
38+
const std::pair<typename std::iterator_traits<UnderlyingIterator>::value_type, typename std::iterator_traits<UnderlyingIterator>::value_type>&
39+
>
40+
{
41+
public:
42+
explicit consecutive_iterator(BeginIterator<UnderlyingIterator> begin, EndIterator<UnderlyingIterator> end) : iterator_(begin.get()), next_(begin.get() != end.get() ? std::next(begin.get()) : begin.get()), isEnd_(false) {}
43+
explicit consecutive_iterator(EndIterator<UnderlyingIterator> end) : iterator_(end.get()), next_(end.get()), isEnd_(true) {}
44+
consecutive_iterator operator++() {++iterator_; ++next_; return *this;}
45+
auto operator*() { return std::make_pair(*iterator_, *next_);}
46+
bool operator==(const consecutive_iterator& other)
47+
{
48+
if (isEnd_ == other.isEnd_) return iterator_ == other.iterator_;
49+
if (other.isEnd_) return next_ == other.iterator_;
50+
if (isEnd_) return iterator_ == other.next_;
51+
}
52+
bool operator!=(const consecutive_iterator& other){ return !(*this == other); }
53+
auto operator-(const consecutive_iterator& other) { return next_ - other.next_;}
54+
55+
private:
56+
UnderlyingIterator iterator_;
57+
UnderlyingIterator next_;
58+
bool isEnd_;
59+
};
60+
61+
namespace view
62+
{
63+
64+
template<typename Range>
65+
auto consecutive(Range const& range) -> iterator_range<consecutive_iterator<decltype(range.begin())>>
66+
{
67+
using UnderlyingIterator = decltype(range.begin());
68+
return iterator_range<consecutive_iterator<UnderlyingIterator>>(
69+
consecutive_iterator<UnderlyingIterator>(BeginIterator<UnderlyingIterator>(range.begin()), EndIterator<UnderlyingIterator>(range.end())),
70+
consecutive_iterator<UnderlyingIterator>(EndIterator<UnderlyingIterator>(range.end())));
71+
}
72+
73+
} // namespace view
74+
} // namespace ranges
75+
76+
77+
#endif

0 commit comments

Comments
 (0)