-
Notifications
You must be signed in to change notification settings - Fork 1
/
tokenize.h
104 lines (94 loc) · 2.18 KB
/
tokenize.h
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
#include <cstddef> // for size_t
#include <string_view> // for string_view
template <char Delimiter>
class Tokenize
{
public:
Tokenize() = delete;
constexpr Tokenize(const Tokenize&) = default;
constexpr Tokenize(Tokenize&&) = default;
constexpr Tokenize& operator=(const Tokenize&) = default;
constexpr Tokenize& operator=(Tokenize&&) = default;
explicit constexpr Tokenize(std::nullptr_t)
: m_Source{}
{
}
explicit constexpr Tokenize(const char* source)
: m_Source{source}
{
GetNext();
}
explicit constexpr Tokenize(std::string_view source)
: m_Source{source}
{
GetNext();
}
constexpr bool operator==(const Tokenize& rhs) const = default;
constexpr bool operator!=(const Tokenize& rhs) const = default;
constexpr auto begin()
{
return *this;
}
constexpr auto end()
{
return Tokenize{m_Source, end_tag_t{}};
}
constexpr auto begin() const
{
return *this;
}
constexpr auto end() const
{
return Tokenize{m_Source, end_tag_t{}};
}
constexpr auto cbegin() const
{
return *this;
}
constexpr auto cend() const
{
return Tokenize{m_Source, end_tag_t{}};
}
constexpr auto operator*()
{
return m_Source.substr(m_Position, m_Next - m_Position);
}
constexpr decltype(auto) operator++()
{
if (!Advance())
*this = end();
return *this;
}
constexpr auto operator++(int)
{
auto copy = *this;
++(*this);
return copy;
}
private:
struct end_tag_t
{
};
constexpr Tokenize(std::string_view source, end_tag_t)
: m_Source{source}, m_Position{source.size()}, m_Next{source.size()}
{
}
constexpr void GetNext()
{
++m_Next;
while (m_Next < m_Source.size() && m_Source[m_Next] != Delimiter)
{
++m_Next;
}
}
constexpr bool Advance()
{
m_Position = m_Next + 1;
GetNext();
return m_Next != m_Position;
}
std::string_view m_Source;
size_t m_Position{0};
size_t m_Next{0};
};