1 #ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
4 #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
10 #include "stringsource.h"
11 #include "streamcharsource.h"
16 inline bool RegEx::Matches(char ch
) const {
22 inline bool RegEx::Matches(const std::string
& str
) const {
23 return Match(str
) >= 0;
26 inline bool RegEx::Matches(const Stream
& in
) const {
27 return Match(in
) >= 0;
30 template <typename Source
>
31 inline bool RegEx::Matches(const Source
& source
) const {
32 return Match(source
) >= 0;
36 // . Matches the given string against this regular expression.
37 // . Returns the number of characters matched.
38 // . Returns -1 if no characters were matched (the reason for
39 // not returning zero is that we may have an empty regex
40 // which is ALWAYS successful at matching zero characters).
41 // . REMEMBER that we only match from the start of the buffer!
42 inline int RegEx::Match(const std::string
& str
) const
44 StringCharSource
source(str
.c_str(), str
.size());
48 inline int RegEx::Match(const Stream
& in
) const
50 StreamCharSource
source(in
);
54 template <typename Source
>
55 inline bool RegEx::IsValidSource(const Source
& source
) const
61 inline bool RegEx::IsValidSource
<StringCharSource
>(const StringCharSource
&source
) const
72 template <typename Source
>
73 inline int RegEx::Match(const Source
& source
) const
75 return IsValidSource(source
) ? MatchUnchecked(source
) : -1;
78 template <typename Source
>
79 inline int RegEx::MatchUnchecked(const Source
& source
) const
83 return MatchOpEmpty(source
);
85 return MatchOpMatch(source
);
87 return MatchOpRange(source
);
89 return MatchOpOr(source
);
91 return MatchOpAnd(source
);
93 return MatchOpNot(source
);
95 return MatchOpSeq(source
);
101 //////////////////////////////////////////////////////////////////////////////
103 // Note: the convention MatchOp*<Source> is that we can assume IsSourceValid(source).
104 // So we do all our checks *before* we call these functions
107 template <typename Source
>
108 inline int RegEx::MatchOpEmpty(const Source
& source
) const {
109 return source
[0] == Stream::eof() ? 0 : -1;
113 inline int RegEx::MatchOpEmpty
<StringCharSource
>(const StringCharSource
& source
) const {
114 return !source
? 0 : -1; // the empty regex only is successful on the empty string
118 template <typename Source
>
119 inline int RegEx::MatchOpMatch(const Source
& source
) const {
126 template <typename Source
>
127 inline int RegEx::MatchOpRange(const Source
& source
) const {
128 if(m_a
> source
[0] || m_z
< source
[0])
134 template <typename Source
>
135 inline int RegEx::MatchOpOr(const Source
& source
) const {
136 for(std::size_t i
=0;i
<m_params
.size();i
++) {
137 int n
= m_params
[i
].MatchUnchecked(source
);
145 // Note: 'AND' is a little funny, since we may be required to match things
146 // of different lengths. If we find a match, we return the length of
147 // the FIRST entry on the list.
148 template <typename Source
>
149 inline int RegEx::MatchOpAnd(const Source
& source
) const {
151 for(std::size_t i
=0;i
<m_params
.size();i
++) {
152 int n
= m_params
[i
].MatchUnchecked(source
);
162 template <typename Source
>
163 inline int RegEx::MatchOpNot(const Source
& source
) const {
166 if(m_params
[0].MatchUnchecked(source
) >= 0)
172 template <typename Source
>
173 inline int RegEx::MatchOpSeq(const Source
& source
) const {
175 for(std::size_t i
=0;i
<m_params
.size();i
++) {
176 int n
= m_params
[i
].Match(source
+ offset
); // note Match, not MatchUnchecked because we need to check validity after the offset
186 #endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66