-
Notifications
You must be signed in to change notification settings - Fork 0
/
_l_chrng.h
198 lines (176 loc) · 4.79 KB
/
_l_chrng.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#ifndef __L_CHRNG_H
#define __L_CHRNG_H
// Copyright David Lawrence Bien 1997 - 2021.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt).
// _l_chrng.h
// character range class.
// Range is [first,second] ( i.e. not [first,second). )
// Can use [0,0] for empty element - since not valid input.
#include <ostream>
#include "jsonstrm.h"
__REGEXP_BEGIN_NAMESPACE
// We store the elements as t_TyRangeEl which is larger than t_TyChar because there are values that are
// outside of the character range.
template < class t_TyRangeEl, class t_TyChar >
struct _fa_char_range : public pair< t_TyRangeEl, t_TyRangeEl >
{
private:
typedef pair< t_TyRangeEl, t_TyRangeEl > _TyBase;
typedef _fa_char_range _TyThis;
public:
typedef t_TyRangeEl _TyRangeEl;
typedef t_TyChar _TyChar;
typedef typename _l_char_type_map< _TyChar >::_TyUnsigned _TyUnsignedChar;
using _TyBase::first;
using _TyBase::second;
_fa_char_range( _fa_char_range const & ) = default;
~_fa_char_range() = default;
_fa_char_range()
: _TyBase( 0, 0 )
{
}
_fa_char_range( t_TyRangeEl _rFirst, t_TyRangeEl _rSecond )
: _TyBase( _rFirst, _rSecond )
{
Assert( second >= first );
}
void set_empty()
{
first = 0;
second = 0;
}
bool empty() const _BIEN_NOTHROW
{
if ( !first )
{
Assert( !second );
return true;
}
return false;
}
bool operator < ( _TyThis const & _r ) const _BIEN_NOTHROW
{
return second < _r.first;
}
// This is for containers which can have overlapping char ranges.
bool CanonicalLess( _TyThis const & _r ) const _BIEN_NOTHROW
{
return static_cast< _TyBase const & >( *this ) < _r;
}
bool intersects( _TyThis const & _r ) const _BIEN_NOTHROW
{
if ( first < _r.first )
return second >= _r.first;
else
return first <= _r.second;
}
bool contains( t_TyRangeEl const & _r ) const _BIEN_NOTHROW
{
return _r >= first && _r <= second;
}
bool isconsecutiveleft( _TyThis const & _r ) const _BIEN_NOTHROW
{
return _r.second+1 == first;
}
bool isconsecutiveright( _TyThis const & _r ) const _BIEN_NOTHROW
{
return second+1 == _r.first;
}
bool isconsecutive( _TyThis const & _r ) const _BIEN_NOTHROW
{
return isconsecutiveleft( _r ) || isconsecutiveright( _r );
}
// Return this range without _r and return any remaining range in _rSecondResult.
void remove( _TyThis const & _r, _TyThis & _rSecondResult )
{
if ( first < _r.first )
{
if ( second > _r.second )
{
_rSecondResult.first = _r.second+1;
_rSecondResult.second = second;
}
else
{
_rSecondResult.set_empty();
if ( second < _r.first )
return;
}
second = _r.first-1;
}
else
{
_rSecondResult.set_empty();
if ( first <= _r.second )
{
if ( second <= _r.second )
set_empty();
else
first = _r.second+1;
}
}
}
friend std::ostream & operator << ( std::ostream & _ros, const _TyThis & _r )
{
std::ostream::sentry s(_ros);
if ( s )
{
_ros << "['" << ( _r.first ? _r.first : ' ' ) <<
"'-'" << ( _r.second ? _r.second : ' ' ) << "']";
}
return _ros;
}
void DumpToString( string & _rstr ) const
{
PrintfStdStr( _rstr, "[%llu-%llu]", uint64_t(first), uint64_t(second) );
}
template < class t_TyJsonValueLife >
void ToJSONStream( t_TyJsonValueLife & _jvl ) const
{
Assert( _jvl.FAtArrayValue() );
if ( _jvl.FAtArrayValue() )
{
if ( !first )
_jvl.WriteNullValue();
else
if ( ( first > 254/* _l_char_type_map< _TyChar >::ms_kcMax */ ) || ( first < 32 ) ) // filter out unprintable characters.
_jvl.PrintfStringValue( "0x%llx", uint64_t((_TyUnsignedChar)first) );
else
{
_TyChar ch = (_TyChar)first;
_jvl.WriteStringValue( &ch, 1 );
}
if ( !second )
_jvl.WriteNullValue();
else
if ( ( second > 254/* )_l_char_type_map< _TyChar >::ms_kcMax */ ) || ( second < 32 ) ) // filter out unprintable characters.
_jvl.PrintfStringValue( "0x%llx", uint64_t((_TyUnsignedChar)second) );
else
{
_TyChar ch = (_TyChar)second;
_jvl.WriteStringValue( &ch, 1 );
}
}
}
};
template < class t_TyNfaCharRange >
struct _fa_char_range_intersect
{
bool operator ()( t_TyNfaCharRange const & _rL, t_TyNfaCharRange const & _rR ) const _BIEN_NOTHROW
{
return _rL.intersects( _rR );
}
};
// Calls _TyNfaCharRange::CanonicalLess().
template < class t_TyNfaCharRange >
struct _fa_char_range_canonical_less
{
bool operator ()( t_TyNfaCharRange const & _rL, t_TyNfaCharRange const & _rR ) const _BIEN_NOTHROW
{
return _rL.CanonicalLess( _rR );
}
};
__REGEXP_END_NAMESPACE
#endif //__L_CHRNG_H