-
Notifications
You must be signed in to change notification settings - Fork 456
/
Range.hpp
104 lines (88 loc) · 1.88 KB
/
Range.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#pragma once
template<typename value_t>
class RangeImpl
{
class Iterator;
public:
RangeImpl(value_t begin, value_t end, value_t step = 1) :m_begin(begin), m_end(end), m_step(step)
{
if (step>0 && m_begin >= m_end)
throw std::logic_error("end must greater than begin.");
else if (step<0 && m_begin <= m_end)
throw std::logic_error("end must less than begin.");
m_step_end = (m_end - m_begin) / m_step;
if (m_begin + m_step_end*m_step != m_end)
{
m_step_end++;
}
}
Iterator begin()
{
return Iterator(0, *this);
}
Iterator end()
{
return Iterator(m_step_end, *this);
}
value_t operator[](int s)
{
return m_begin + s*m_step;
}
int size()
{
return m_step_end;
}
private:
value_t m_begin;
value_t m_end;
value_t m_step;
int m_step_end;
class Iterator
{
public:
Iterator(int start, RangeImpl& range) : m_current_step(start), m_range(range)
{
m_current_value = m_range.m_begin + m_current_step*m_range.m_step;
}
value_t operator*() { return m_current_value; }
const Iterator* operator++()
{
m_current_value += m_range.m_step;
m_current_step++;
return this;
}
bool operator==(const Iterator& other)
{
return m_current_step == other.m_current_step;
}
bool operator!=(const Iterator& other)
{
return m_current_step != other.m_current_step;
}
const Iterator* operator--()
{
m_current_value -= m_range.m_step;
m_current_step--;
return this;
}
private:
value_t m_current_value;
int m_current_step;
RangeImpl& m_range;
};
};
template<typename T, typename V>
auto Range(T begin, T end, V stepsize)->RangeImpl<decltype(begin + end + stepsize)>
{
return RangeImpl<decltype(begin + end + stepsize)>(begin, end, stepsize);
}
template<typename T>
RangeImpl<T> Range(T begin, T end)
{
return RangeImpl<T>(begin, end, 1);
}
template<typename T>
RangeImpl<T> Range(T end)
{
return RangeImpl<T>(T(), end, 1);
}