@@ -1537,7 +1537,7 @@ public:
1537
1537
void _Add_char2(_Elem _Ch);
1538
1538
void _Add_class();
1539
1539
void _Add_char_to_class(_Elem _Ch);
1540
- void _Add_range2 (_Elem, _Elem);
1540
+ void _Add_range3 (_Elem, _Elem);
1541
1541
void _Add_named_class(typename _RxTraits::char_class_type, _Rx_char_class_kind);
1542
1542
void _Add_equiv2(const _Elem*, const _Elem*);
1543
1543
void _Add_coll2(const _Elem*, const _Elem*);
@@ -1567,11 +1567,8 @@ private:
1567
1567
_Node_base* _Current;
1568
1568
regex_constants::syntax_option_type _Flags;
1569
1569
const _RxTraits& _Traits;
1570
- const int _Bmax; // Do not use; use _Get_bmax instead.
1571
- const int _Tmax; // Do not use; use _Get_tmax instead.
1572
-
1573
- unsigned int _Get_bmax() const;
1574
- unsigned int _Get_tmax() const;
1570
+ const int _Bmax; // TRANSITION, ABI: preserved for binary compatibility
1571
+ const int _Tmax; // TRANSITION, ABI: preserved for binary compatibility
1575
1572
1576
1573
public:
1577
1574
_Builder& operator=(const _Builder&) = delete;
@@ -2911,33 +2908,61 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_char_to_class(_Elem _Ch) { // add
2911
2908
}
2912
2909
2913
2910
template <class _FwdIt, class _Elem, class _RxTraits>
2914
- void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range2 (const _Elem _Arg0, const _Elem _Arg1) {
2911
+ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range3 (const _Elem _Arg0, const _Elem _Arg1) {
2915
2912
// add character range to set
2913
+ using string_type = typename _RxTraits::string_type;
2916
2914
unsigned int _Ex0 = static_cast<typename _RxTraits::_Uelem>(_Arg0);
2917
2915
const unsigned int _Ex1 = static_cast<typename _RxTraits::_Uelem>(_Arg1);
2918
2916
_Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Current);
2919
2917
2920
- for (; _Ex0 <= _Ex1 && _Ex1 < _Get_bmax(); ++_Ex0) { // set a bit
2921
- if (!_Node->_Small) {
2918
+ // set bits and check that the range is non-empty
2919
+ if (_Flags & regex_constants::collate) {
2920
+ _Elem _Ch;
2921
+ const auto _Ch_ptr = _STD addressof(_Ch);
2922
+ const auto _Arg0_ptr = _STD addressof(_Arg0);
2923
+ const auto _Arg1_ptr = _STD addressof(_Arg1);
2924
+ const string_type _Arg0_key = _Traits.transform(_Arg0_ptr, _Arg0_ptr + 1);
2925
+ const string_type _Arg1_key = _Traits.transform(_Arg1_ptr, _Arg1_ptr + 1);
2926
+
2927
+ if (_Arg0_key > _Arg1_key) {
2928
+ _Xregex_error(regex_constants::error_range);
2929
+ }
2930
+
2931
+ for (unsigned int _UCh = 0; _UCh < _Bmp_max; ++_UCh) {
2932
+ _Ch = static_cast<_Elem>(_UCh);
2933
+ const string_type _Ch_key = _Traits.transform(_Ch_ptr, _Ch_ptr + 1);
2934
+ if (_Arg0_key <= _Ch_key && _Ch_key <= _Arg1_key) {
2935
+ if (!_Node->_Small) {
2936
+ _Node->_Small = new _Bitmap;
2937
+ }
2938
+ _Node->_Small->_Mark(_UCh);
2939
+ }
2940
+ }
2941
+ } else if (_Ex0 > _Ex1) {
2942
+ _Xregex_error(regex_constants::error_range);
2943
+ } else {
2944
+ if (!_Node->_Small && _Ex0 < _Bmp_max) {
2922
2945
_Node->_Small = new _Bitmap;
2923
2946
}
2924
2947
2925
- _Node->_Small->_Mark(_Ex0);
2926
- }
2948
+ for (; _Ex0 <= _Ex1 && _Ex0 < _Bmp_max; ++_Ex0) {
2949
+ _Node->_Small->_Mark(_Ex0);
2950
+ }
2927
2951
2928
- if ((_Flags & regex_constants::collate) || _Ex1 >= _Ex0) {
2929
- if (_Ex1 - _Ex0 < _Get_tmax()) {
2952
+ if (_Ex1 - _Ex0 < _ARRAY_THRESHOLD) {
2930
2953
for (; _Ex0 <= _Ex1; ++_Ex0) {
2931
2954
_Add_char_to_array(static_cast<_Elem>(_Ex0));
2932
2955
}
2933
- } else { // store remaining range as pair
2934
- if (!_Node->_Ranges) {
2935
- _Node->_Ranges = new _Buf<_Elem>;
2936
- }
2956
+ }
2957
+ }
2937
2958
2938
- _Node->_Ranges->_Insert2(static_cast<_Elem>(_Ex0));
2939
- _Node->_Ranges->_Insert2(_Arg1);
2959
+ if ((_Flags & regex_constants::collate) || _Ex1 >= _Ex0) { // store remaining range as pair
2960
+ if (!_Node->_Ranges) {
2961
+ _Node->_Ranges = new _Buf<_Elem>;
2940
2962
}
2963
+
2964
+ _Node->_Ranges->_Insert2(static_cast<_Elem>(_Ex0));
2965
+ _Node->_Ranges->_Insert2(_Arg1);
2941
2966
}
2942
2967
}
2943
2968
@@ -2991,16 +3016,6 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Char_to_elts2(const _Elem* const _Firs
2991
3016
(*_Cur)->_Data._Insert2(_First, _Last);
2992
3017
}
2993
3018
2994
- template <class _FwdIt, class _Elem, class _RxTraits>
2995
- unsigned int _Builder<_FwdIt, _Elem, _RxTraits>::_Get_bmax() const {
2996
- return static_cast<unsigned int>(_Bmax);
2997
- }
2998
-
2999
- template <class _FwdIt, class _Elem, class _RxTraits>
3000
- unsigned int _Builder<_FwdIt, _Elem, _RxTraits>::_Get_tmax() const {
3001
- return static_cast<unsigned int>(_Tmax);
3002
- }
3003
-
3004
3019
template <class _FwdIt, class _Elem, class _RxTraits>
3005
3020
void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_equiv2(const _Elem* const _First, const _Elem* const _Last) {
3006
3021
// add elements of equivalence class to bracket expression
@@ -4328,18 +4343,7 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_ClassRanges() { // check for valid clas
4328
4343
_Chr2 = _Traits.translate(_Chr2);
4329
4344
}
4330
4345
4331
- if (_Flags & regex_constants::collate) {
4332
- const _Elem* const _Chr1_ptr = _STD addressof(_Chr1);
4333
- const _Elem* const _Chr2_ptr = _STD addressof(_Chr2);
4334
- if (_Traits.transform(_Chr2_ptr, _Chr2_ptr + 1) < _Traits.transform(_Chr1_ptr, _Chr1_ptr + 1)) {
4335
- _Error(regex_constants::error_range);
4336
- }
4337
- } else if (static_cast<typename _RxTraits::_Uelem>(_Chr2)
4338
- < static_cast<typename _RxTraits::_Uelem>(_Chr1)) {
4339
- _Error(regex_constants::error_range);
4340
- }
4341
-
4342
- _Nfa._Add_range2(_Chr1, _Chr2);
4346
+ _Nfa._Add_range3(_Chr1, _Chr2);
4343
4347
} else if (_Ret == _Prs_chr) {
4344
4348
_Nfa._Add_char_to_class(static_cast<_Elem>(_Val));
4345
4349
}
0 commit comments